Author Posts

July 2, 2014 at 5:02 am

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.

July 2, 2014 at 5:44 am

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

July 2, 2014 at 6:56 am

If you look at the syntax:

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:

-Name
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
}

July 2, 2014 at 10:45 pm

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

July 3, 2014 at 5:47 am

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!

[url]http://powershell.com/cs/media/p/33169.aspx[/url]

This helped me learn XML but it was not easy.

-VERN