Powershell script to remotely start services across a domain and email on failur

This topic contains 1 reply, has 2 voices, and was last updated by Profile photo of Brian B Brian B 7 months, 3 weeks ago.

  • Author
    Posts
  • #38128
    Profile photo of Jesse
    Jesse
    Participant

    Hey guys, I'm still learning powershell and I'm working on developing a slightly more advanced script than what I'm used to working with, could use some help.

    Basically this script needs to scan all servers on a domain for any "automatic" services that are in a "stopped" state, attempt to start them, and return an error code which will then be emailed to a case creation queue if the service fails to start. I have the following so far (No email config included, I can always add that later). Ideally I would also like to add an exclusion list that will skip over services with specific names (like the software protection service).

    So far, this script seems to pull the CSV correctly, try is working correctly, and it successfully cycles through each server, ultimately presenting the following output:

    Updated Server list has been pulled from AD and sent to C:\Patching\ObjectList.csv
    Press Enter to continue...:
    Attempting to start the Print Spooler service on ASHDC01
    0
    Successfully started 'Print Spooler' on ASHDC01
    Attempting to start the Software Protection service on ASHDC01
    Set-Service : Service 'Software Protection (sppsvc)' cannot be configured due to the following error: Access is denied
    At C:\Users\jesse\Desktop\ServiceCheck.ps1:58 char:84
    + ... e $Name.name | Set-Service -Status Running
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Set-Service], ServiceCommandException
    + FullyQualifiedErrorId : CouldNotSetService,Microsoft.PowerShell.Commands.SetServiceCommand

    0
    Successfully started 'Software Protection' on ASHDC01
    Attempting to start the Software Protection service on ASHVC01
    Set-Service : Service 'Software Protection (sppsvc)' cannot be configured due to the following error: Access is denied
    At C:\Users\jesse\Desktop\ServiceCheck.ps1:58 char:84
    + ... e $Name.name | Set-Service -Status Running
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Set-Service], ServiceCommandException
    + FullyQualifiedErrorId : CouldNotSetService,Microsoft.PowerShell.Commands.SetServiceCommand

    0
    Successfully started 'Software Protection' on ASHVC01

    This has a few issues right off the bat, A: the error code for access denied should be "2", not 0– so the switch command doesn't appear to be correctly displaying the output. The software protection service also doesn't exist on ASHVC01 so it isn't correctly scanning for stopped services on the new server but simply seems to be using the services that didn't start on the first server for the second (I'm saying this because I stopped the print spooler on the ashvc01 server also and it didn't attempt to start). Any help would be greatly appreciated.

    Import-Module ActiveDirectory
    
    ## Return Code Listing
    $ReturnCode = @{}
    $ReturnCode.Add(0,"Success")
    $ReturnCode.Add(1,"Not Supported")
    $ReturnCode.Add(2,"Access Denied")
    $ReturnCode.Add(3,"Dependent Services Running")
    $ReturnCode.Add(4,"Invalid Service Control")
    $ReturnCode.Add(5,"Service Cannot Accept Control")
    $ReturnCode.Add(6,"Service Not Active")
    $ReturnCode.Add(7,"Service Request Timeout")
    $ReturnCode.Add(8,"Unknown Failure")
    $ReturnCode.Add(9,"Path Not Found")
    $ReturnCode.Add(10,"Service Already Running")
    $ReturnCode.Add(11,"Service Database Locked")
    $ReturnCode.Add(12,"Service Dependency Deleted")
    $ReturnCode.Add(13,"Service Dependency Failure")
    $ReturnCode.Add(14,"Service Disabled")
    $ReturnCode.Add(15,"Service Logon Failure")
    $ReturnCode.Add(16,"Service Marked For Deletion")
    $ReturnCode.Add(17,"Service No Thread")
    $ReturnCode.Add(18,"Status Circular Dependency")
    $ReturnCode.Add(19,"Status Duplicate Name")
    $ReturnCode.Add(20,"Status Invalid Name")
    $ReturnCode.Add(21,"Status Invalid Parameter")
    $ReturnCode.Add(22,"Status Invalid Service Account")
    $ReturnCode.Add(23,"Status Service Exists")
    $ReturnCode.Add(24,"Service Already Paused")
    
    ##Defines Output files needed for listing each server in the environment
    
    $outputfile = "C:\Patching\ObjectList.csv"
    $servicelist = "C:\Patching\ServiceList.csv"
    $Class = @{
    Class = "Win32_Service"
    }
    $FindFilter = @{
    Filter = "startmode='auto' and state='Stopped'"
    }
    
    ##Pull all "Server" Operating system PCs from Active Directory and export to the defined outputfile.
    
    Get-ADComputer -Filter {OperatingSystem -Like "Windows *Server*"} -Property * | select Name | Export-CSV -path $outputfile -force -notype
    write-host "Updated Server list has been pulled from AD and sent to" $outputfile
    
    Pause 10
    
    ##Define the Servers object for the next foreach
    $computername = Import-CSV $outputfile
    
    try{
    foreach ($name in $computername){
    
              Foreach($Svc in Get-WmiObject @Class @FindFilter){
              Write-Host "Attempting to start the"$Svc.DisplayName"service on "$Name.name -ForeGround "Yellow"
              $Command = Get-Service -Name $Svc.DisplayName -Computername $Name.name | Set-Service -Status Running
             [int32]$Result = $Command.ReturnValue
              $Result
    
    switch ($Result){
    0 {Write-Output "Successfully started '$($Svc.DisplayName)' on $($Name.name)"; break}
    default {Write-Error -Message "Error starting '$($Svc.DisplayName)' on $($Svc.__SERVER). Error: $($ReturnCode[$Result])."}
    }
    }}}
    catch{
    Write-Error "Error trying to connect and retrieve services from $Name.name"
    }
    
  • #38133
    Profile photo of Brian B
    Brian B
    Participant

    I don't have time to completely look over your code today, but I think you need to move your Try/Catch code inside the Foreach. That way for each system, it tries/catches. Probably most of your problem.

    Brian

You must be logged in to reply to this topic.