« PowerShell – less code, same result | Main | Excel, PowerShell, and the Import-CSV Cmdlet »
PowerShell and XML
By Adam Bell | March 1, 2007
By far, for me, the most useful feature I’ve found in PowerShell is how easy it is to manipulate XML documents. I’ve written VBScripts in the past that extracted data from XML, performed a task, and then updated the XML document when it was done.
Now, personally I found this quite a tricky task. Let me give you an example, we have the following XML document:
<section name="build">
<Package ID="W2K3">
<PartitionType>A</PartitionType>
</package>
<package ID="XPSP2">
<PartitionType>B</PartitionType>
</package>
</section>
The aim is to extract the PartitionType for the W2K3 package.
In PowerShell, this is really easy:
$payload = get-content -path d:\coding\ps\payload.xml
foreach ($package in $payload.section.package)
{
if ($package.id -eq "w2k3")
{
write-host $package.partitiontype
}
}
As you can see it’s easy to navigate to attributes or nodes within the XML document. So what happens if you want to add another package?
$newPkg = $payload.CreateElement("Package")
$newPkg.SetAttribute("ID", "Vista")
Now the only really hassle I’ve experienced when trying to add new nodes, is when it’s the first node at that level. Adrian Milliner over at Soapy Frog provided a work around for this (bug?) in the comments of the Microsoft PowerShell Team blog.
With this in mind I use the following the syntax to add the node:
$payload["section"].AppendChild($newPkg)
Now we have the new package node, we still need to add the child node under it for the partitiontype.
$partition = $payload.CreateElement("partitiontype")
$partition.set_InnerText("C")
$nodecount = $payload.section.package.count
if ($nodecount -ne $null)
{
$I = ($nodecount -1)
$payload.section.package[$I].AppendChild($partition)
}
$payload.save("D:\coding\ps\payload.xml")
So now we’ve covered some basic XML manipulations. Our end result in this example woud be:
<section name="build">
<Package ID="W2K3">
<PartitionType>A</PartitionType>
</package>
<package ID="XPSP2">
<PartitionType>B</PartitionType>
</package>
<package ID="Vista">
<PartitionType>C</PartitionType>
</package>
</section>
If we take some of our earlier AD examples you can see how easy it would be to add in nodes for ou’s, groups, and accounts and it suddenly looks a whole lot easier to build an Active Directory ;)
Of course one application could be to write some script to read your live AD structure, save it into an XML document, and then use it to build Active Directory for a test environment. Though this would take some effort it has some excellent portability advantages. If you’re careful on your coding you can write your scripts so that the domain name isn’t hard-coded.
Topics: PowerShell | No Comments »