Auto fix services after comparing before and after reboot

This topic contains 8 replies, has 3 voices, and was last updated by  savan kariya 3 years, 2 months ago.

  • Author
  • #23810

    savan kariya

    I succeeded in comparing the services before and after reboot, how would i auto fix it. If someone can help.

    Basically, i want every service which was Running before, should be running now.

    Since now I have got this :

    $compareobject = Compare-Object -ReferenceObject $(Get-Content C:\before.txt) -DifferenceObject $(Get-Content C:\after.txt)|
    Where-Object {$_.SideIndicator -eq "=>"}| ForEach-object{$_.InputObject}

  • #23813

    Jaap Brasser

    So what you want to do is use the $_.InputObject as input for Get-Service which can then be piped into Start-Service. Have a look at the following example and let me know if it makes sense:

    Compare-Object -ReferenceObject $(Get-Content C:\before.txt) -DifferenceObject $(Get-Content C:\after.txt)|
    Where-Object {$_.SideIndicator -eq "=>"}| ForEach-object{Get-Service $_.InputObject | Start-Service}

    What you should consider though is that there is no error handling, or logging to the console. If you would like to verify if everything is running you would have to run the command again without the | ForEach-Object portion of the pipeline.

  • #23815

    Don Jones

    I wouldn't use TXT files for the comparison. Use Export-CliXML to create your comparison files, and compare those. Limit the comparison to whatever properties you want, but XML will produce a more useful input object, especially when it comes to debugging.

  • #23821

    savan kariya

    Thanks Jaap for getting it real quick, however I am still unable to get the auto fix done. It looks like the .txt file doesn't contain the headers (Name and Status) and that's why it is unable to find the difference object in terms of service. It gives me below error; I also tried for .csv and .xml files neither of them worked though. Can you put something together for this.

    PS C:\> Compare-Object -ReferenceObject $(Get-Content C:\before.txt) -DifferenceObject $(Get-Content C:\after.txt)|
    Where-Object {$_.SideIndicator -eq "=>"}| ForEach-object{Get-Service $_.inputobject | Start-Service}

    [b]Get-Service : Cannot find any service with service name 'Stopped BITS Background Intelligent Transfer Ser...'.
    At line:2 char:58
    + Where-Object {$_.SideIndicator -eq "=>"}| ForEach-object{Get-Service $_.inputobj ...
    + ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: [Stopped BITS ...Transfer Ser...:String] [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand[/b]

  • #23822

    savan kariya

    Ohk.. I have got the solution.

    [b]Get-WmiObject -Class win32_service | where {$_.state -ne 'Running' } | Export-Clixml -Path "C:\before.xml"
    $Bfr_Rbt = Import-Clixml -Path "C:\before.xml"
    Get-WmiObject -Class win32_service | where {$_.state -ne 'Running' } | Export-Clixml -Path "C:\after.xml"
    $Aft_Rbt = Import-Clixml -Path "C:\after.xml"
    $Serv = Compare-Object $Bfr_Rbt $Aft_Rbt -Property name,state | Start-Service[/b]

    But now I want it for multiple computers, listed in a file. How would I do that?

  • #23823

    Jaap Brasser

    Okay so it really depends on what kind of information you would like to export, indeed the example I listed only works if you source files would either only contain the displayname or the name of the service. I suggest you use what Don Jones suggested and export your results as CLIXml. Something along these lines should help you get started:

    Get-Service | Where-Object -FilterScript {$_.Status -eq 'Running'} |
    Export-Clixml -Path C:\Before.xml

    Then you could update the ForEach-Object portion of your script to this:

    | ForEach-object {
        Get-Service -Name $_.InputObject.Name | Start-Service
    | ForEach-object {
        Get-Service -Name $_.InputObject.DisplayName | Start-Service

    Let me know how that works out for you.

  • #23825

    Jaap Brasser

    Ah sorry didn't see you response there before I typed mine, it depends you can use Start-Service in combination with Invoke-Command if you have PowerShell Remoting enabled in your environment. If you don't you could start the services using WMI. Do you have PowerShell Remoting enabled for the computers you want to include in this job?

  • #23847

    savan kariya

    No, I don't have remoting enabled for my computer objects.

  • #23862

    savan kariya

    OK, I have got something... and it works... But I noticed that – "WinRM is not set up to allow remote access to this machine for management.
    The following changes must be made:
    Set the WinRM service type to delayed auto start.
    Start the WinRM service.
    Create a WinRM listener on http://* to accept WS-Man requests to any IP on this

    Now, I have 3000 client objects where I want to run this script upon and to change the WinRM Config on all of them is not a good idea.

    Is there any other way we can do this?

    Invoke-Command -ComputerName (get-content C:\computers.txt) {Get-WmiObject -Class win32_service | where {$_.state -ne 'Running' } }| Export-Clixml -Path "C:\before.xml"
    $Bfr_Rbt = Import-Clixml -Path "C:\before.xml"
    Invoke-Command -ComputerName (get-content C:\computers.txt) {Get-WmiObject -Class win32_service | where {$_.state -ne 'Running' }} | Export-Clixml -Path "C:\after.xml"
    $Aft_Rbt = Import-Clixml -Path "C:\after.xml"
    $serv = Compare-Object $Bfr_Rbt $Aft_Rbt -Property Name, State, PSComputerName
    Get-Service -name($serv.Name) -ComputerName($serv.PSComputerName) | Start-Service

You must be logged in to reply to this topic.