Create PowerShell 2-Dimensional Array From XML Configuration File

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.
LVL 2
Alan VargaAccess DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

oBdACommented:
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

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Alan VargaAccess DeveloperAuthor 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.
0
oBdACommented:
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

0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

Alan VargaAccess DeveloperAuthor 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.
0
Alan VargaAccess DeveloperAuthor 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.
0
Alan VargaAccess DeveloperAuthor Commented:
This was understandable, short and to the point.  Kudos for a well-written solution that worked as advertised.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.