I know I can monitor SSL certificates with a preconfigured sensor in PRTG.
But how can I monitor an active digital CA windows certificate on the machine running the PRTG probe?
I know I can monitor SSL certificates with a preconfigured sensor in PRTG.
But how can I monitor an active digital CA windows certificate on the machine running the PRTG probe?
certificate custom-script-exe custom-sensor expiry powershell prtg ps1
Created on Jul 20, 2012 12:37:43 PM by
Daniel Zobel [Product Manager]
Last change on Mar 19, 2015 3:42:27 PM by
Martina Wittmann [Paessler Support]
9 Replies
This article applies to PRTG Network Monitor 12 or later
I found a way to monitor certification-expiry that should be useful for you.
Note: You will be able to monitor certificates on the machine running the PRTG Probe only; you cannot monitor certificates on remote machines with this!
Please copy&paste the following script in a file with the extension .ps1 and place it in the Custom Sensors\EXEXML sub directory of your PRTG program directory. In the PRTG web interface, add a new EXE/Script (Advanced) sensor using this script.
The sensor without any parameter returns the expiry time in days of any certificates installed on your probe computer. You can filter the stores by using the -store <your store name> parameter.
It will be usefull for us if you can give us some feedback if and how the sensor works.
# begin of script # Param( $store='all' ) # To get this script running with PRTGNetworkMonitor you need to enable RemoteSigned-scripting for 32bit-processes. # This can be done with running 'c:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe "Set-ExecutionPolicy RemoteSigned"' on a system with default paths # the logic behind this sensor is based on the basics from http://blogs.technet.com/b/heyscriptingguy/archive/2011/02/16/use-powershell-and-net-to-find-expired-certificates.aspx # Examples of Parameters-string in sensorsettings # -store AuthRoot # possible values see $stores-variable + 'all' or leave the field empty for default ('all') # !!! the storenames are casesensitiv !!! # declare script-wide variables $script:starttime = Get-Date $script:table = $null $script:resultText = "OK" $stores = @('AddressBook', 'AuthRoot', 'CertificateAuthority', 'My', 'Root', 'TrustedPeople', 'TrustedPublisher') function main { switch ($store) { 'all' { foreach($certStore in $stores){ $storeRef = New-Object System.Security.Cryptography.X509Certificates.X509Store($certStore,"LocalMachine") $storeRef.Open("ReadOnly") foreach($certificate in $storeRef.Certificates) { addCertificate -certificate $certificate -storename $storeRef.name } } } default { $storeRef = New-Object System.Security.Cryptography.X509Certificates.X509Store($store,"LocalMachine") $storeRef.Open("ReadOnly") foreach($certificate in $storeRef.Certificates) { addCertificate -certificate $certificate -storename $storeRef.name } } } # add the execution-time to channels $row = $table.NewRow(); $row.channel = "ExecutionTime"; $row.unit = "TimeSeconds"; $row.SpeedTime = "Second"; $row.float = "1"; $row.ShowChart = "0"; $row.ShowTable = "0"; $row.Value = "$([Math]::Round((new-timespan $starttime).totalseconds,1))"; $table.Rows.Add($row) # forward the generated table to xml-generator and store the result $retval = $table | New-Xml -RootTag prtg -ItemTag result -ChildItems Channel,Value,Unit,CustomUnit,Warning,Error,speedtime,volumesize,mode,showchart,showtable,float -ResultTag $resultText write-host $retval } function addCertificate { param($certificate, $storeName) $value = ($certificate.notAfter - ($script:starttime)).Days if (($script:store -eq 'all') -and ($storeName -ne '')) { $prefix = "$($storeName) - " } if ($value -ne '') { $row = $table.NewRow(); if ($certificate.friendlyName -ne '') { $row.channel = "$prefix$($certificate.friendlyName)"; } else { $row.channel = "$prefix$($certificate.GetName())"; } $row.value = $value $row.unit = "Custom" $row.customUnit = "Days" $table.Rows.Add($row) } } function prepareResultTable { # create a table to store the information only if not yet done # all available values predefined, in the result only the active values will apear if ($script:table -eq $null) { $script:table = New-Object system.Data.DataTable "result" $col1 = New-Object system.Data.DataColumn channel,string $col2 = New-Object system.Data.DataColumn value,string # a Integer or float value preconverted into a string! $col3 = New-Object system.Data.DataColumn unit,string # BytesBandwidth/BytesMemory/BytesDisk/Temperature/Percent/TimeResponse/TimeSeconds/Custom/Count/CPU (%)/BytesFile/SpeedDisk/SpeedNet/TimeHours $col4 = New-Object system.Data.DataColumn customUnit,string $col5 = New-Object system.Data.DataColumn warning,string # 0/1 (no/yes) 0 $col6 = New-Object system.Data.DataColumn SpeedSize,string # One/Kilo/Mega/Giga/Tera/Byte/KiloByte/MegaByte/GigaByte/TeraByte/Bit/KiloBit/MegaBit/GigaBit/TeraBit $col7 = New-Object system.Data.DataColumn VolumeSize,string # siehe Speedsize $col8 = New-Object system.Data.DataColumn SpeedTime,string # Second/Minute/Hour/Day $col9 = New-Object system.Data.DataColumn Mode,string # Absolute/Difference $col10 = New-Object system.Data.DataColumn ShowChart,string # 0/1 (no/yes) 1 $col11 = New-Object system.Data.DataColumn ShowTable,string # 0/1 (no/yes) 1 $col12 = New-Object system.Data.DataColumn Float,string # 0/1 (no integer/yes float) 0 $table.columns.add($($col1)) $table.columns.add($($col2)) $table.columns.add($($col3)) $table.columns.add($($col4)) $table.columns.add($($col5)) $table.columns.add($($col6)) $table.columns.add($($col7)) $table.columns.add($($col8)) $table.columns.add($($col9)) $table.columns.add($($col10)) $table.columns.add($($col11)) $table.columns.add($($col12)) } } # this function produces a well-formated xml-output out of a given table function New-Xml { param($RootTag="ROOT",$ItemTag="ITEM", $ChildItems="*", $resultTag, $Attributes=$Null) Begin { $xml = "<$RootTag>`n" } Process { $xml += " <$ItemTag>`n" foreach ($child in $_ | Get-Member -Type *Property $childItems) { $Name = $child.Name if ("$($_.$name)" -ne "") { $xml += " <$Name>$($_.$Name)</$Name>`n" } } $xml += " </$ItemTag>`n" } End { if ([string]$resultTag -ne $false) { $xml += " <text>$resultTag</text>`n" } $xml += "</$RootTag>`n" $xml } } # print a xml-errormessage function printErrorXml($errortext = $script:resultText) { $errorXml = "<prtg>`n" $errorXml += " <error>1</error>`n" $errorXml += " <text>$errortext</text>`n" $errorXml += "</prtg>`n" [System.Console]::WriteLine($errorXml) disconnect($session) exit } prepareResultTable main exit #end of script #
Created on Jul 20, 2012 12:42:41 PM by
Daniel Zobel [Product Manager]
Last change on Aug 29, 2012 11:05:59 AM by
Daniel Zobel [Product Manager]
i have a Problem with this Script, i have copy it to a ps1 script an load it in new sensor exe/XML. But when i activate the ne sensor i get a failor:
Error reading Response: Invalid XML (missing/prtg)
Whats wrong?
Thanks a lot
Hello,
what happens when you run the script manually? As this is a powershell script, did you set the Powershell execution policy accordingly?
best regards.
Hello, thanks a lot for the script. How can I check the certificats on other servers then the probe server. And it is possibel to create some failure limits for the sensor?
best regards
That would require the script to be invoked on the remote host (via Invoke-Script). A bit of work is necessary then, I'm afraid. Limits can be applied within the channel settings just like for any other sensor :)
Hello
I have a script which will print certificate name and expiry days in Issued certificates from a Certificate Authority server. can someone help me in printing the output in xml format so that we can monitor in PRTG
############# Starting Script #################### function get-ExpiringCerts ($duedays=60,$CAlocation="CAServer\Some Root CA") { $certs = @() $now = get-Date; $expirationdate = $now.AddDays($duedays) $CaView = New-Object -Com CertificateAuthority.View.1 [void]$CaView.OpenConnection($CAlocation) $CaView.SetResultColumnCount(5) $index0 = $CaView.GetColumnIndex($false, "Issued Common Name") $index1 = $CaView.GetColumnIndex($false, "Certificate Expiration Date") $index2 = $CaView.GetColumnIndex($false, "Issued Email Address") $index3 = $CaView.GetColumnIndex($false, "Certificate Template") $index4 = $CaView.GetColumnIndex($false, "Request Disposition") $index0, $index1, $index2, $index3, $index4 | %{$CAView.SetResultColumn($_) } # CVR_SORT_NONE 0 # CVR_SEEK_EQ 1 # CVR_SEEK_LT 2 # CVR_SEEK_GT 16 $index1 = $CaView.GetColumnIndex($false, "Certificate Expiration Date") $CAView.SetRestriction($index1,16,0,$now) $CAView.SetRestriction($index1,2,0,$expirationdate) # brief disposition code explanation: # 9 - pending for approval # 15 - CA certificate renewal # 16 - CA certificate chain # 20 - issued certificates # 21 - revoked certificates # all other - failed requests $CAView.SetRestriction($index4,1,0,20) $RowObj= $CAView.OpenView() while ($Rowobj.Next() -ne -1){ $Cert = New-Object PsObject $ColObj = $RowObj.EnumCertViewColumn() [void]$ColObj.Next() do { $current = $ColObj.GetName() $Cert | Add-Member -MemberType NoteProperty $($ColObj.GetDisplayName()) -Value $($ColObj.GetValue(1)) -Force } until ($ColObj.Next() -eq -1) Clear-Variable ColObj $datediff = New-TimeSpan -Start ($now) -End ($cert."Certificate Expiration Date") "Certificate " + $cert."Issued Common Name" + " will expire in " + $dateDiff.Days + " days at " + $cert."Certificate Expiration Date" #"Send email to : " + $cert."Issued Email Address" "------------------------" } $RowObj.Reset() $CaView = $null [GC]::Collect() } get-ExpiringCerts -duedays 365 -CAlocation "CAServer\Some Root CA" ######## Ending Script #############
Regards Madhusudhan Kasturi
Created on Jan 26, 2021 8:53:05 PM by
msk001819
(0)
Last change on Jan 27, 2021 6:27:25 AM by
Felix Wiesneth [Paessler Support]
Hello,
The output has to be as expected by PRTG. You can find the proper output syntax in your Webinterface under "Setup > PRTG API > Custom Sensors" or within our online manual. This article might help as well.
Hello, Thanks for the reply I am very much new to powershell and xml. Can anyone of you help me in providing script similar to above.
Thanks in advance
Hello, maybe someone out of the community might be able to help. Currently we -Paessler - can only offer general support for PRTG. Regarding customization and custom sensors/scripts we can only offer very limited support: We can of course provide hints, but we do not provide or adjust custom scripts. Thank you for understanding.
©2023 Paessler AG Terms & Conditions Privacy Policy Legal Notice Download & Install
Add comment