What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

auto starting Services

Votes:

0

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.

services-status startup-type windows-services

Created on Jan 15, 2016 8:39:54 AM



4 Replies

Accepted Answer

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.

Created on Jan 15, 2016 1:33:05 PM by  Stephan Linke [Paessler Support]



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"

Created on Mar 3, 2018 6:44:16 PM



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

Created on Mar 5, 2018 7:21:44 AM by  Sebastian Kniege [Paessler Support]



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]




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.