I have two xml files with the same format, I can get the output in powershell to display each file correctly but I need to compare StatusErrorResultsFiltered.xml to StatusErrorResults.xml and output the unique entries that exist in one but not both files,excluding the "description" field.
Current Code:
$XMLPath = "C:\Users\John.Doe\Desktop\Projects\Powershell\backend library conversion\TEST\"
# Exporting the unique results as undefined errors to an XML file
$filteredResults = [xml](Get-Content "$XMLPath/Output/StatusErrorResultsFiltered.xml")
$unitResults = [xml](Get-Content "$XMLPath/StatusErrorResults.xml")
$originalEntries = $unitResults.Objs.obj.ms.s | Where-Object {$_.N -eq "Device" -or $_.N -eq "Mstatus"}
$filteredEntries = $filteredResults.Objs.obj.ms.s | Where-Object {$_.N -eq "Device" -or $_.N -eq "Mstatus"}
# Using Compare-Object to find unique entries
$uniqueEntries = Compare-Object $originalEntries $filteredEntries -Property Device,Mstatus |
Select-Object -Property Device,Mstatus |
Sort-Object -unique -Property Device,Mstatus
$uniqueEntries | Export-Clixml -Path "$XMLPath\Output\UndefinedErrors.xml"
Currently the undefinedErrors.xml is showing one node with Device and Mstatus but does not actually include the data that should be there.
<Objs xmlns="http://schemas.microsoft.com/powershell/2004/04" Version="1.1.0.1">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.System.Management.Automation.PSCustomObject</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<Nil N="Device"/>
<Nil N="Mstatus"/>
</MS>
</Obj>
</Objs>
StatusErrorResultsFiltered.xml
<Objs xmlns="http://schemas.microsoft.com/powershell/2004/04" Version="1.1.0.1">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="Device">DeviceName5</S>
<S N="Mstatus">5</S>
<S N="Description">Generic Text for example</S>
</MS>
</Obj>
<Obj RefId="1">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName4</S>
<S N="Mstatus">38</S>
<S N="Description">Generic Text for example</S>
</MS>
</Obj>
<Obj RefId="2">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName3</S>
<S N="Mstatus">18</S>
<S N="Description">Generic Text for example</S>
</MS>
</Obj>
<Obj RefId="3">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName2</S>
<S N="Mstatus">16</S>
<S N="Description">Generic Text for example</S>
</MS>
</Obj>
<Obj RefId="4">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName1</S>
<S N="Mstatus">49</S>
<S N="Description">Generic Text for example</S>
</MS>
</Obj>
</Objs>
StatusErrorResults.xml
<Objs xmlns="http://schemas.microsoft.com/powershell/2004/04" Version="1.1.0.1">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="Device">DeviceName5</S>
<S N="Mstatus">5</S>
</MS>
</Obj>
<Obj RefId="1">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName4</S>
<S N="Mstatus">38</S>
</MS>
</Obj>
<Obj RefId="2">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName3</S>
<S N="Mstatus">18</S>
</MS>
</Obj>
<Obj RefId="3">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName2</S>
<S N="Mstatus">16</S>
</MS>
</Obj>
<Obj RefId="4">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName1</S>
<S N="Mstatus">49</S>
</MS>
</Obj>
<Obj RefId="5">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName6</S>
<S N="Mstatus">16</S>
</MS>
</Obj>
<Obj RefId="6">
<TNRef RefId="0"/>
<MS>
<S N="Device">DeviceName7</S>
<S N="Mstatus">49</S>
</MS>
</Obj>
</Objs>
CodePudding user response:
Since you're dealing with CLIXML files - i.e. XML-based files that contain .NET objects serialized by PowerShell - you can use Import-Clixml
to import them, which makes comparing the resulting objects with Compare-Object
easier:
$XMLPath = 'C:\Users\John.Doe\Desktop\Projects\Powershell\backend library conversion\TEST'
$filteredFile = "$XMLPath/Output/StatusErrorResultsFiltered.xml"
$resultFile = "$XMLPath/StatusErrorResults.xml"
Compare-Object (Import-Clixml $filteredFile) (Import-Clixml $resultFile) -Property Device, MStatus |
Select-Object * -ExcludeProperty SideIndicator |
Sort-Object -Unique -Property Device, Mstatus |
Export-Clixml "$XMLPath\Output\UndefinedErrors.xml"
Note the need to remove the SideIndicator
property from the output objects, which Compare-Object
invariably adds to the output objects.
CodePudding user response:
Use Import-CliXMl, it will convert the XML to PS Objects and then you can can work on the unique part, then again Export-CliXml
$unitResults = Import-Clixml "$XMLPath/StatusErrorResults.xml"
$filteredResults = $(Import-Clixml "$XMLPath/Output/StatusErrorResultsFiltered.xml" | Select-Object -Property "Device", "Mstatus")
$unitResults = $filteredResults
$endResult = $unitResults | Sort-Object -Property Device,Mstatus -Unique
$endResult | Export-Clixml -Path "$XMLPath\Output\UndefinedErrors.xml"