Skip to main content

How to Parse XML Files in a Batch Script (via PowerShell)

XML (eXtensible Markup Language) is a common, structured format for storing configuration data, logs, and information for data exchange. While its hierarchical structure is powerful, it is nearly impossible to parse reliably with pure batch script commands. Batch scripting is designed for simple, line-based text and lacks the tools to understand XML's nested tags and attributes.

The solution is to delegate this complex parsing task to a tool that is designed for it. The PowerShell engine, built into all modern versions of Windows, has a powerful, native XML parser. This guide will teach you how to call PowerShell from your batch script to easily and reliably read values from any XML file.

The Challenge: Why Pure Batch Fails with XML

A simple XML file looks like this:

<Settings>
<Server>
<Host>db.example.com</Host>
<Port>1433</Port>
</Server>
</Settings>

A pure batch script using a FOR /F loop would see this as just a series of text lines. It has no understanding that <Port> is a child of <Server>. Trying to read this with findstr or other line-based tools is extremely brittle and will break the moment the formatting changes (e.g., if a line break is added).

The Core Method: Calling PowerShell

The correct and only recommended method is to use a PowerShell one-liner. PowerShell can cast the entire file's content into an XML object, allowing you to navigate its structure using a simple "dot notation."

The Basic PowerShell Syntax:

  • [xml]$XmlDocument = Get-Content 'file.xml'
  • $XmlDocument.Settings.Server.Host

This is what we will execute from our batch script.

The PowerShell Command Explained

Let's break down the key parts of the PowerShell command we will use.

  • [xml]$XmlDocument = Get-Content 'file.xml': This reads the file.xml and "casts" its content into a fully structured XML object named $XmlDocument.
  • Dot Notation: Once it's an XML object, you can navigate the hierarchy simply by using dots (.) to access the child nodes. To get the <Host> value from our example, the path is $XmlDocument.Settings.Server.Host.
  • XPath with Select-Xml: For more complex queries (e.g., finding a node with a specific attribute), PowerShell supports XPath. Select-Xml -Path 'file.xml' -XPath "/Settings/Server/Host"

Basic Example: Reading a Simple Node Value

Let's read the <Host> value from our sample config.xml file.

config.xml
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<Server>
<Host>db.example.com</Host>
<Port>1433</Port>
</Server>
</Settings>

The script:

@ECHO OFF
SET "XmlFile=config.xml"
SET "ServerHost="

FOR /F "delims=" %%V IN (
'powershell -Command "(Get-Content '%XmlFile%' -Raw | ConvertFrom-Xml).Settings.Server.Host"'
) DO (
SET "ServerHost=%%V"
)

ECHO The server host from the XML is: %ServerHost%
note

A more modern PowerShell approach uses ConvertFrom-Xml, which is often more robust.

Reading Node Attributes

XML nodes can also have attributes. PowerShell can access these just as easily.

For example:

users.xml
<Users>
<User ID="101">Alice</User>
<User ID="102">Bob</User>
</Users>

And the Batch Script that gets the ID of the first user:

@ECHO OFF
SET "XmlFile=users.xml"
SET "UserID="

FOR /F "delims=" %%I IN (
'powershell -Command "(Get-Content '%XmlFile%' -Raw | ConvertFrom-Xml).Users.User[0].ID"'
) DO (
SET "UserID=%%I"
)

ECHO The first user's ID is: %UserID%
note

In PowerShell, when there are multiple nodes with the same name, they are treated as an array. [0] gets the first one.

The FOR /F Pattern for Capturing Output

As with all commands that return a value, the standard way to capture the output from our PowerShell one-liner is to wrap it in a FOR /F loop.

FOR /F "delims=" %%V IN ('powershell -Command "..."') DO SET "Result=%%V"
  • delims=: This is important to ensure that if the returned value contains spaces, the entire string is captured.

Practical Example: Reading a Setting from a Configuration File

This script reads a connection string from an application's .config file, which is a common XML format.

For example:

app.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="ConnectionString" value="Server=db.prod;Database=main;User ID=app;Password=secret;"/>
<add key="Timeout" value="30"/>
</appSettings>
</configuration>

And this script uses XPath to find the <add> node where the key attribute is "ConnectionString" and then gets its value attribute.

@ECHO OFF
SET "ConfigFile=app.config"
SET "ConnString="

ECHO --- Reading Connection String from %ConfigFile% ---
ECHO.

FOR /F "delims=" %%S IN (
'powershell -NoProfile -Command "(Select-Xml -Path '%ConfigFile%' -XPath ""//appSettings/add[@key='ConnectionString']"").Node.value"'
) DO (
SET "ConnString=%%S"
)

IF DEFINED ConnString (
ECHO [SUCCESS] Found the Connection String:
ECHO %ConnString%
) ELSE (
ECHO [FAILURE] Could not find the Connection String in the config file.
)

Conclusion

While pure batch scripting is not suited for parsing XML, its ability to call PowerShell makes this a simple and highly reliable task.

  • Never try to parse XML with line-based tools like findstr or a pure FOR /F loop; it is not reliable.
  • The PowerShell one-liner is the standard and only recommended method for this task.
  • Use dot notation ($xml.Node.Child) for simple XML structures.
  • Use XPath with Select-Xml for more complex queries, such as finding nodes based on attribute values.
  • Always use a FOR /F loop to capture the output from PowerShell into your batch script's variables.

By delegating the heavy lifting to PowerShell, you can write batch scripts that can confidently and correctly interact with any XML-based configuration file or data source.