############################################################### # # Scriptname: PRTGCustomCitrixADMEvents.ps1 # # Autor: Urs Heeb # Date: 26.09.2022 # # Version: 2022.09.01 / 26.09.22 / Urs Heeb # Create script # 2022.09.02 / 28.09.22 / Urs Heeb # Little corrections (misspellings) # Modified connection string after rebuild PS module # Create PRTG output # 2022.09.03 / 29.09.22 / Urs Heeb # Filter out known entities from PRTG output # 2022.10.01 / 06.10.22 / Urs Heeb # Filter out known entities from PRTG output # 2022.10.02 / 07.10.22 / Urs Heeb # Reduce PRTG severity output for DOWN services # 2022.11.01 / 14.11.22 / Urs Heeb # Filter out known failure objects and messages from PRTG output # # Description: Script does following: # Connects to a Citrix ADM # Gets the information of all active events # Filters out the cleared events # # Requirements: # PRTG variables are needed while configuration # FQDN of the ADM %windowsdomain %windowsuser %windowspassword # PRTG service user needs read permission on Citrix ADM # PRTGCustomCitrixADM.psm1 module is needed in the same # PRTG custom sensor folder as this script # ############################################################### ### # Get parameter from PRTG param ( [string]$server, [string]$domain, [string]$username, [string]$password ) # For troubleshooting <# $server="adm.domain.pit" $username="username" $password="password" $CustomSensors="\\domain.pit\development\PRTG Custom sensors" #> # Import ADM PS module $CustomSensors="C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML\" Import-Module $CustomSensors\PRTGCustomCitrixADM.psm1 # Create the ADM session $ADMHost = "https://"+$server $ADMSession = Connect-ADM -ADMHost $ADMHost -CredUser $username -CredPW $password # Prepare the output variables $ActiveEvents = $null $ActiveEvents2 = $null # Get the events from the ADM $ActiveEvents = Invoke-ADMNitro -ADMSession $ADMSession -OperationMethod GET -ResourceType active_event # Create the variable only with the active events content $ActiveEvents2 = $ActiveEvents | Select-Object active_event #$ActiveEvents2.active_event | FT category, severity -AutoSize # Prepare the PRTG output $returnState=$null $returnState=@() $returnStateOK = 0 $returnStateWarning = 1 $returnStateCritical = 2 $RetCritical = $null $RetMajor = $null $RetMinor = $null $RetWarning = $null $RetClear = $null $RetInformational = $null $WarningString = "Warning - some entities needs attention" $WarningLevel = "0.9" $AlertString = "ALERT - ADM needs attention!" $AlertLevel = "0.9" # Prepare a device_entity_name exlusion list for PRTG outputs # Add each device in quota with a comma (except the last line) $DeviceExcludeList = $null $DeviceExcludeList = @( "entity1", "entity.domain.pit" ) # Prepare a failureobj exlusion list for PRTG outputs # Add each failure object in quota with a comma (except the last line) $FailureObjectExcludeList = $null $FailureObjectExcludeList = @( "object1", "object2" ) # Prepare a message exlusion list for PRTG outputs # Add each message in quota with a comma (except the last line) $MessageExcludeList = $null $MessageExcludeList = @( "192.168.99.99" ) $Events = $null $Events = @() ForEach ($Event in $ActiveEvents2.active_event){ If ($Event.severity -eq "Critical"){ # Filter out 'entityup' messages from critical state If ($Event.category -ne "entityup"){ $RetState = $returnStateCritical $Events += [PSCustomObject]@{Severity=$Event.severity;SourceIP=$Event.source;SourceHost=$Event.hostname;Category=$Event.category;Entity=$Event.device_entity_name;State=[Int64]$RetState} $RetCritical = $RetCritical + 1 } } ElseIf ($Event.severity -eq "Major"){ # For Troubleshooting #Write-Host $Event.severity " - " $Event.category " - " $Event.device_entity_name # Filter out known entities, failure objects etc. from major state # Set variable $DeviceAlarm, if the device isn't filtered $DeviceAlarm = $null ForEach ($ExcludedDevice in $DeviceExcludeList) { $Entity = $Event.device_entity_name If ($DeviceAlarm -or ($DeviceAlarm -eq $null)) { If ($Entity -notlike "*$ExcludedDevice*") { $DeviceAlarm = $true } Else{ $DeviceAlarm = $false } } } If ($DeviceAlarm){ ForEach ($ExcludedFO in $FailureObjectExcludeList) { $Entity = $Event.failureobj If ($DeviceAlarm -or ($DeviceAlarm -eq $null)) { If ($Entity -notlike "*$ExcludedFO*") { $DeviceAlarm = $true } Else{ $DeviceAlarm = $false } } } } If ($DeviceAlarm){ ForEach ($ExcludedMessage in $MessageExcludeList) { $Entity = $Event.message If ($DeviceAlarm -or ($DeviceAlarm -eq $null)) { If ($Entity -notlike "*$ExcludedMessage*") { $DeviceAlarm = $true } Else{ $DeviceAlarm = $false } } } } # If device isn't excluded, add to monitoring array # Services (svc) or service groups (svg) returns a warning instead an alarm If ($DeviceAlarm){ If (($Event.device_entity_name -like "*svc*") -or ($Event.device_entity_name -like "*svg*")) { $RetState = $returnStateWarning $Events += [PSCustomObject]@{Severity=$Event.severity;SourceIP=$Event.source;SourceHost=$Event.hostname;Category=$Event.category;Entity=$Event.device_entity_name;State=[Int64]$RetState} $RetWarning = $RetWarning + 1 } Else { $RetState = $returnStateCritical $Events += [PSCustomObject]@{Severity=$Event.severity;SourceIP=$Event.source;SourceHost=$Event.hostname;Category=$Event.category;Entity=$Event.device_entity_name;State=[Int64]$RetState} $RetMajor = $RetMajor + 1 } } } ElseIf ($Event.severity -eq "Minor"){ $RetState = $returnStateCritical $Events += [PSCustomObject]@{Severity=$Event.severity;SourceIP=$Event.source;SourceHost=$Event.hostname;Category=$Event.category;Entity=$Event.device_entity_name;State=[Int64]$RetState} $RetMinor = $RetMinor + 1 } ElseIf ($Event.severity -eq "Warning"){ $RetState = $returnStateWarning $Events += [PSCustomObject]@{Severity=$Event.severity;SourceIP=$Event.source;SourceHost=$Event.hostname;Category=$Event.category;Entity=$Event.device_entity_name;State=[Int64]$RetState} $RetWarning = $RetWarning + 1 } ElseIf ($Event.severity -eq "Clear"){ $RetClear = $RetClear + 1 } ElseIf ($Event.severity -eq "Informational"){ $RetInformational = $RetInformational + 1 } } # For troubleshooting #$Events | FT -AutoSize # Determine return string depends on the several states If ($Events.State -contains 2) { $RetString = $AlertString } ElseIf ($Events.State -contains 1) { $RetString = $WarningString } Else { $RetString = "OK" } # For troubleshooting #$RetString # Start preparing XML output $retXml = "`n" $retXml += " `n" $retXml += " Critical events`n" $retXml += " $RetCritical`n" $retXml += " Count`n" $retXml += " 1`n" $retXml += " $AlertLevel`n" $retXml += " $AlertString`n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " Major events`n" $retXml += " $RetMajor`n" $retXml += " Count`n" $retXml += " 1`n" $retXml += " $AlertLevel`n" $retXml += " $AlertString`n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " Minor events`n" $retXml += " $RetMinor`n" $retXml += " Count`n" $retXml += " 1`n" $retXml += " $AlertLevel`n" $retXml += " $AlertString`n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " `n" $retXml += " Warning events`n" $retXml += " $RetWarning`n" $retXml += " Count`n" $retXml += " 1`n" $retXml += " `n" $retXml += " `n" $retXml += " $WarningLevel`n" $retXml += " $WarningString`n" $retXml += " `n" $retXml += " `n" $retXml += " Cleared events`n" $retXml += " $RetClear`n" $retXml += " Count`n" $retXml += " 0`n" $retXml += " `n" $retXml += " `n" $retXml += " Information events`n" $retXml += " $RetInformational`n" $retXml += " Count`n" $retXml += " 0`n" $retXml += " `n" $retXml += " $RetString`n" $retXml += "`n" ### # Return info to PRTG write-host $retXml