I wanted to share this information because the Powershell integration with PRTG is difficult to comprehend at times. Let's put it this way, I sure found it difficult to understand!
I find that there are many things that I need to monitor but PRTG does not always supply a specific sensor to solve that problem.
One thing that forced me to make this work was that Microsoft depricated SNMP monitoring of DHCP services. They have completely removed the SNMP OID category for DHCP in their SNMP support on 2012 and higher servers. (Not a good decision Microsoft!!!)
I really needed to find a new way to get the current status of specific DHCP scopes that might fill up from time to time.
I know that there is a WMI scripting sensor but I wanted to write it in Powershell so that I could recycle the process for other Microsoft items that need monitoring via Powershell. This should help me to do that with small modifications. I am hoping to use this method with VMware PowerCLI to help monitor our VMware systems, too.
I use several probe servers so the first tasks were to:
- Add the DHCP Administration feature in Windows Server 2012r2 to the probe server using Windows Server Manager
- Import the Powershell module into the 32-bit Powershell environment
- Write a Powershell command that could capture the correct information without formatting. That command which returns an in-use percentage is here:
(get-dhcpserverv4scopestatistics -ComputerName servername -ScopeId $scopeid).PercentageInUse
ScopeID is the IP scope assigned to DHCP server. In this case our example is 10.10.20.0.
The second task was to create a script that would work with PRTG. I named it dhcpscopevalue.ps1 and placed it into the Custom Sensor/EXE location on the probe that will run the script. I did much Googling and found various PRTG examples, scripts, and Powershell tutorials that helped me figure it out.
That script is here:
<# Add the following parameters separated by spaces to the PRTG parameters field in the same order as listed. Powershell requires them to be surrounded by single quotes. Parameters Example: '10.10.20.0' '%host' '%windowsuser' '%windowspassword' #> Param( [string]$scopeid, [string]$hostname, [string]$Username, [string]$Password ) # create credentials $SecPassword = $Password | ConvertTo-SecureString -AsPlainText -force $cred = new-object -typename System.Management.Automation.PSCredential ($Username, $SecPassword) # Create session and run script. Use invoke-command with credentials. Import scopeid variable into scriptblock. $ret = invoke-command -ComputerName $hostname -Credential $cred -ScriptBlock {Param($scopeid) (get-dhcpserverv4scopestatistics -ComputerName dhcpprd01 -ScopeId $scopeid).PercentageInUse} -ArgumentList $scopeid # output data for prtg to use write-host $ret":DHCP Scope $scopeid Used: $ret%" # Do some housekeeping Remove-Variable -Name scopeid # The exit command seems to help end the script to avoid timeouts. exit
The third task is to create a custom EXE sensor with the noted settings. Name it something useful and add a tag name that makes sense. An example of my probe name is DHCP Scope - Guest Wireless: 10.10.20.0. My tag is dhcppercent. The Security Context was changed to Use Windows credentials of parent device. The Value Type is float and I changed the Primary Channel field to ScopePercent(%). Remember to change the Value Type and the Primary Channel field when you first create the sensor. It cannot be modified later.
I made a PRTG Map for our Networking Team Members to leave on display so that they would have a visual monitoring of the important scopes. I also modified the sensor channel event thresholds to that it would show the proper warning and error conditions when it hit 90% and 100%. Once you have done all of this work, use the clone feature to make new ones and edit the appropriate settings after you clone the sensor. It saves a lot of time.
Please note: If you add more of these sensors, remember that each one runs another Powershell script which puts a big load on the computer. I found that I could safely run about 22 sensors with 60 sec. intervals, 44 sensors with 5 minute intervals, or 80 using 10 minute intervals. I could tell they were having problems because they would start showing 0 data values.
My next step will be to check out the new REST sensor or the EXEXML sensor and see if we can create a single sensor with multiple channels. I hope it will have a lighter load on the system by running a single script instead of many.
Article Comments
I forgot to credit some sources that helped me to figure out this solution in addition to the PRTG KB articles and documentation.
https://lockstepgroup.com/blog/extreme-basics-of-prtg-custom-sensors-with-powershell/ https://thedomainiown.wordpress.com/prtg-related/general-custom-exe-script/
Sep, 2017 - Permalink
After 6 months: Has there been any progress implementing this as an "out-of-the-box"-sensor?
Mar, 2018 - Permalink
I'm afraid this is not planned as a native sensor. It's part of the script world now, and if there is enough usage there, we can consider building a native sensor.
Mar, 2018 - Permalink
That is sad to hear. It seems like Paessler is more and more ignoring new ideas and improvement recommendations from users. Don't get me wrong. Support has always been very good. Questions to support@ always get answered very fast. But in regards of improvements and enhancements to the system I feel pretty ignored right about now as I have brought in at least 10 new ideas for improvements over the last year and not even one of them was picked up. I always read "that is not planned". :-(
Mar, 2018 - Permalink
Please bear in mind, we've got 200,000 installations of our software, often with several users per installation working with our applications. It's in the nature of being a user of any product that you'll come up with ideas much faster than the ideas can put into reality. This applies to software as to pretty much any other product.
That means we have to focus on implementing those ideas where most users benefit from. Because even if we've had one developer per user, it would still be impossible to implement each idea, because thinking of an idea is instant, whereas putting it into code, testing it, documenting and supporting it, isn't instant.
So we have to say no a lot. That does not mean though, that we like to say no, it simply is the reality we live in. And it doesn't mean that the rejected ideas aren't useful in their specific use cases. It's always a compromise.
Mar, 2018 - Permalink
Hi Torsten,
I understand your point, but in this case sounds like an Excuse. There are many many people who would be very glad to have this sensor available. It is not a random request. The DHCP service is one of the most critical elements in the infrastructure. Having a ping is not enough.
I hope that this can be taken not as another stupid request, but as a very important one.
Regards.
Apr, 2018 - Permalink
Hi Tom,
Thanks for the great script. I made a few changes to allow for the fact that my DHCP server is running 2008 R2 and there for didn't have the required PowerShell command get-dhcpserverv4scopestatistics.
Since my PRTG server was running Server 2012 R2 I added the DHCP Server Tools feature to it and then used the belwo modifed version of your script. Basically I just removed the invoke piece and run the get-dhcpserverv4scopestatistics command directly from the PRTG server.
Add the following parameters separated by spaces to the PRTG parameters field in the same order as listed. Powershell requires them to be surrounded by single quotes.
Parameters Example
'10.10.20.0' '%host' '%windowsuser' '%windowspassword' |
Script
Param( [string]$scopeid, [string]$hostname, [string]$Username, [string]$Password ) # create credentials $SecPassword = $Password | ConvertTo-SecureString -AsPlainText -force $cred = new-object -typename System.Management.Automation.PSCredential ($Username, $SecPassword) # Create session and run script. Use invoke-command with credentials. Import scopeid variable into scriptblock. $ret = (get-dhcpserverv4scopestatistics -ComputerName DhcpServername -ScopeId $scopeid).PercentageInUse # output data for prtg to use write-host $ret":DHCP Scope $scopeid Used: $ret%" # Do some housekeeping Remove-Variable -Name scopeid # The exit command seems to help end the script to avoid timeouts. exit
Jun, 2018 - Permalink
If you are running 2008r2, I believe you would need to install the Microsoft Framework 3 or higher.
Jun, 2018 - Permalink
Hi,
is the script still working on any system? We have a 2016 DHCP server, but get no information back from the script.
Aug, 2018 - Permalink
Dear PekkaHopp,
in order to debug it, please open the sensor's settings tab and enable the sensor option "Write Exe result to disk". After the next scan, the log files are in "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)" where you can analyze the script output.
Aug, 2018 - Permalink
My newest DHCP server is Windows 2012 Standard.
I'm using the script from Luciano (normal EXE, not Advanced EXE).
Parameters: | '<dhcp_scope>' '%host' '%windowsuser' '%windowspassword' |
---|---|
Result: | The_number_of_available_addresses |
I've not been able to create a multi-scope sensor.
Aug, 2018 - Permalink
Dear Corné,
please also open the sensor's settings tab and enable the sensor option "Write Exe result to disk". You find the log in "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)" after the next sensor scan, allowing you a look at the output.
For example, it could be that the parameters were provided wrongly, or that the script has not enough rights to run. In order to address the latter issue, please check the script sensor's security context.
Aug, 2018 - Permalink
Dear PekkaHopp,
Be sure that you have created this in the 32-bit Powershell environment on your probe that will be running the script. For troubleshooting purposes, run the script from the Powershell window to see if it returns information or throws an error message.
Aug, 2018 - Permalink
I second the request of a native DHCP scope sensor as well, since this is really a critical service for us.
In the meanwhile I use a little modified version of the script I found on Reddit: https://www.reddit.com/r/prtg/comments/632z0d/script_monitor_dhcp_scope_usage/
Param ( [STRING]$serverName ) $dhcpScopeStats = Get-DhcpServerv4ScopeStatistics -ComputerName $serverName $xmlOutput = '<?xml version="1.0" encoding="UTF-8" ?><prtg>' foreach ($scope in $dhcpScopeStats) { $xmlOutput = $xmlOutput + "<result> <channel>$($scope.ScopeId)</channel> <value>$([math]::Round($scope.PercentageInUse))</value> <unit>Percent</unit> <limitmode>1</limitmode> <LimitMaxError>95</LimitMaxError> <LimitMaxWarning>90</LimitMaxWarning> <LimitErrorMsg>DHCP Scope is over 95%</LimitErrorMsg> <LimitWarningMsg>DHCP Scope is over 90%</LimitWarningMsg> </result>" } $xmlOutput = $xmlOutput + "</prtg>" $xmlOutput
Set it up as xmlexesensor and the parameter of it to '%host' (including the single quotes). Requires the DHCP-Tools on the probe server.
In this way I can check the older 2008 R2 DHCP servers as well and have all scopes in channels.
Sep, 2018 - Permalink
Hello,
Can someone help me please All i keep getting is a percentage symbol but no value next to it. The sensors green and i've set limits but it just stays at 0% even though we're using a lot of the scope. Help please?
Oct, 2018 - Permalink
Dear KarbonHomes,
in order to debug custom scripts, please go to its sensor "Settings" tab, and enable "Write exe result to disk". The logs are written to "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)", and show the output produced by the script. In many cases, the output shows an error message which prevents the further execution of the Powershell program.
Oct, 2018 - Permalink
Hi,
Here's an improved version of your script that can take multiple scopes in a single sensor & also you don't need to specify scopes manually:
<# Add the following parameters separated by spaces to the PRTG parameters field in the same order as listed. Powershell requires them to be surrounded by single quotes. Parameters Example: '%host' '%windowsuser' '%windowspassword' #> Param( [string]$hostname, [string]$Username, [string]$Password ) # create credentials $SecPassword = $Password | ConvertTo-SecureString -AsPlainText -force $cred = new-object -typename System.Management.Automation.PSCredential ($Username, $SecPassword) # Create session and run script. Use invoke-command with credentials. invoke-command -ComputerName $hostname -Credential $cred -ScriptBlock { $dhcpscopes = Get-DhcpServerv4Scope | where state -EQ active #get all active scopes Write-Host "<prtg>" #start creating the XML format #this part creates as many entries as necessary depending on the number of Scopes foreach ($scope in $dhcpscopes) { $scopeid = $scope.ScopeId.IPAddressToString $percentage = (get-dhcpserverv4scopestatistics -ScopeId $scopeid).PercentageInUse Write-Host "<result>" "<channel>$scopeid</channel>" "<value>$percentage</value>" "<LimitMaxError>90</LimitMaxError>" "<LimitMode>1</LimitMode>" "<float>1</float>" "</result>" } Write-Host "</prtg>"} # The exit command seems to help end the script to avoid timeouts. exit
Jul, 2019 - Permalink
Dear mbaybarsk,
thank you for sharing the script!
Please allow me these two remarks:
1) The script could produce more than 50 channels. PRTG officially supports only up to 50 channels. For stability, it would be useful to limit the foreach loop to a certain number of channels.
2) It could happen that the primary channels gets no data, for those purposes I recommend to create a channel with a static output which serves as primary one.
Jul, 2019 - Permalink
First I'd like to say thank you all for sharing your scripts and work.
This is what I'm using in our environment.
PRTG Server: Windows Server 2019
DHCP Server: Windows Server 2012R2
This script utilizes invoke-command.
<# Sensor name: dhcpserverv4scopestatistics exe/script: getdhcpserverv4scopestatistics.ps1 Parameters: '%host' '%windowsdomain' '%windowsuser' "%windowspassword" sec context: use windows credentials of parent device #> Param( [string]$ComputerName, [string]$windowsdomain, [string]$Username, [string]$Password ) $Username = "$Username@$windowsdomain" # create credentials $SecPassword = $Password | ConvertTo-SecureString -AsPlainText -force $Credential = new-object -typename System.Management.Automation.PSCredential ($Username, $SecPassword) $ret = invoke-command -ComputerName $ComputerName -Credential $Credential -ScriptBlock { Param($ComputerName) get-dhcpserverv4scopestatistics -ComputerName $ComputerName } -ArgumentList $ComputerName # use system collections arraylist for performance # alternatively maybe look into StringBuilder # also adding / appending is more efficient vs += using @() array $ArrayList = [System.Collections.ArrayList]@() # prtg xml headers $null = $ArrayList.add( @" <?xml version="1.0" encoding="Windows-1252" ?> <prtg> "@ ) # for stability reasons we may want first 50 highly used ScopeIds: $ret = $ret | sort -Descending PercentageInUse | select -First 50 <# ScopeId Free InUse PercentageInUse Reserved Pending SuperscopeName ------- ---- ----- --------------- -------- ------- -------------- 172.16.28.0 118 243 67.31302 25 0 172.16.6.0 87 117 57.35294 1 0 172.16.8.0 87 114 56.71642 9 0 #> # prtx xml results foreach($r in $ret) { $ScopeID = $r.ScopeID $PercentageInUse = $r.PercentageInUse $null = $ArrayList.add( @" <result> <channel>DHCP Scope - $ScopeID</channel> <unit>Percent</unit> <mode>Absolute</mode> <showChart>1</showChart> <showTable>1</showTable> <warning>0</warning> <float>1</float> <value>$PercentageInUse</value> <LimitMaxError>37</LimitMaxError> <LimitMaxWarning></LimitMaxWarning> <LimitWarningMsg>My custom note for warnings</LimitWarningMsg> <LimitErrorMsg>My custom note for errors</LimitErrorMsg> <LimitMode>1</LimitMode> </result> "@ ) } # prtg xml footer $null = $ArrayList.add( @" </prtg> "@ ) # output data for prtg to use $ArrayList # The exit command helps to end the script and avoid timeouts. exit
Oct, 2019 - Permalink
Hi, Can someone share the permissions required for this script to work without admin rights? I have added the user to the dchp-users and remote management groups yet I always get the error + CategoryInfo : PermissionDenied: (PS_DhcpServerv4ScopeStatistics:root/Microsoft/...ScopeStatistics) [Get-DhcpServerv4ScopeStatistics], CimException
Thanks
Feb, 2020 - Permalink
Permissions needed: Make sure the account used for running the script has permissions for remote script execution.
Feb, 2020 - Permalink
Dear Corné,
please check the security context you set for this sensor, as the probe service (using the local SYSTEM account by default) might not be allowed to run remote scripts. Instead, use the device's credentials.
Please also make sure that the powershell execution policy is configured to allow running the script (see Powershell command set-executionpolicy).
Feb, 2020 - Permalink
Not sure if anyone would find this useful, I took one of the above scripts and edited it to also show scope names with subnets. It should be noted to use this sensor in this post you have to set the Security Context to "Use Windows credentials of parent device". If it is left at the default the sensor will error out with no data found.
Param ( [STRING]$serverName ) $dhcpScopeStats = Get-DhcpServerv4Scope -ComputerName $serverName $xmlOutput = '<?xml version="1.0" encoding="UTF-8" ?><prtg>' foreach ($scope in $dhcpScopeStats) { $ScopeName = $scope.Name $ScopeId = $scope.ScopeId $ScopeStats = Get-DhcpServerv4ScopeStatistics -ScopeId $ScopeId -ComputerName $serverName | select PercentageInUse $xmlOutput = $xmlOutput + "<result> <channel>$($ScopeName) ($ScopeID)</channel> <value>$([math]::Round($ScopeStats.PercentageInUse))</value> <unit>Percent</unit> <limitmode>1</limitmode> <LimitMaxError>95</LimitMaxError> <LimitMaxWarning>90</LimitMaxWarning> <LimitErrorMsg>DHCP Scope is over 95%</LimitErrorMsg> <LimitWarningMsg>DHCP Scope is over 90%</LimitWarningMsg> </result>" } $xmlOutput = $xmlOutput + "</prtg>" $xmlOutput
Jul, 2020 - Permalink
Hi All,
I'm getting this error when attempting to use this ps script, any help in getting this working?
I have the Syntax below
Param( [string]$'Mgmt-Svr', [string]$'Int.Net', [string]$'username', [string]$'password' ) $Username = "$Username@$windowsdomain"
At line:13 char:9
+ [string]$'Mgmt-Svr', + ~
Parameter declarations are a comma-separated list of variable names with optional initializer expressions.
At line:13 char:9
+ [string]$'Mgmt-Svr', + ~ Missing ')' in function parameter list. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvalidFunctionParameter
Oct, 2021 - Permalink
Hello parky,
using a hyphen in Powershell variables is problematic unless first created with New-Variable. For this parameter block the easiest way is to not use hyphens.
Oct, 2021 - Permalink
We're using this script for a couple of years now, without any problems. Since the last Windows Updates two weeks ago, we notice high CPU usage on the DHCP servers. The process wsmprowhost.exe is using 50% CPU. In Event Viewer it looks like this process is executing 58 commands for one scope. As we are monitoring five scopes and check every minute, there is almost non-stop high CPU usage.
Our environment: DCHP servers are Windows Server 2019. Installed updates two weeks ago: KB5017270, KB5018419 and Servicing Stack 10.0.17763.3460
PRTG Probe is Windows Server 2012. Installed updates two weeks ago: KB5018413, KB5018478, KB5018518 and KB5018457
Is anyone seeing the same issue and maybe has a solution?
Oct, 2022 - Permalink
Hi Tom,
Awesome work, thanks for sharing! The script will find its way into our PRTG Sensor World soon :)
Kind regards,
Stephan Linke, Tech Support Team
Sep, 2017 - Permalink