├── check_ms_iis_application_pool.ps1 └── readme.md /check_ms_iis_application_pool.ps1: -------------------------------------------------------------------------------- 1 | # Script name: check_ms_iis_application_pool.ps1 2 | # Version: v1.06.180411 3 | # Created on: 10/03/2016 4 | # Author: Willem D'Haese 5 | # Purpose: Checks Microsoft Windows IIS application pool cpu and memory usage 6 | # On Github: https://github.com/willemdh/check_ms_iis_application_pool 7 | # On OutsideIT: https://outsideit.net/monitoring-iis-application-pools 8 | # Recent History: 9 | # 27/01/17 => AppCmd method as workaround for hanging gci 10 | # 28/01/16 => appcount to the back 11 | # 18/02/17 => Cleanup and PSSharpening 12 | # 15/09/17 => Fixed perfdata not working in some cases (Yannick Charton) 13 | # 22/09/17 => Fixed bug with multiple w3wp processes 14 | # 11/04/18 => Fixed bug with multiple w3wp processes, cpu and memory parts and added warn/crit to perfdata (Yannick Charton) 15 | # Copyright: 16 | # This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published 17 | # by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed 18 | # in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 19 | # PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public 20 | # License along with this program. If not, see . 21 | 22 | #Requires -Version 2.0 23 | 24 | $DebugPreference = 'SilentlyContinue' 25 | $VerbosePreference = 'SilentlyContinue' 26 | #$DebugPreference = 'Continue' 27 | #$VerbosePreference = 'Continue' 28 | 29 | $IISStruct = New-Object -TypeName PSObject -Property @{ 30 | StopWatch = [Diagnostics.Stopwatch]::StartNew() 31 | ApplicationPool = '' 32 | ProcessId = '' 33 | Process = '' 34 | PoolCount = '' 35 | PoolState = '' 36 | SitesCount = '' 37 | WarningMemory = '' 38 | CriticalMemory = '' 39 | WarningCpu = '' 40 | CriticalCpu = '' 41 | CurrentMemory = '' 42 | CurrentCpu = '' 43 | Duration = '' 44 | Exitcode = 3 45 | AppPoolOnDemand = 0 46 | AppCmd = 0 47 | AppCmdList = '' 48 | ReturnString = 'UNKNOWN: Please debug the script...' 49 | } 50 | 51 | #region Functions 52 | 53 | Function Write-Log { 54 | Param ( 55 | [parameter(Mandatory=$true)][string]$Log, 56 | [parameter(Mandatory=$true)][ValidateSet('Debug', 'Info', 'Warning', 'Error', 'Unknown')][string]$Severity, 57 | [parameter(Mandatory=$true)][string]$Message 58 | ) 59 | $Now = Get-Date -Format 'yyyy-MM-dd HH:mm:ss,fff' 60 | $LocalScriptName = Split-Path -Path $myInvocation.ScriptName -Leaf 61 | If ( $Log -eq 'Undefined' ) { 62 | Write-Debug -Message "${Now}: ${LocalScriptName}: Info: LogServer is undefined." 63 | } 64 | ElseIf ( $Log -eq 'Verbose' ) { 65 | Write-Verbose -Message "${Now}: ${LocalScriptName}: ${Severity}: $Message" 66 | } 67 | ElseIf ( $Log -eq 'Debug' ) { 68 | Write-Debug -Message "${Now}: ${LocalScriptName}: ${Severity}: $Message" 69 | } 70 | ElseIf ( $Log -eq 'Output' ) { 71 | Write-Host "${Now}: ${LocalScriptName}: ${Severity}: $Message" 72 | } 73 | ElseIf ( $Log -match '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])(?::(?\d+))$' -or $Log -match '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) { 74 | $IpOrHost = $log.Split(':')[0] 75 | $Port = $log.Split(':')[1] 76 | If ( $IpOrHost -match '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) { 77 | $Ip = $IpOrHost 78 | } 79 | Else { 80 | $Ip = [Net.Dns]::GetHostAddresses($IpOrHost)[0].IPAddressToString 81 | } 82 | Try { 83 | $LocalHostname = ([Net.Dns]::GetHostByName((hostname.exe)).HostName).tolower() 84 | $JsonObject = (New-Object -TypeName PSObject | 85 | Add-Member -PassThru NoteProperty logsource $LocalHostname | 86 | Add-Member -PassThru NoteProperty hostname $LocalHostname | 87 | Add-Member -PassThru NoteProperty scriptname $LocalScriptName | 88 | Add-Member -PassThru NoteProperty logtime $Now | 89 | Add-Member -PassThru NoteProperty severity_label $Severity | 90 | Add-Member -PassThru NoteProperty message $Message ) 91 | If ( $psversiontable.psversion.major -ge 3 ) { 92 | $JsonString = $JsonObject | ConvertTo-Json 93 | $JsonString = $JsonString -replace "`n",' ' -replace "`r",' ' 94 | } 95 | Else { 96 | $JsonString = $JsonObject | ConvertTo-Json2 97 | } 98 | $Socket = New-Object -TypeName System.Net.Sockets.TCPClient -ArgumentList ($Ip,$Port) 99 | $Stream = $Socket.GetStream() 100 | $Writer = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($Stream) 101 | $Writer.WriteLine($JsonString) 102 | $Writer.Flush() 103 | $Stream.Close() 104 | $Socket.Close() 105 | } 106 | Catch { 107 | Write-Host "${Now}: ${LocalScriptName}: Error: Something went wrong while trying to send message to logserver `"$Log`"." 108 | } 109 | Write-Verbose -Message "${Now}: ${LocalScriptName}: ${Severity}: Ip: $Ip Port: $Port JsonString: $JsonString" 110 | } 111 | ElseIf ($Log -match '^((([a-zA-Z]:)|(\\{2}\w+)|(\\{2}(?:(?:25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)(?(?=\.?\d)\.)){4}))(\\(\w[\w ]*))*)') { 112 | If (Test-Path -Path $Log -pathType container){ 113 | Write-Host "${Now}: ${LocalScriptName}: Error: Passed Path is a directory. Please provide a file." 114 | Exit 1 115 | } 116 | ElseIf (!(Test-Path -Path $Log)) { 117 | Try { 118 | $null = New-Item -Path $Log -Type file -Force 119 | } 120 | Catch { 121 | $Now = Get-Date -Format 'yyyy-MM-dd HH:mm:ss,fff' 122 | Write-Host "${Now}: ${LocalScriptName}: Error: Write-Log was unable to find or create the path `"$Log`". Please debug.." 123 | exit 1 124 | } 125 | } 126 | Try { 127 | "${Now}: ${LocalScriptName}: ${Severity}: $Message" | Out-File -filepath $Log -Append 128 | } 129 | Catch { 130 | Write-Host "${Now}: ${LocalScriptName}: Error: Something went wrong while writing to file `"$Log`". It might be locked." 131 | } 132 | } 133 | } 134 | 135 | Function ConvertTo-JSON2 { 136 | param ( 137 | $MaxDepth = 4, 138 | $ForceArray = $false 139 | ) 140 | Begin { 141 | $Data = @() 142 | } 143 | Process{ 144 | $Data += $_ 145 | } 146 | End{ 147 | If ($Data.length -eq 1 -and $ForceArray -eq $false) { 148 | $Value = $Data[0] 149 | } 150 | Else { 151 | $Value = $Data 152 | } 153 | If ($Value -eq $null) { 154 | Return 'null' 155 | } 156 | $DataType = $Value.GetType().Name 157 | Switch -Regex ($DataType) { 158 | 'String' { Return "`"{0}`"" -f (Format-JSONString $Value ) } 159 | '(System\.)?DateTime' { Return "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $Value } 160 | 'Int32|Double' { Return "$Value" } 161 | 'Boolean' { Return "$Value".ToLower() } 162 | '(System\.)?Object\[\]' { 163 | If ($MaxDepth -le 0) { 164 | Return "`"$value`"" 165 | } 166 | $JsonResult = '' 167 | ForEach ($Elem in $Value) { 168 | If ($JsonResult.Length -gt 0) { 169 | $JsonResult +=', ' 170 | } 171 | $JsonResult += ($Elem | ConvertTo-JSON -MaxDepth ($MaxDepth -1)) 172 | } 173 | Return '[' + $jsonResult + ']' 174 | } 175 | '(System\.)?Hashtable' { 176 | $JsonResult = '' 177 | ForEach ($Key in $Value.Keys) { 178 | If ($JsonResult.Length -gt 0) { 179 | $JsonResult +=', ' 180 | } 181 | $jsonResult += 182 | @' 183 | "{0}": {1} 184 | '@ -f $Key , ($Value[$Key] | ConvertTo-JSON2 -MaxDepth ($MaxDepth -1) ) 185 | } 186 | Return '{' + $jsonResult + '}' 187 | } 188 | default { 189 | If ($MaxDepth -le 0) { 190 | Return "`"{0}`"" -f (Format-JSONString $Value) 191 | } 192 | Return '{' +(($value | Get-Member -MemberType *property | ForEach-Object { 193 | @' 194 | "{0}": {1} 195 | '@ -f $_.Name , ($value.($_.Name) | ConvertTo-JSON2 -maxDepth ($maxDepth -1)) 196 | }) -join ', ') + '}' 197 | } 198 | } 199 | } 200 | } 201 | 202 | Function Initialize-Args { 203 | Param ( 204 | [Parameter(Mandatory=$true)]$Args 205 | ) 206 | try { 207 | For ( $i = 0; $i -lt $Args.count; $i++ ) { 208 | $CurrentArg = $Args[$i].ToString() 209 | if ($i -lt $Args.Count-1) { 210 | $Value = $Args[$i+1]; 211 | If ($Value.Count -ge 2) { 212 | foreach ($Item in $Value) { 213 | $null = Test-Strings -String $Item 214 | } 215 | } 216 | else { 217 | $Value = $Args[$i+1]; 218 | $null = Test-Strings -String $Value 219 | } 220 | } 221 | else { 222 | $Value = '' 223 | } 224 | switch -regex -casesensitive ($CurrentArg) { 225 | '^(-A|--ApplicationPool)$' { 226 | if ($value -match '^[a-zA-Z0-9. _-]+$') { 227 | $IISStruct.ApplicationPool = $Value 228 | } 229 | else { 230 | throw "Application Pool `"$value`" does not meet regex requirements." 231 | } 232 | $i++ 233 | } 234 | '^(-WM|--WarningMemory)$' { 235 | if ($value -match '^[0-9]{1,10}$') { 236 | $IISStruct.WarningMemory = $Value 237 | } 238 | else { 239 | throw "Method `"$value`" does not meet regex requirements." 240 | } 241 | $i++ 242 | } 243 | '^(-CM|--CriticalMemory)$' { 244 | if ($value -match '^[0-9]{1,10}$') { 245 | $IISStruct.CriticalMemory = $Value 246 | } 247 | else { 248 | throw "Method `"$value`" does not meet regex requirements." 249 | } 250 | $i++ 251 | } 252 | '^(-WC|--WarningCpu)$' { 253 | if ($value -match '^[0-9]{1,10}$') { 254 | $IISStruct.WarningCpu = $Value 255 | } 256 | else { 257 | throw "Method `"$value`" does not meet regex requirements." 258 | } 259 | $i++ 260 | } 261 | '^(-CC|--CriticalCpu)$' { 262 | if ($value -match '^[0-9]{1,10}$') { 263 | $IISStruct.CriticalCpu = $Value 264 | } 265 | else { 266 | throw "Method `"$value`" does not meet regex requirements." 267 | } 268 | $i++ 269 | } 270 | '^(-APOD|--AppPoolOnDemand)$' { 271 | if ($value -match '^[0-1]{1,2}$') { 272 | $IISStruct.AppPoolOnDemand = $Value 273 | } 274 | else { 275 | throw "Method `"$value`" does not meet regex requirements." 276 | } 277 | $i++ 278 | } 279 | '^(-Appcmd|-AppCmd|-appcmd|-APPCMD)$' { 280 | if ($value -match '^[0-1]{1,2}$') { 281 | $IISStruct.Appcmd = $Value 282 | } 283 | else { 284 | throw "Method `"$value`" does not meet regex requirements." 285 | } 286 | $i++ 287 | } 288 | '^(-h|--Help)$' { 289 | Write-Help 290 | } 291 | default { 292 | throw "Illegal arguments detected: $_" 293 | } 294 | } 295 | } 296 | } 297 | catch { 298 | Write-Host "CRITICAL: Argument: $CurrentArg Value: $Value Error: $_" 299 | Exit 2 300 | } 301 | } 302 | Function Test-Strings { 303 | Param ( [Parameter(Mandatory=$true)][string]$String ) 304 | $BadChars=@("``", '|', ';', "`n") 305 | $BadChars | ForEach-Object { 306 | If ( $String.Contains("$_") ) { 307 | Write-Host "Error: String `"$String`" contains illegal characters." 308 | Exit $IISStruct.ExitCode 309 | } 310 | } 311 | Return $true 312 | } 313 | 314 | Function Invoke-CheckIISApplicationPool { 315 | Try { 316 | Import-Module -Name WebAdministration 317 | If (Get-ChildItem -Path IIS:\AppPools | Where-Object {$_.Name -eq "$($IISStruct.ApplicationPool)"}) { 318 | $IISStruct.PoolState = Get-ChildItem -Path IIS:\AppPools | Where-Object {$_.Name -eq "$($IISStruct.ApplicationPool)"} | Select-Object -Property State -ExpandProperty State 319 | If ( $IISStruct.PoolState -eq 'Started') { 320 | $IISStruct.ProcessId = Get-WmiObject -NameSpace 'root\WebAdministration' -class 'WorkerProcess' | Where-Object {$_.AppPoolName -match $IISStruct.ApplicationPool} | Select-Object -Expand ProcessId 321 | If ( $IISStruct.ProcessId ) { 322 | If ( @($($IISStruct.ProcessId)) -gt 1 ) { 323 | $IISStruct.CurrentCpu = 0 324 | $IISStruct.CurrentMemory = 0 325 | Get-WmiObject -NameSpace 'root\WebAdministration' -class 'WorkerProcess' | Where-Object {$_.AppPoolName -match $IISStruct.ApplicationPool} | Select-Object -Expand ProcessId | ForEach-Object { 326 | $MyProcessId=$_ 327 | $IISStruct.Process = Get-Wmiobject -Class Win32_PerfFormattedData_PerfProc_Process | Where-Object { $_.IdProcess -eq $MyProcessId } 328 | $MyCurrentCpu = $IISStruct.Process.PercentProcessorTime 329 | $MyCurrentMemory = [Math]::Round(($IISStruct.Process.workingSetPrivate / 1MB),2) 330 | $IISStruct.CurrentCpu += $MyCurrentCpu 331 | $IISStruct.CurrentMemory += $MyCurrentMemory 332 | Write-Log Verbose Info "Application pool $($IISStruct.ApplicationPool) process id: $_ Percent CPU: $MyCurrentCpu Private Memory: $MyCurrentMemory" 333 | } 334 | } 335 | Else { 336 | $IISStruct.Process = Get-Wmiobject -Class Win32_PerfFormattedData_PerfProc_Process | Where-Object { $_.IdProcess -eq $IISStruct.ProcessId } 337 | $IISStruct.CurrentCpu = $IISStruct.Process.PercentProcessorTime 338 | $IISStruct.CurrentMemory = [Math]::Round(($IISStruct.Process.workingSetPrivate / 1MB),2) 339 | } 340 | Write-Log Verbose Info "Application pool $($IISStruct.ApplicationPool) process id(s): $($IISStruct.ProcessId) Percent CPU: $($IISStruct.CurrentCpu) Private Memory: $($IISStruct.CurrentMemory)" 341 | $Sites = Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool='$($IISStruct.ApplicationPool)' and @path='/']/parent::*" machine/webroot/apphost -name name 342 | $Apps = Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool='$($IISStruct.ApplicationPool)' and @path!='/']" machine/webroot/apphost -name path 343 | $IISStruct.SitesCount = ($Sites,$Apps | ForEach-Object {$_.value}).count 344 | $IISStruct.ExitCode = 0 345 | $IISStruct.ReturnString = "OK: Application Pool `"$($IISStruct.ApplicationPool)`" with $($IISStruct.SitesCount) Applications. {CPU: $($IISStruct.CurrentCpu) %}{Memory: $($IISStruct.CurrentMemory) MB}" 346 | $IISStruct.ReturnString += " | 'pool_cpu'=$($IISStruct.CurrentCpu)%;$($IISStruct.WarningCpu);$($IISStruct.CriticalCpu);0;100 'pool_memory'=$($IISStruct.CurrentMemory)MB;$($IISStruct.WarningMemory);$($IISStruct.CriticalMemory);0; 'app_count'=$($IISStruct.SitesCount)" 347 | } 348 | Else { 349 | If ( $IISStruct.AppPoolOnDemand = 1 ) { 350 | $IISStruct.Process = 0 351 | $IISStruct.CurrentCpu = 0 352 | $IISStruct.CurrentMemory = 0 353 | $Sites = 0 354 | $Apps = 0 355 | $IISStruct.SitesCount = 0 356 | $IISStruct.ExitCode = 0 357 | $IISStruct.ReturnString = "OK: Application Pool Started but no process is assigned yet `"$($IISStruct.ApplicationPool)`" with 0 Applications. {CPU: 0%}{Memory: 0MB}" 358 | $IISStruct.ReturnString += " | 'pool_cpu'=0%;$($IISStruct.WarningCpu);$($IISStruct.CriticalCpu);0;100 'pool_memory'=0MB;$($IISStruct.WarningMemory);$($IISStruct.CriticalMemory);0; 'app_count'=0" 359 | } 360 | Else { 361 | Throw "Application Pool `"$($IISStruct.ApplicationPool)`" not found in WMI." 362 | } 363 | } 364 | } 365 | Else { 366 | Throw "Application Pool `"$($IISStruct.ApplicationPool)`" is $($IISStruct.PoolState)." 367 | } 368 | } 369 | Else { 370 | Throw "Application Pool `"$($IISStruct.ApplicationPool)`" does not exist." 371 | } 372 | } 373 | Catch { 374 | $IISStruct.ExitCode = 2 375 | $IISStruct.ReturnString = "CRITICAL: $_" 376 | } 377 | } 378 | Function Invoke-CheckIISWithAppCmd { 379 | Try { 380 | [xml]$AppCmdXml = & "$env:windir\system32\inetsrv\appcmd.exe" list apppools /xml 381 | $IISStruct.PoolCount = $AppCmdXml.appcmd.APPPOOL.Count 382 | If ( ! $IISStruct.PoolCount ) { 383 | $IISStruct.PoolState = $AppCmdXml.appcmd.APPPOOL.'state' 384 | if ( $AppCmdXml.appcmd.APPPOOL.'APPPOOL.NAME' -eq $IISStruct.ApplicationPool ) { 385 | $Found = $True 386 | } 387 | Else { 388 | $IISStruct.ReturnString = "CRITICAL: NO IIS application pool with name $($IISStruct.ApplicationPool) found. " 389 | $IISStruct.ExitCode = 2 390 | } 391 | } 392 | Else { 393 | $Found = $False 394 | $i = 0 395 | while ( ! $found -and $i -lt $IISStruct.PoolCount ) { 396 | If ( $AppCmdXml.appcmd.APPPOOL[$i].'APPPOOL.NAME' -eq $IISStruct.ApplicationPool ) { 397 | Write-Log Verbose Info "Application pool found: $($IISStruct.ApplicationPool)" 398 | $IISStruct.PoolState = $AppCmdXml.appcmd.APPPOOL[$i].'state' 399 | $Found = $True 400 | } 401 | Write-Log Verbose Info "Pool: $($AppCmdXml.appcmd.APPPOOL[$i].'APPPOOL.NAME')" 402 | $i++ 403 | } 404 | } 405 | If ( $Found ) { 406 | If ( $IISStruct.PoolState -eq 'Started') { 407 | $IISStruct.ProcessId = Get-WmiObject -NameSpace 'root\WebAdministration' -class 'WorkerProcess' | Where-Object {$_.AppPoolName -match "^$($IISStruct.ApplicationPool)$"} | Select-Object -Expand ProcessId 408 | If ( $IISStruct.ProcessId ) { 409 | $IISStruct.Process = get-wmiobject Win32_PerfFormattedData_PerfProc_Process | Where-Object { $_.IdProcess -eq $IISStruct.ProcessId } 410 | $IISStruct.CurrentCpu = $IISStruct.Process.PercentProcessorTime 411 | Write-Log Verbose Info "Application pool $($IISStruct.ApplicationPool) process id: $($IISStruct.ProcessId) Percent CPU: $($IISStruct.CurrentCpu)" 412 | $IISStruct.CurrentMemory = [Math]::Round(($IISStruct.Process.workingSetPrivate / 1MB),2) 413 | Write-Log Verbose Info "Application pool $($IISStruct.ApplicationPool) process id: $($IISStruct.ProcessId) Private Memory: $($IISStruct.CurrentMemory)" 414 | $Sites = Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool='$($IISStruct.ApplicationPool)' and @path='/']/parent::*" machine/webroot/apphost -name name 415 | $Apps = Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[@applicationPool='$($IISStruct.ApplicationPool)' and @path!='/']" machine/webroot/apphost -name path 416 | $IISStruct.SitesCount = ($Sites,$Apps | ForEach-Object {$_.value}).count 417 | $IISStruct.ExitCode = 0 418 | $IISStruct.ReturnString = "OK: Application Pool `"$($IISStruct.ApplicationPool)`" with $($IISStruct.SitesCount) Applications. {CPU: $($IISStruct.CurrentCpu) %}{Memory: $($IISStruct.CurrentMemory) MB}" 419 | $IISStruct.ReturnString += " | 'pool_cpu'=$($IISStruct.CurrentCpu)%;$($IISStruct.WarningCpu);$($IISStruct.CriticalCpu);0;100 'pool_memory'=$($IISStruct.CurrentMemory)MB;$($IISStruct.WarningMemory);$($IISStruct.CriticalMemory);0; 'app_count'=$($IISStruct.SitesCount)" 420 | } 421 | Else { 422 | If ( $IISStruct.AppPoolOnDemand = 1 ) { 423 | $IISStruct.Process = 0 424 | $IISStruct.CurrentCpu = 0 425 | $IISStruct.CurrentMemory = 0 426 | $Sites = 0 427 | $Apps = 0 428 | $IISStruct.SitesCount = 0 429 | $IISStruct.ExitCode = 0 430 | $IISStruct.ReturnString = "OK: Application Pool Started but no process is assigned yet `"$($IISStruct.ApplicationPool)`" with 0 Applications. {CPU: 0%}{Memory: 0MB}" 431 | $IISStruct.ReturnString += " | 'pool_cpu'=0%;$($IISStruct.WarningCpu);$($IISStruct.CriticalCpu);0;100 'pool_memory'=0MB;$($IISStruct.WarningMemory);$($IISStruct.CriticalMemory);0; 'app_count'=0" 432 | } 433 | Else { 434 | Throw "Application Pool `"$($IISStruct.ApplicationPool)`" not found in WMI." 435 | } 436 | } 437 | } 438 | Else { 439 | Throw "Application Pool `"$($IISStruct.ApplicationPool)`" is $($IISStruct.PoolState)." 440 | } 441 | } 442 | Else { 443 | Throw "NO IIS application pool with name $($IISStruct.ApplicationPool) found. " 444 | } 445 | } 446 | Catch { 447 | $IISStruct.ExitCode = 2 448 | $IISStruct.ReturnString = "CRITICAL: $_" 449 | } 450 | } 451 | 452 | #endregion Functions 453 | 454 | #region Main 455 | 456 | If ( $Args ) { 457 | If ( ! ( $Args[0].ToString()).StartsWith('$') ) { 458 | If ( $Args.count -ge 1 ) { 459 | Initialize-Args $Args 460 | } 461 | } 462 | Else { 463 | $IISStruct.ReturnString = 'CRITICAL: Script needs mandatory parameters to work.' 464 | $IISStruct.ExitCode = 2 465 | } 466 | } 467 | If ( $IISStruct.AppCmd -eq 0 ) { 468 | Invoke-CheckIISApplicationPool 469 | } 470 | else { 471 | Invoke-CheckIISWithAppCmd 472 | } 473 | Write-Host $IISStruct.ReturnString 474 | Exit $IISStruct.ExitCode 475 | 476 | #endregion Main 477 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Nagios plugin to check Microsoft IIS application pool states 2 | 3 | ### Idea 4 | 5 | Checks Microsoft Windows IIS application pool state returning web application count, % CPU usage and memory usage. 6 | 7 | ### Screenshots 8 | 9 | ![IIS 01](/../screenshots/check-ms-iis-application-pool-outputs.png?raw=true "IIS Application Pool Outputs") 10 | 11 | ### Status 12 | 13 | In production. 14 | 15 | ### How To 16 | 17 | https://outsideit.net/monitoring-iis-application-pools/ 18 | 19 | ### Help 20 | 21 | In case you find a bug or have a feature request, please make an issue on GitHub. 22 | 23 | ### On Nagios Exchange 24 | 25 | https://exchange.nagios.org/directory/Plugins/Web-Servers/IIS/Check-Microsoft-IIS-Application-Pool/details 26 | 27 | ### Copyright 28 | 29 | This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public 30 | License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later 31 | version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the 32 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 33 | details at . 34 | --------------------------------------------------------------------------------