it-swarm.com.de

Wie man in Powershell durch XML iteriert?

Ich habe dieses XML-Dokument in einer Textdatei:

<?xml version="1.0"?>
<Objects>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="DisplayName" Type="System.String">SQL Server (MSSQLSERVER)</Property>
    <Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Running</Property>
  </Object>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="DisplayName" Type="System.String">SQL Server Agent (MSSQLSERVER)</Property>
    <Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Stopped</Property>
  </Object>
</Objects>

Ich möchte durch jedes Objekt iterieren und DisplayName und ServiceState finden. Wie würde ich das machen? Ich habe alle möglichen Kombinationen ausprobiert und bemühe mich, das herauszufinden.

Ich mache das, um das XML in eine Variable zu bekommen:

[xml]$priorServiceStates = Get-Content $serviceStatePath;

dabei ist $serviceStatePath der oben angegebene Name der XML-Datei. Ich dachte dann, ich könnte so etwas tun:

foreach ($obj in $priorServiceStates.Objects.Object)
{
    if($obj.ServiceState -eq "Running")
    {
        $obj.DisplayName;
    }
}

Und in diesem Beispiel möchte ich einen String mit SQL Server (MSSQLSERVER) ausgeben.

28
Mark Allison

PowerShell verfügt über integrierte XML- und XPath-Funktionen . Sie können das Cmdlet Select-Xml mit einer XPath-Abfrage verwenden, um Knoten aus einem XML-Objekt auszuwählen, und anschließend.

[xml]$xml = Get-Content $serviceStatePath
$nodes = Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml
$nodes | ForEach-Object {$_.Node.'#text'}

Oder kürzer

[xml]$xml = Get-Content $serviceStatePath
Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml |
  % {$_.Node.'#text'}
35
mswietlicki

Sie können dies auch ohne den [xml] -Cast tun. (Obwohl xpath eine Welt für sich ist. https://www.w3schools.com/xml/xml_xpath.asp )

$xml = (select-xml -xpath / -path stack.xml).node
$xml.objects.object.property

Oder nur dies, xpath unterscheidet zwischen Groß- und Kleinschreibung. Beide haben die gleiche Ausgabe:

$xml = (select-xml -xpath /Objects/Object/Property -path stack.xml).node
$xml


Name         Type                                                #text
----         ----                                                -----
DisplayName  System.String                                       SQL Server (MSSQLSERVER)
ServiceState Microsoft.SqlServer.Management.Smo.Wmi.ServiceState Running
DisplayName  System.String                                       SQL Server Agent (MSSQLSERVER)
ServiceState Microsoft.SqlServer.Management.Smo.Wmi.ServiceState Stopped
0
js2010