I have been using PowerShell monitors with WhatsUp Gold for nearly 3 years now. They offer a lot of flexibility and the ability to query a lot more systems that is available natively through SNMP, WMI or other built in monitor types.
However, with all of this flexibility comes the ability to introduce many problems. I have developed a list of best practices that I follow whenever I write my monitors, which so far has fared me well and I have not had too many issues.
About the NMPoller – Why we need to be careful with memory
At this time, WhatsUp Gold is a 32-bit application (I am running 16.5.1). The NMPoller service is therefore constrained. I have witnessed the poller freeze on multiple occasions when it runs out of resources, leading to unreliable monitoring of systems. Not something that is desirable!
Best Practices
1. Filter objects and properties aggressively. Only get the information that you actually need, and only return properties that you really care about. The less data to process, the quicker the monitor will run and the less memory required.
2. Sort sparingly. This is a monitor, alerting you to a state. The order of items probably isn’t important.
3. Use variables sparingly. They consume memory, which does not always get properly cleared by the NMPoller. If you have to use variables, and they contain a large amount of data, remove them just before returning.
There is a trade-off here though. Whilst it can sometimes be possible to write your command in a single line, it may not be that easy to understand and debug. The point here is to reduce the accumulation of large amounts of data in memory.
4. Clean up any custom PSObjects that you create. Remove the variable or set to null before returning the results.
5. If you are using remoting, ensure sessions get removed. Don’t expect them to be cleaned up for you.
6. If using remoting, do all the work in the remote session, and just return the result value/description object. Less data has to travel across the network aiding performance.
7. Avoid using Import-PSSession. If required, only import the commands that you actually need. Try to use Invoke-Command instead though, as the monitor should run quicker. Imported cmdlets use up memory even after the session has been removed.
8. Invoke the Garbage Collector just before returning the values by using
[System.GC]::Collect()
9. Keep it simple. Monitors should be checking details. Any attempts to automatically fix issues should be handled by an Action.
There are probably other things to consider, but these are what I have identified so far. If you think there is something else that should be included here, please let me know.