Create PowerShell 2-Dimensional Array From XML Configuration File

Alan Varga
Alan Varga used Ask the Experts™
on
How do I convert the child nodes for a specific computer in this configuration file to a 2-dimensional table?  Here is the XML:
<PsProjects>
    <metadata>
        <revdate>2017-04-14</revdate>
    </metadata>


    <computers>

        <computer id="livingroom02">
            <item type="folder">C:\Computer-livingroom02 SYS 033</item>
            <item type="folder">C:\Computer-livingroom02 SYS 033\Hardware\Network Adapters</item>
            <item type="folder">C:\Computer-livingroom02 SYS 033\Software</item>
            <item type="folder">C:\Program2\Powershell</item>
            <item type="folder">C:\Program2\Varga\Network Mapping</item>
            <item type="folder">D:\Programming Languages\PowerShell</item>
            <item type="textfile">PsProjects.xml</item>
        </computer>

        <computer id="work">
            <item type="folder">C:\Computer</item>
            <item type="folder">C:\AlansDownloads\Alan\_AlansBriefcase</item>
            <item type="folder">C:\Computer\Hardware\Network Adapters</item>
            <item type="folder">C:\Computer\Software</item>
            <item type="folder">C:\Program2\Varga\Network Mapping</item>
            <item type="folder">C:\Workshop\PowerShell-work</item>
            <item type="textfile">PsProjects.xml</item>
        </computer>

    </computers>
</PsProjects>

Open in new window


This code doesn't seem to allow accessing individual elements of a specific item:
ForEach ( $computer in $ProjectsConfigFile.SelectNodes( "//PsProjects/computers/computer" ) ) {
    $PsComputerName = $computer.Attributes['id'].Value
    If ( $PsComputerName -eq $ThisComputerId ) {
        $MatchingComputer = $computer

        [array]$ProjectItems = $MatchingComputer.item

        break
    }
}

Open in new window


The results I want are like this:

$Result = $ProjectItems | Out-GridView -Passthru -Title "Select an item and click OK or press <Enter>, or press <Esc> to quit"
$Selection = [array]::IndexOf( $ProjectItems, $Result )

$SelectedItemText = $ProjectItems[$Selection].'#text'
$SelectedItemType = $ProjectItems[$Selection].type

#or

$SelectedItem = $ProjectItems[$Selection]
$SelectedItemText = $SelectedItem.'#text'
$SelectedItemType = $SelectedItem.type

Open in new window


I have a Switch statement further on that will do something different with $SelectedItemText, depending on whether $SelectedItemType is a folder or a textfile.

My problem is that $Result returns the type and text together.  Also, GridView lists the type column first and the #text column second.  What I want returned is the #text# for the row I select.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
Try it like this:
$ThisComputerId = 'work'
$ProjectsConfigFile = [xml](Get-Content -Path D:\Temp\blubb.xml)
$ComputerNode = $ProjectsConfigFile.SelectSingleNode("//PsProjects/computers/computer[@id='$($ThisComputerId)']")
$ProjectItems = $ComputerNode.SelectNodes('item') | Select-Object -Property @{n='Type'; e={$_.Type}}, @{n='Text'; e={$_.'#text'}}
If ($Result = ($ProjectItems | Out-GridView -Title "Select an item and click OK or press <Enter>, or press <Esc> to quit" -OutputMode Single)) {
	$SelectedItemType = $Result.Type
	$SelectedItemText = $Result.Text
} Else {
	Exit 1
}
"Selected Type: $($SelectedItemType)" | Write-Host
"Selected Text: $($SelectedItemText)" | Write-Host

Open in new window

Alan VargaAccess Developer

Author

Commented:
That looks much more efficient, and I understand it, but when I evaluate $Result in debug mode (breakpoint at line 6) I get an object, but not one with properties I can use:

Hit Line breakpoint on 'C:\Computer\Untitled1.ps1:6'
[DBG]: PS C:\Computer>> $result
@{Type=folder; Text=C:\Computer}

Open in new window


However, typing $Result. (note the period to prompt for properties), Intellisense only offers Length, Clone, etc.
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
Can't reproduce, works just fine here. Are you using the xml you attached, and the exact script I posted? Does it display correctly in the GridView?
$ThisComputerId = 'work'
$ProjectsConfigFile = [xml](Get-Content -Path D:\Temp\PsProjects.xml)
$ComputerNode = $ProjectsConfigFile.SelectSingleNode("//PsProjects/computers/computer[@id='$($ThisComputerId)']")
$ProjectItems = $ComputerNode.SelectNodes('item') | Select-Object -Property @{n='Type'; e={$_.GetAttribute('type')}}, @{n='Text'; e={$_.InnerText}}
If ($Result = ($ProjectItems | Out-GridView -Title "Select an item and click OK or press <Enter>, or press <Esc> to quit" -OutputMode Single)) {
	$SelectedItemType = $Result.Type
	$SelectedItemText = $Result.Text
} Else {
	Exit 1
}
"Selected Type: $($SelectedItemType)" | Write-Host
"Selected Text: $($SelectedItemText)" | Write-Host

Open in new window

Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Alan VargaAccess Developer

Author

Commented:
This is strange: I saved your most recent (re-)post on my computer at home, adjusted the computer id and the path for the configuration file and it worked without a hitch.

I will have to do some more troubleshooting at work on Monday.  Thanks for your patience and guidance.
Alan VargaAccess Developer

Author

Commented:
I figured it out!  Near the beginning of my script (which was not shown here) I was initializing some variables (a habit of VBA option explicit).  My problem was
[string]$Result = ""

Open in new window

After I commented that out, $Result was allowed to be whatever it wanted to be (object? array?), everything worked as expected.  Thanks for your help.
Alan VargaAccess Developer

Author

Commented:
This was understandable, short and to the point.  Kudos for a well-written solution that worked as advertised.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial