Powershell to monitor all Windows Services set to "Automatic".

Hi, I'm posting this as is. Maybe it'll help someone else out. We were looking for a way to monitor many window services at once, but not all services. Trying to set up one service monitor at a time was going to be prohibitive. We hit on using a powershell script and to monitor anything set to Automatic. We included an "ignore list" where we could add services that are not always running so they don't generate false positives. Took about two weeks to build out our list. YMMV. We used the Services' Display Name as the value to use in the ignore list but you could change that.

 

PowerShell Active Monitor

Name: Windows Services Monitor

Description: PowerShell monitor - This monitors Windows Server Services that are set to Automatic. If the service is set to Automatic and is not running an alert will be generated.

Timeout: 60 Seconds

Script Text:

 

  1. # WhatsUp Gold Active Script Monitor (PowerShell)
  2.  
  3. # Windows Services: Automatic but Not Running (WMI)
  4.  
  5. # Includes an ignore list by DisplayName (exact match)
  6.  
  7.  
  8. $rc = 0
  9.  
  10. $msg = ""
  11.  
  12.  
  13. try {
  14.  
  15. $addr = [string]$Context.GetProperty("Address")
  16.  
  17. $user = [string]$Context.GetProperty("CredWindows:DomainAndUserid")
  18.  
  19. $pass = [string]$Context.GetProperty("CredWindows:Password")
  20.  
  21.  
  22. if ([string]::IsNullOrEmpty($user) -or [string]::IsNullOrEmpty($pass)) {
  23.  
  24. throw "Missing Windows credential (CredWindows) on this device."
  25.  
  26. }
  27.  
  28.  
  29. $sec = ConvertTo-SecureString $pass -AsPlainText -Force
  30.  
  31. $cred = New-Object System.Management.Automation.PSCredential($user, $sec)
  32.  
  33.  
  34. # Pull services that should be running (Automatic) but are not
  35.  
  36. $svc = Get-WmiObject -Class Win32_Service -ComputerName $addr -Credential $cred -Filter "StartMode='Auto' AND State<>'Running'"
  37.  
  38.  
  39. # -----------------------------
  40.  
  41. # IGNORE LIST (DisplayName)
  42.  
  43. # -----------------------------
  44.  
  45. $ignore = @(
  46.  
  47. "Microsoft Edge Update Service (edgeupdate)",
  48.  
  49. "AppX Deployment Service (AppXSVC)",
  50.  
  51. "Background Intelligent Transfer Service",
  52.  
  53. "Connected Devices Platform Service",
  54.  
  55. "Downloaded Maps Manager",
  56.  
  57. "Delivery Optimization",
  58.  
  59. "Device Management Wireless Application Protocol (WAP) Push message Routing Service",
  60.  
  61. "Google Updater Internal Service (GoogleUpdaterInternalService147.0.7703.0)",
  62.  
  63. "Google Updater Service (GoogleUpdaterService147.0.7703.0)",
  64.  
  65. "Google Updater Internal Service (GoogleUpdaterInternalService148.0.7730.0)",
  66.  
  67. "Google Updater Service (GoogleUpdaterService148.0.7730.0)",
  68.  
  69. "Group Policy Client",
  70.  
  71. "MDM Integration Service",
  72.  
  73. "Windows Biometric Service",
  74.  
  75. "Remote Registry",
  76.  
  77. "SharePoint Migration Service",
  78.  
  79. "Software Protection",
  80.  
  81. "SysMain",
  82.  
  83. "Volume Shadow Copy",
  84.  
  85. "wuauserv",
  86.  
  87. "Windows Modules Installer",
  88.  
  89. "Windows Time",
  90.  
  91. "Windows Update"
  92.  
  93. )
  94.  
  95.  
  96. # Remove ignored services
  97.  
  98. $svc = $svc | Where-Object { $ignore -notcontains $_.DisplayName }
  99.  
  100.  
  101. # If anything remains, alert DOWN and list them
  102.  
  103. if ($svc) {
  104.  
  105. $rc = 1
  106.  
  107. $lines = @()
  108.  
  109. foreach ($s in $svc) {
  110.  
  111. $lines += ($s.DisplayName + " [" + $s.Name + "] State=" + $s.State)
  112.  
  113. }
  114.  
  115. $msg = "Automatic services NOT running on " + $addr + ":`r`n" + ($lines -join "`r`n")
  116.  
  117. }
  118.  
  119. else {
  120.  
  121. $msg = "OK - All Automatic services are running (after ignore list) on " + $addr + "."
  122.  
  123. }
  124.  
  125. }
  126.  
  127. catch {
  128.  
  129. $rc = 1
  130.  
  131. $msg = "Script error: " + $_.Exception.Message
  132.  
  133. }
  134.  
  135.  
  136. $Context.SetResult($rc, $msg)

 


Nichol Goldstein likes this.
  • Davey Flavin (Progress Software)

    @Shawn Samuels (Customer)​ 

     

    Thank you very much for sharing this - I'm sure someone will get use out of this.

     

    Just so you are aware, it is possible to bulk create service monitors as part of the creation process - We have a multi selection for this exact scenario

     

    image 

    imageLet me know if you have any questions on this and if I can help further

  • Mike Rockwell (Progress Software)

    I edited your post to use the script block function to make your code easier to read and copy.