How would I be able to monitor services status whose startup Type is "Automatic" with one sensor which only indicates if the condition is OK or not. Ideally, if the sensor could write down the service name in the error.
auto starting Services
Votes:
0
4 Replies
Votes:
0
There you go:
#=========================== # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | || (_ | #|_| |_|_\ |_| \___| # 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" # ------------------ # (c) 2014 Stephan Linke | Paessler AG param( [string]$ComputerName = "", [string]$IgnoreList = "Dell Digital Delivery Service,Gruppenrichtlinienclient,Remoteregistrierung,Software Protection", [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 it has been tested within a domain. Non-domain computers might not work. Also make sure that basic WMI access is working fine (i.e. other WMI sensors work on the device.
Votes:
1
I've got a slightly different script to achieve a similar thing, though it's more versatile (allows monitoring of all services, not just automatically started ones, plus it deals appropriately with "triggered" services)
Param ( [Parameter (Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [string] $ComputerName, [string[]]$Filter, [bool]$IncludeAll = $false, [string[]]$Exclude ) # Start with an empty service list $svc = $null # If no service filter has been provided, default to all services if ($Filter -eq $null) { # Are we supposed to include all services? if ($IncludeAll -eq $false) { # Yes - grab all services with the type "Automatic" $svc = Get-Service -ComputerName $ComputerName | Where-Object { $_.StartType -eq 'Automatic' } } else { # No - just grab all services $svc = Get-Service -ComputerName $ComputerName } } else { # Service filter has been provided - are we looking for all services, or just Automatically started ones? if ($IncludeAll -eq $false) { # Just automatic ones - loop through each filter provided and return all services that match each filter foreach ($f in $Filter) { $svc += Get-Service -ComputerName $ComputerName | Where-Object { ($_.Name -match $f) -and ($_.StartType -eq 'Automatic') } } } if ($IncludeAll -eq $true) { # All services - loop through each filter provided and return all services that match each filter foreach ($f in $Filter) { $svc += Get-Service -ComputerName $ComputerName | Where-Object { ($_.Name -match $f) } } } } # Make sure there are no duplicate services returned. Sort the list of services by the display name. $svc = $svc | Select-Object -Unique | Sort-Object -Property DisplayName # Loop through each exclusion provided and remove the service if it's found. foreach ($e in $Exclude) { $svc = $svc | Where-Object { $_.Name -ne $e } } $down = @() $warning = @() #Start output for PRTG Write-Host '<prtg>' foreach ($s in $svc) { Write-Host '<result>' Write-Host "<channel>$($s.DisplayName)</channel>" # Enumerate the service status to a value that can be looked up by PRTG. switch ($s.Status) { 'Stopped' { $status = 0 } 'Running' { $status = 1 } 'Paused' { $status = 2 } 'StopPending' { $status = 11 } 'StartPending' { $status = 12 } 'PausePending' { $status = 21 } 'ContinuePending' { $status = 22 } default { $status = 99 } } Write-Host "<value>$status</value>" # switch ($s.StartType) { 'Automatic' { # Try to determine if this is a triggered service or not $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName) $key = $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\$($s.Name)\\TriggerInfo") if ($key -eq $null) { # Service has no triggers - value should be looked up by PRTG with appropriate states for an automatically started service Write-Host '<ValueLookup>windows.service.automatic</ValueLookup>' # Note if the service is anything other than "Running" for later report to PRTG if ($s.Status -eq 'Stopped') { $down += "$($s.DisplayName) ($($s.Name))" } elseif ($s.Status -ne 'Running') { $warning += "$($s.DisplayName) ($($s.Name))" } } else { # Service has triggers - value should be looked up by PRTG with appropriate states the same as for manually started service Write-Host '<ValueLookup>windows.service.manual</ValueLookup>' } } 'Manual' { # Service is manually started - value should be loked up by PRTG with appropriate states Write-Host '<ValueLookup>windows.service.manual</ValueLookup>' } 'Disabled' { # Service is disabled - value should be loked up by PRTG with appropriate states Write-Host '<ValueLookup>windows.service.disabled</ValueLookup>' } } Write-Host '</result>' } if ($down.Count -gt 0) { # Some services are down - update the message that will be displayed to the user in PRTG to make it easier to find failed services Write-Host "<text>The following services are down: $(($down) -join ',')</text>" } else { # All services OK. Set the message to be displayed to the end user in PRTG appropriately Write-Host '<text>All selected services are in an appropriate state</text>' } Write-Host '</prtg>'
For this, you'll also need to add the following three files to $PRTG\lookups\custom.
windows.service.automatic.ovl
<?xml version="1.0" encoding="UTF-8"?> <ValueLookup id="windows.service.automatic" desiredValue="1" undefinedState="Error" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd"> <Lookups> <SingleInt state="Error" value="0">Stopped</SingleInt> <SingleInt state="Ok" value="1">Running</SingleInt> <SingleInt state="Warning" value="2">Paused</SingleInt> <SingleInt state="Warning" value="11">Stop Pending</SingleInt> <SingleInt state="Warning" value="12">Start Pending</SingleInt> <SingleInt state="Warning" value="21">Pause Pending</SingleInt> <SingleInt state="Warning" value="22">Continue Pending</SingleInt> <SingleInt state="Error" value="99">Unknown Status</SingleInt> </Lookups> </ValueLookup>
windows.service.manual.ovl
<?xml version="1.0" encoding="UTF-8"?>
<ValueLookup id="windows.service.manual" desiredValue="1" undefinedState="Error" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
<Lookups>
<SingleInt state="Ok" value="0">Stopped</SingleInt>
<SingleInt state="Ok" value="1">Running</SingleInt>
<SingleInt state="Ok" value="2">Paused</SingleInt>
<SingleInt state="Ok" value="11">Stop Pending</SingleInt>
<SingleInt state="Ok" value="12">Start Pending</SingleInt>
<SingleInt state="Ok" value="21">Pause Pending</SingleInt>
<SingleInt state="Ok" value="22">Continue Pending</SingleInt>
<SingleInt state="Error" value="99">Unknown Status</SingleInt>
</Lookups>
</ValueLookup>
windows.service.disabled.ovl
<?xml version="1.0" encoding="UTF-8"?> <ValueLookup id="windows.service.disabled" desiredValue="1" undefinedState="Error" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd"> <Lookups> <SingleInt state="Ok" value="0">Stopped</SingleInt> <SingleInt state="Error" value="1">Running</SingleInt> <SingleInt state="Error" value="2">Paused</SingleInt> <SingleInt state="Warning" value="11">Stop Pending</SingleInt> <SingleInt state="Error" value="12">Start Pending</SingleInt> <SingleInt state="Error" value="21">Pause Pending</SingleInt> <SingleInt state="Error" value="22">Continue Pending</SingleInt> <SingleInt state="Error" value="99">Unknown Status</SingleInt> </Lookups> </ValueLookup>
This will return one channel for each service that displays an appropriate status with errors and warnings being set appropriately for each type of service. Note that this script doesn't include any credentials - it is expected that either the PRTG probe service is running as an appropriate user or that you select "Use Windows credentials of parent device"
Votes:
0
Hello rhil_au,
Thank you very much for your valuable reply. I am pretty sure that other users will benefit of it, thanks!
Best regards,
Sebastian
Votes:
1
Hi I optimized the PRTG Script to start the Service if its possible, then check again and if its still not up then do an error.
Output is for PRTG EXEXML Sensor
Just put n the parameter field of the sensor sth like:
-ComputerName TS01 -Username "domäne\administrator" -Password "*******" -IgnoreList "KDService,DELL"
#=========================== # ___ ___ _____ ___ #| _ \ _ \_ _/ __| #| _/ / | || (_ | #|_| |_|_\ |_| \___| # 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" # # ------------------ # (c) 2014 Stephan Linke | Paessler AG # (c) 2018 modified Jasper Golze | ITcares # Mod: # - PRTG XML output # - try first to start Service, wait, check again param( [string]$ComputerName = "", [string]$IgnoreList = "", [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,Manager für heruntergeladene Karten,Software Protection,Windows-Biometriedienst' $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'} } # Try to start Stopped Services foreach ($service in $Services) { try { $returninfo = $service.StartService(); Start-Sleep -s 10 } catch { write-host "Servicestart fehlgeschlagen" } } # Check again if there are still not running services # Get list again 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'} } write-host "<?xml version="1.0" encoding="UTF-8"?> <prtg>" if($Services){ $ServiceList = ($Services | Select -expand DisplayName) -join ", " if(!$Services.Count){ Write-Host "<result><channel>Fehlerhafte Dienste</channel><value>1</value></result><error>1</error><text>1:Automatic service(s) not running: "$ServiceList"</text></prtg>" exit 1 } else{ Write-Host "<result><channel>Fehlerhafte Dienste</channel><value>"$Services.Count"</value></result><error>1</error><text>"$Services.Count":Automatic service(s) not running: "$ServiceList"</text></prtg>" exit 1 } } else{ Write-Host "<result><channel>Fehlerhafte Dienste</channel><value>0</value></result><text>0:All automatic services are running.</text></prtg>" exit 0 } #===========================
Created on Sep 10, 2018 5:19:55 PM
Last change on Sep 11, 2018 4:28:27 AM by
Sven Roggenhofer [Paessler Technical Support]
Add comment