Help with Comparing XML Objects

This topic contains 4 replies, has 4 voices, and was last updated by  Vern Anderson 3 years, 10 months ago.

  • Author
  • #16717

    Rehan Peerzade

    Need help with with comparing XML Objects, I am trying to write a script which starts automatic services only which were running before reboot of a server.

    $Bfr_Rbt = Import-Clixml -Path "C:\BR_Stp.xml"
    Get-WmiObject -Class win32_service | where {$_.startmode -eq 'Auto' -and $_.state -ne 'Running' } | Export-Clixml -Path "C:\AR_Stp.xml"
    $Aft_Rbt = Import-Clixml -Path "C:\AR_Stp.xml"
    $Serv = Compare-Object $Bfr_Rbt $Aft_Rbt

    The $serv will now PSCustomObject values. And I cannot pass this to Start-Service. Am I going wrong, Please assist.

  • #16719

    Jason Hofferle

    When you run Compare-Object, use the -Property parameter to specify only the relevant properties. It will still output a PSCustomObject, but it will be structured in a way that can be passed to Start-Service.

    $serv = Compare-Object $a $b -Property name,state
  • #16720

    Rob Simmers

    If you look at the syntax:

    Start-Service [[b]-InputObject] [-Exclude ] [-Include ] [-PassThru ] []

    Start-Service [-Exclude ] [-Include ] [-PassThru ] -DisplayName []

    Start-Service [[b]-Name] [/b] [-Exclude ] [-Include ] [-PassThru ] []

    Get-Service wuauserv | Start-Service
    Start-Service -DisplayName"Windows Update"
    Start-Service -Name  wuauserv

    Notice that most params accept a string array as well, so you could find all required services and put them in an array to do something like:

    $arrServices = @("WSearch"," wuauserv","wudfssvc")
    Start-Service -Name $arrServices

    If you review the help, it also indicates that -Name accepts pipeline input:

    Specifies the service names for the service to be started.

    Required? true
    Position? 1
    Default value
    Accept pipeline input? true (ByPropertyName, ByValue)
    Accept wildcard characters? false

    As long as the object you are passing contains a "Name" property, it can be piped (e.g. $myObject | Start-Service). So, there are many ways to actually pass the information, but you don't show how you are trying to do it. This is a basic example without the XML conversion:

    $before = Get-WmiObject -Class Win32_Service -Filter "StartMode = 'Auto' And State  'Running'"
    $after = Get-WmiObject -Class Win32_Service -Filter "StartMode = 'Auto' And State  'Running'"
    Compare-Object $before $after -PassThru | Where{$_.SideIndicator -eq "< ="} | foreach{
        "Starting {0}" -f $_.Name
        Start-Service -Name $_.Name
  • #16752

    Rehan Peerzade

    Hi Jason and Rob, It worked. Now i am able to compare the files and also pass on the output to start-service. I was not performing the [b]where[/b] part before.
    Thank you for the help.

    Get-WmiObject -Class win32_service | where {$_.startmode -eq 'Auto' -and $_.state -ne 'Running' } | Export-Clixml -Path "C:\Before.xml"
    $Before =  Import-Clixml -Path "C:\Before.xml"
    Get-WmiObject -Class win32_service | where {$_.startmode -eq 'Auto' -and $_.state -ne 'Running' } | Export-Clixml -Path "C:\After.xml"
    $after =  Import-Clixml -Path "C:\After.xml"
    $tostart = Compare-Object $Before $After -PassThru | where { $_.SideIndicator -eq "=>" }
    $tostart | Start-Service
  • #16755

    Vern Anderson

    Some services especially those where the name starts with "CLR_" will be set to auto but don't need to stay running unless something calls them. In fact if you start them in the GUI you get a pop-up saying just that. The CMDLETs are really meant for working within PowerShell and don't do a good job of working with true XML formats as well. Using the XML class is the way to go in my opinion.

    For learning XML I found that Dr. Tobias Weltner's PowerShell monthly issue #11 was a great resource!


    This helped me learn XML but it was not easy.


You must be logged in to reply to this topic.