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.
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
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
}
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 where 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
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