How can I monitor all services set to automatic on a server?
How do I monitor all services on a server set to automatic
Votes:
0
Best Answer
Votes:
1
Attention Make sure to use at least five minute intervals to avoid high CPU load
Use the following PowerShell script with a EXE/Script sensor:
#=========================== # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | ||(_ | #|_| |_|_\ |_|\___| # NETWORK MONITOR #------------------- # Description: This script will iterate through the windows services that are set to automatic starting and alert # if they don't. # Parameters: # -ComputerName - The name of the computer you want to check for its service (ip is okay too) # -IgnoreList: The services that are ignored by the script (like google update services) # -Username: The username and the domain/computer name that applies to the target hosts # -Password: The password for the given user. # Example: # Get-Services.ps1 -ComputerName %host -Username "%windowsdomain\%windowsuser" -Password "%windowspassword" -IgnoreList "Service1,Service2" # Values with % will be replaced by PRTG automatically. # ------------------ # (c) 2014 Stephan Linke | Paessler AG param( [string]$ComputerName = "localhost", [string]$IgnoreList = "Dell Digital Delivery Service,Google Update", [string]$UserName, [string]$Password ) # Error if there's anything going on $ErrorActionPreference = "Stop" # Generate Credentials Object $SecPasswd = ConvertTo-SecureString $Password -AsPlainText -Force $Credentials= New-Object System.Management.Automation.PSCredential ($UserName, $secpasswd) # hardcoded list that applies to all hosts $IgnoreScript = 'Google Update Service (gupdate),PRTG Probe Service' $IgnoreCombined = @($IgnoreList) + @($IgnoreScript) $Ignore = $IgnoreCombined -Split "," # Get list of services that are not running, not in the ignore list and set to automatic. Try{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName -Credential $Credentials | Where {$_.StartMode -eq 'Auto' -and $Ignore -notcontains $_.DisplayName -and $_.State -ne 'Running'} } # If the script runs for the PRTG server itself, we don't need credentials Catch{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName | Where {$_.StartMode -eq 'Auto' -and $Ignore -notcontains $_.DisplayName -and $_.State -ne 'Running'} } if($Services){ $ServiceList = ($Services | Select -expand DisplayName) -join ", " if(!$Services.Count){ Write-Host "1:Automatic service(s) not running:"$ServiceList exit 1 } else{ Write-Host $Services.Count":Automatic service(s) not running:"$ServiceList exit 1 } } else{ Write-Host "0:All automatic services are running." exit 0 } #===========================
Note that the services are comma seperated (service1,service2) without a space, both in $IgnoreList and $IgnoreScript. Let me know if that worked for you :)
Created on Nov 26, 2014 1:46:14 PM by
Stephan Linke [Paessler Support]
Last change on May 9, 2018 7:33:17 AM by
Stephan Linke [Paessler Support]
37 Replies
Votes:
0
Hey fitzgeraldk,
on PRTG you got the option to monitor services via Windows Object (WMI). You can choose service for service, but you have to know, which one is "automatic".
To add one Sensor, do the following:
- Add new Sensor
- Choose WMI in top menu of "new sensor"
- Choose Service WMI
- "Mark" the services you want to monitor
- "Save"
That's it, now you have an monitoring of these sensors. But you have to get attention, every service is a sensor. If you don't got unlimited, don't waste power of your probe ;).
Best
Sascha
Votes:
1
Attention Make sure to use at least five minute intervals to avoid high CPU load
Use the following PowerShell script with a EXE/Script sensor:
#=========================== # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | ||(_ | #|_| |_|_\ |_|\___| # NETWORK MONITOR #------------------- # Description: This script will iterate through the windows services that are set to automatic starting and alert # if they don't. # Parameters: # -ComputerName - The name of the computer you want to check for its service (ip is okay too) # -IgnoreList: The services that are ignored by the script (like google update services) # -Username: The username and the domain/computer name that applies to the target hosts # -Password: The password for the given user. # Example: # Get-Services.ps1 -ComputerName %host -Username "%windowsdomain\%windowsuser" -Password "%windowspassword" -IgnoreList "Service1,Service2" # Values with % will be replaced by PRTG automatically. # ------------------ # (c) 2014 Stephan Linke | Paessler AG param( [string]$ComputerName = "localhost", [string]$IgnoreList = "Dell Digital Delivery Service,Google Update", [string]$UserName, [string]$Password ) # Error if there's anything going on $ErrorActionPreference = "Stop" # Generate Credentials Object $SecPasswd = ConvertTo-SecureString $Password -AsPlainText -Force $Credentials= New-Object System.Management.Automation.PSCredential ($UserName, $secpasswd) # hardcoded list that applies to all hosts $IgnoreScript = 'Google Update Service (gupdate),PRTG Probe Service' $IgnoreCombined = @($IgnoreList) + @($IgnoreScript) $Ignore = $IgnoreCombined -Split "," # Get list of services that are not running, not in the ignore list and set to automatic. Try{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName -Credential $Credentials | Where {$_.StartMode -eq 'Auto' -and $Ignore -notcontains $_.DisplayName -and $_.State -ne 'Running'} } # If the script runs for the PRTG server itself, we don't need credentials Catch{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName | Where {$_.StartMode -eq 'Auto' -and $Ignore -notcontains $_.DisplayName -and $_.State -ne 'Running'} } if($Services){ $ServiceList = ($Services | Select -expand DisplayName) -join ", " if(!$Services.Count){ Write-Host "1:Automatic service(s) not running:"$ServiceList exit 1 } else{ Write-Host $Services.Count":Automatic service(s) not running:"$ServiceList exit 1 } } else{ Write-Host "0:All automatic services are running." exit 0 } #===========================
Note that the services are comma seperated (service1,service2) without a space, both in $IgnoreList and $IgnoreScript. Let me know if that worked for you :)
Created on Nov 26, 2014 1:46:14 PM by
Stephan Linke [Paessler Support]
Last change on May 9, 2018 7:33:17 AM by
Stephan Linke [Paessler Support]
Votes:
0
Hello Stephan
How can i make it, that the hostname isn't allways the Probe_Server? I'd like to aplly it on all domaincomputers
Thanks for your help
Votes:
0
Hi in4out,
Did you already try to forward the hostname with the parameters
-ComputerName "NameOfTheComputer"
in the sensor settings?
Best regards, Felix
Votes:
0
i´m getting this error:
"Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:\Program Files (x86)\PRTG Network Monitor\custom sensors\EXE\check_automatic_services.ps1:43 char:20 + Catch{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName | Whe ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedA ccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.Pow erShell.Commands.GetWmiObjectCommand )" (Code: PE132)."
what exactly do i have to change?
Created on Jan 27, 2016 8:44:01 AM
Last change on Feb 10, 2016 8:46:24 AM by
Luciano Lingnau [Paessler]
Votes:
0
Dear Daniel,
It looks like that the user does not have the required permissions. Try to use a Domain Administrator and see if the scans work.
Best regards, Felix
Votes:
0
Do I need to create one script per server? I got the script working, but seems that I need to create one powershell script per server.
Thanks, Manny
Votes:
0
Hello MannyL,
you can use only a single script file but you will need to deploy it multiple times (once per device who's services you wish to monitor). When deploying the sensor enter the following in the Parameters field of the sensor:
-ComputerName %host |
This way PRTG will use the device's address each time the sensor is run.
For further set-up instructions please refer to the sensor's manual page.
Best Regards,
Votes:
0
This script is great. is there a posibility to ignore a dynamic service name, from Windows 2016. There is a service: OneSyncSvc_91e8dd1 where the part after the "_" is dynamic for each server and the service are set ti autostart with delay and just runs if a sync is in progress.
Votes:
0
Did you try adding OneSyncSvc_* to the ignore list? :)
Votes:
0
Hi Stephan,
We adapted to XML and expanded the features your script for internal use, but in good spirit I want to share it back with PRTG's community -- however I note that copyright is claimed, would it be OK if I posted our updated version here? If you would prefer to update the original post, I can send it to you privately as well.
Cheers; Kevin
Votes:
0
Hi Kevin,
Feel free to share everything others could help. :)
Please don't forget to put it in the code markup (three { in the beginning and three } in the end of the code).
Votes:
0
Thanks Dariusz!
All: see below, an XML adapted version of the above script. My intention here was to assist in determining if failures are due to new software installations, and to provide some better sensor history. It also uses the PRTG environment variables to reduce the opportunity for typos and other human errors in the parameters. Finally, I added a much-needed grace period to avoid false positives during server startup.
#=========================== # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | ||(_ | #|_| |_|_\ |_|\___| # NETWORK MONITOR #------------------- # Description: This script will iterate through the windows services that are set to automatic starting and alert # if they don't. To aid in reviewing historical data, several counts of services are returned alongside # an uptime count. There is also a grace period to avoid false alarms during boot up. # # Required Parameters: NOTE: these can be omitted if the 'Set placeholders as environment values' is enabled. # -ComputerName: The name of the computer you want to check for its service (ip is okay too) # -Username: The username and the domain/computer name that applies to the target hosts # -Password: The password for the given user. # # Optional Parameters: # -IgnoreList: The services that are ignored by the script (like google update services). Use * as wildcard. Note several # common offenders are excluded in the script, see $IgnoreHardcoded # -StartupGrace: Override the grace period after startup, default of 600s. Note the official behavior of Windows is to start # Automatic (Delayed start) services 2 minutes after the last Automatic service starts, so on slow systems # this may require a longer delay. # # Example: # AdvancedAutomaticServicesCheck.ps1 -ComputerName %host -Username "%windowsdomain\%windowsuser" -Password "%windowspassword" -IgnoreList "Service1, Service2*" # Values with % will be replaced by PRTG automatically. # # ------------------ # Adapted by Kevin White [email protected], from 'Get-Services.ps1' by: # (c) 2014 Stephan Linke | Paessler AG # # Version 2.3 -- April 27,2017 # param( [string]$ComputerName = "", [string]$UserName = "", [string]$Password = "", [string]$IgnoreList = "", [int] $StartupGrace = 600 # NB: "Automatic (Delayed Start)" is actually 2 min after the last automatic service starts, so this seems like a safe default. ) #confirm we have params or env's set for all req'd params $paramErrors=""; if(!$ComputerName) { if(!$env:prtg_host) { $paramErrors += "ComputerName, "; } else { $ComputerName = $env:prtg_host } } if(!$UserName) { if(!$env:prtg_windowsuser) { $paramErrors += "UserName, "; } else { if(!$env:prtg_windowsdomain) { $UserName = $env:prtg_windowsuser } else { $UserName = $env:prtg_windowsdomain + "\" + $env:prtg_windowsuser } } } if(!$Password) { if(!$env:prtg_windowspassword) { $paramErrors += "Password, "; } else { $Password = $env:prtg_windowspassword } } #fix line wrap output on some old systems, see https://kb.paessler.com/en/topic/11163-how-to-avoid-line-breaks-for-powershell-custom-scripts-used-with-an-exe-script-sensor $host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(512,50) #error out if missing critical parameters if($paramErrors) { "<prtg> <error>1</error> <text>In the settings of this sensor, please set the 'Set placeholders as environment values', or add the following script parameter(s): "+$paramErrors.TrimEnd(", ")+".</text> </prtg> " exit 0; } # Error if there's anything going on $ErrorActionPreference = "Stop" # Generate Credentials Object $Credentials= New-Object System.Management.Automation.PSCredential ($UserName, (ConvertTo-SecureString $Password -AsPlainText -Force)) # hardcoded list that applies to all hosts $IgnoreHardcoded = @('Google Update Service (gupdate)', 'Google Update', 'Dell Digital Delivery Service', 'VNC Server Version 4', 'Windows Modules Installer', 'Windows Biometric Service', 'Software Protection', 'Microsoft .NET Framework NGEN*', 'TPM Base Services', 'Windows Update', 'Remote Registry', 'Shell Hardware Detection', 'GoToAssist*', 'Performance Logs and Alerts', 'Windows Licensing Monitoring Service', 'Shell Hardware Detection', 'Volume Shadow Copy', 'Microsoft Exchange Server Extension for Windows Server Backup') # NB: the weird "| ? {$_}" is to remove empty array elements $Ignore = ((@($IgnoreList -Split ",") + $IgnoreHardcoded) | ? {$_} | foreach { [Regex]::Escape($_.trim()) -replace "\*", ".*" } ) -join "|" Try { $All_Services = Get-WmiObject Win32_Service -ComputerName $ComputerName -Credential $Credentials $wmi_os = gwmi Win32_OperatingSystem -ComputerName $ComputerName -Credential $Credentials } Catch { # If the script runs for the PRTG probe server itself, we don't need credentials, lets try w/o creds Try { $All_Services = Get-WmiObject Win32_Service -ComputerName $ComputerName $wmi_os = gwmi Win32_OperatingSystem -ComputerName $ComputerName } Catch { "<prtg> <error>1</error> <text>Error: could not connect to host `"$ComputerName`". " + $Error[0].Exception.Message + ".</text> </prtg> " exit 0; } } $FilteredServices = $All_Services | Where {$_.DisplayName -notmatch $Ignore} $ServicesFilteredOut = $All_Services | Where {$_.DisplayName -match $Ignore} $UptimeSeconds = ([int](New-TimeSpan $wmi_os.ConvertToDateTime($wmi_os.Lastbootuptime) $(get-date)).TotalSeconds) $Services = $FilteredServices | Where {$_.StartMode -eq 'Auto' -and $_.State -ne 'Running'} "<prtg> <result> <channel>Total Services</channel> <unit>Count</unit> <value>" + ($FilteredServices | measure).Count + "</value> <unit>Count</unit> <FLOAT>0</FLOAT> </result> <result> <channel>Total Services Started</channel> <value>" + ($FilteredServices | Where { $_.State -eq 'Running' } | measure).Count + "</value> <unit>Count</unit> <FLOAT>0</FLOAT> </result> <result> <channel>Total Automatic (and Delayed) Services</channel> <value>" + ($FilteredServices | Where { $_.StartMode -eq 'Auto' } | measure).Count + "</value> <FLOAT>0</FLOAT> <unit>Count</unit> </result> <result> <channel>Total Automatic (and Delayed) Services Started</channel> <value>" + ($FilteredServices | Where { $_.StartMode -eq 'Auto' -and $_.State -eq 'Running' } | measure).Count + "</value> <FLOAT>0</FLOAT> <unit>Count</unit> </result> <result> <channel>Total Automatic (and Delayed) Services NOT Started</channel> <value>" + ($FilteredServices | Where { $_.StartMode -eq 'Auto' -and $_.State -ne 'Running' } | measure).Count + "</value> <FLOAT>0</FLOAT> <unit>Count</unit> </result>" if(($FilteredServices | Where { $_.StartMode -eq 'Auto' -and $_.State -ne 'Running' } | measure).Count -ge 1) { #At least 1 service is not running, issue warning or error $NotRunningServices = ($FilteredServices | Where {$_.StartMode -eq 'Auto' -and $_.State -ne 'Running'} | Select -expand DisplayName) -join ", " if($UptimeSeconds -lt $StartupGrace) { "<Warning>1</Warning> <Text>Grace period remaining: "+($StartupGrace - $UptimeSeconds)+"s; Automatic services not running: " + $NotRunningServices + "</Text>" } else { "<Error>1</Error> <Text>Automatic services not running: " + $NotRunningServices + "</Text>" } } " <result> <channel>Uptime</channel>" #useful to see when there is a grace period for startup in graphs "<value>$UptimeSeconds</value> <FLOAT>0</FLOAT> <unit>TimeSeconds</unit> </result> <result> <channel>Total Services Excluded by Filter</channel> <value>" + ($ServicesFilteredOut | measure).Count + "</value> <FLOAT>0</FLOAT> <unit>Count</unit> </result> </prtg>"
edit: updated script with various fixes and performance improvements
Created on Feb 27, 2017 5:01:59 PM
Last change on Dec 4, 2017 3:11:33 PM by
Dariusz Gorka [Paessler Support]
Votes:
0
Hi Kevin,
I published the script, thank you for your contribution. :)
Best regards.
Votes:
0
Hi Kevin,
Thx for the new version. Now it works with the placeholder *. Great Job
Votes:
0
Hello,
Currently the script sets the sensor to a warning (yellow) state if it detects a stopped service. We'd like to change this to show as down (red) if any service is detected. How can I do this? In the sensor itself, I see that "Limits" is currently disabled, but we get the yellow warnings if a service is down, so I'm thinking the setting for this is somewhere else?
Votes:
0
Hi there,
What exact message is displayed in the sensor message when a stopped service is detected? Is it "Automatic services not running:" or is it "Grace period remaining:""?
Best regards.
Votes:
0
Hello,
It says: "Automatic services not running: "
Votes:
0
Hi Manny,
Just for clarification, do you use Stephan's or Kevin's script?
Best regards.
Votes:
0
If that is the exact text I would hazard a guess it's my version as the original errors with "service(s)".
Manny, you can troubleshoot the script by manually calling it using the switches (i.e. -ComputerName, -UserName, -Password ) or setting the environment variables (i.e. $env:prtg_host = "<target-fqdn>" etc) and then either setting breakpoints if you're using the PowerShell ISE, or just inspecting the contents of the variables after the script has run.
That said I currently have this version on all of my 726 probes and none are reporting a blank service failing (although I do have 19 failing that I should probably look at, haha). Is it possible you have a service with either no name or perhaps some weird characters in the name that could be causing it to trip up?
You might also want to see what kind of results you get back from a call like (run directly on the target machine):
Get-WmiObject Win32_Service | Where {$_.StartMode -eq 'Auto' -and $_.State -ne 'Running'} | select *
The script uses the DisplayName property, so if you have one that is blank that would probably be your culprit.
Hope this helps :)
Votes:
0
Hi Kevin,
Thank you for jumping in, let's wait for an answer. :)
Best regards.
Votes:
0
Hi All! Thanks for your responses and sorry my delayed response.
Looks like I'm using Stephan's code. I actually just want to make the notifications turn Red instead of Yellow. For example, if any service is an a stopped state, then the sensor should be set to a down state (Red). Is this possible?
Thanks!!
Votes:
0
Hi Manny,
Okay, good to know. :)
To change the state, simply edit the script and change line 53 from:
exit 1 |
to:
exit 2 |
This is also described in the webinterface under "Setup > PRTG API" under "Custom Sensors".
Best regards.
Votes:
0
Hello, I've setup a couple new Windows 2016 servers that are not part of the domain and getting the following error:
Response not well-formed: "(Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:\Program Files (x86)\PRTG Network Monitor\custom sensors\EXE\Check_Windows_Auto_Services - Non-Domain.ps1:43 char:20 + Catch{ $Services = Get-WmiObject Win32_Service -ComputerName $ComputerName | Whe ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedA ccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.Pow erShell.Commands.GetWmiObjectCommand )" (code: PE132). It appears that you are experiencing some difficulties with WMI or related areas.
WMI tester works fine from the PRTG server to the target server. The account I'm using for authentication is a local administrator on the non-domain server. I've tried everything in these links:
https://kb.paessler.com/en/topic/60153-what-should-i-do-in-case-of-wmi-errors https://kb.paessler.com/en/topic/1073-what-are-the-most-common-errors-when-monitoring-wmi https://kb.paessler.com/en/topic/203-how-can-i-monitor-wmi-sensors-if-the-target-machine-is-not-part-of-a-domain
No luck :-(
Created on Jun 11, 2019 6:10:42 PM
Last change on Jun 12, 2019 5:24:01 AM by
Dariusz Gorka [Paessler Support]
Votes:
0
One more question. Is there a way to encrypt or hide the credentials that are saved in the PowerShell file? As it is now, anyone with access to the server can open the file and see the credentials in plain text.
Votes:
0
Hi there,
Access Denied simply means that either the user does not have enough rights or does not exist. Please test it with a Domain Administrator instead, does that work?
Also there is no way to hide the credentials in the current state the script is in. You would need to store them somewhere encrypted and read them on the run.
Best regards.
Votes:
0
Hi Dariusz,
I could not use a domain administrator account since the target server is not part of the domain. I did find a fix though. I had to create a registry entry. Here's what i did:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System |
Create a DWORD value called LocalAccountTokenFilterPolicy and assign it a value of 1
Then rebooted the server. That fixed the issue.
As for the credentials... that's unfortunate. I was hoping there was different option. Anyways, thanks for your response.
-Manny
Created on Jun 12, 2019 5:18:17 PM
Last change on Jun 13, 2019 8:13:04 AM by
Dariusz Gorka [Paessler Support]
Votes:
0
Hello,
i try your script, but it doesn't work in current version of PRTG. Is there an updated version of the script?
Votes:
0
Hi there,
A few more information about "does not work" would be beneficial. :)
Do you get an error message after adding the script? If so, please activate the logs within the sensor settings and check the logs saved on the probe under "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)\".
Best regards.
Votes:
0
Hi,
got the error message "Antwort ist nicht wohlgeformt "(<prtg<result><channel> ...") <Code PE132>
Votes:
0
Hi there,
Please make sure that the script is added to the "EXEXML" directory in PRTG's file directory and that you add a EXE Script Advanced Sensor, not a regular one. Is that the case?
Best regards.
Votes:
0
Hi Team,
I want to use this Automatic Services Powershell script with all computers in my domain. If have specified name "server1" in the sensor parameters and %host in the PowerShell script but its not working. Kindly assist.
Votes:
0
One more question can we execute the script on multiple servers without supplying credentials in PowerShell script?
Votes:
0
Hi,
You need to enter the credentials into the script. Furthermore, are your receiving any error message, when you try to create the sensor?
Votes:
0
How do I configure PRTG so that I receive an email notification for every Windows Service change? It seems to only notify only when it is Up or Down. If, for example, I have 3 Automatic Services down, I get an email notification. If one of those services gets started, I don't receive any new notification--which I would like...OR---if a 4th service was stopped, I'd also like to get a new notification email. Thanks!
Votes:
0
Hi there,
as you already mentioned the you can only set a trigger for the while Sensor status. If you want to have more detailed notification trigger, you can choose the "Threshold Trigger" which is able to trigger if a certain channel has a certain value. If this is also not possible, it's not possible to notify you for each service with this Sensor.
Add comment