W.J.P.
W.J.P.

Reputation: 86

PowerShell XML formatting issue

I'm having trouble getting a properly formatted XML file using the following code:

# Get Computer System info
$CompInfo = Get-WmiObject Win32_ComputerSystem
$CompName = $CompInfo.Name

# Get IP Address
$IPAddressTemp = Test-Connection $CompName -count 1 | select Address,Ipv4Address
$IPAddress = $IPAddressTemp.IPV4Address

# Begin Writing values to XML Document
$filePath = "C:\Temp\$CompName.$IPAddress.xml" # Set the File Name
$XmlWriter = New-Object System.XMl.XmlTextWriter($filePath,$Null) # Create The Document
# Set The XML Formatting
$xmlWriter.Formatting = "Indented"
$xmlWriter.Indentation = "4"

# Start the XML Document
$xmlWriter.WriteStartDocument()

# Set the XSL
$XSLPropText = "type='text/xsl' href='style.xsl'"
$xmlWriter.WriteProcessingInstruction("xml-stylesheet", $XSLPropText)

$xmlWriter.WriteStartElement("Server") # Write Root Element

# Write the Basic System Elements to the XML Document
$xmlWriter.WriteStartElement("SystemInfo")
$xmlWriter.WriteElementString("Hostname","$CompName")
$xmlWriter.WriteElementString("IPAddress","$IPAddress")
$xmlWriter.WriteStartElement("Drives") # Add drive information as individual elements

# Get drive information and add each to XML
$logicalDisk = Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" ComputerName localhost
$count=0
foreach($disk in $logicalDisk)
{
$diskObj = "" | Select-Object Disk,Size,FreeSpace
$diskObj.Disk = $disk.DeviceID
$diskObj.Size = "{0:n0} GB" -f (($disk | Measure-Object -Property Size -Sum).sum/1gb)
$diskObj.FreeSpace = "{0:n0} GB" -f (($disk | Measure-Object -Property FreeSpace -Sum).sum/1gb)
$DriveLetter = $diskObj.Disk
$DriveSize = $diskObj.Size
$DriveFreeSpace = $diskObj.FreeSpace
$xmlWriter.WriteStartElement("Disk$count") # Add tag for each drive
$xmlWriter.WriteElementString("DriveLetter","$DriveLetter") # Write Drive Letter to XML
$xmlWriter.WriteElementString("DriveSize","$DriveSize") # Write Drive Size to XML
$xmlWriter.WriteElementString("DriveFreeSpace","$DriveFreeSpace") # Write Drive Free Space to XML
$xmlWriter.WriteEndElement # <-- Closing Drive Tag
$count++
}
# Write Close Tag for Drives and SysInfo elements
$xmlWriter.WriteEndElement # <-- Closing Drives Tag
$xmlWriter.WriteEndElement # <-- Closing SystemInfo
# Write Close Tag for Root Element
$xmlWriter.WriteEndElement # <-- Closing Server

# End the XML Document
$xmlWriter.WriteEndDocument()

# Finish The Document
$xmlWriter.Finalize
$xmlWriter.Flush
$xmlWriter.Close()

The XML output looks like this:

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='style.xsl'?>
<Server>
        <SystemInfo>
            <Hostname>TEST-SERVER</Hostname>
            <IPAddress>10.0.0.10</IPAddress>
            <Drives>
                <Disk0>
                <DriveLetter>C:</DriveLetter>
                <DriveSize>223 GB</DriveSize>
                <DriveFreeSpace>34 GB</DriveFreeSpace>
                <Disk1>
                    <DriveLetter>D:</DriveLetter>
                    <DriveSize>931 GB</DriveSize>
                    <DriveFreeSpace>547 GB</DriveFreeSpace>
                    <Disk2>
                        <DriveLetter>E:</DriveLetter>
                        <DriveSize>466 GB</DriveSize>
                        <DriveFreeSpace>466 GB</DriveFreeSpace>
                        <Disk3>
                            <DriveLetter>G:</DriveLetter>
                            <DriveSize>931 GB</DriveSize>
                            <DriveFreeSpace>159 GB</DriveFreeSpace>
                        </Disk3>
                    </Disk2>
                </Disk1>
            </Disk0>
        </Drives>
    </SystemInfo>
</Server>

And this is how I need to have it appear:

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='style.xsl'?>
<Server>
    <SystemInfo>
        <Hostname>TEST-SERVER</Hostname>
        <IPAddress>10.0.0.10</IPAddress>
        <Drives>
            <Disk0>
                <DriveLetter>C:</DriveLetter>
                <DriveSize>223 GB</DriveSize>
                <DriveFreeSpace>34 GB</DriveFreeSpace>
            </Disk0>
            <Disk1>
                <DriveLetter>D:</DriveLetter>
                <DriveSize>931 GB</DriveSize>
                <DriveFreeSpace>547 GB</DriveFreeSpace>
            </Disk1>
            <Disk2>
                <DriveLetter>E:</DriveLetter>
                <DriveSize>466 GB</DriveSize>
                <DriveFreeSpace>466 GB</DriveFreeSpace>
            </Disk2>
            <Disk3>
                <DriveLetter>G:</DriveLetter>
                <DriveSize>931 GB</DriveSize>
                <DriveFreeSpace>159 GB</DriveFreeSpace>
            </Disk3>
        </Drives>
    </SystemInfo>
</Server>

Can someone tell me what I'm doing wrong?

Thanks

Upvotes: 1

Views: 285

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174435

You're missing a set of parentheses (()) at the end of $XmlWriter.WriteEndElement:

$xmlWriter.WriteStartElement("Disk$count") # Add tag for each drive
$xmlWriter.WriteElementString("DriveLetter","$DriveLetter") # Write Drive Letter to XML
$xmlWriter.WriteElementString("DriveSize","$DriveSize") # Write Drive Size to XML
$xmlWriter.WriteElementString("DriveFreeSpace","$DriveFreeSpace") # Write Drive Free Space to XML
$xmlWriter.WriteEndElement() # <-- Closing Drive Tag - don't forget the the ()

Without the (), it just returns a PSMethod object with the method's signature(s), but it's never executed, which is why your <Drives> child elements keep nesting

Upvotes: 2

Related Questions