The following article will give an example of how to collect performance data into OpsMgr from a VBscript. This will be handy for instances where a perfmon counter does not exist for something that you wish to measure, but you can write a script to output the value and instance information.
I had a customer who wanted to monitor Network Adapter Utilization. This would be measured in % consumption of the total bandwidth of the NIC. You can see an example of this by looking at Task Manager in 2008 and later:
The problem is – this perf counter does not exist in perfmon. However, we do have two perf counters that we can use to calculate the percentage utilization at runtime:
- Bytes Total/sec
- Current Bandwidth
To calculate % Network Utilization – we would use something like the following formula:
((BytesTotalPerSec * 8)/CurrentBandwidth) * 100
We can calculate this pretty easily in VBScript. We will use VBscript to access WMI, get the counter values, perform the math, and submit this information as a propertybag. OpsMgr will take this propertybag value, and insert it along with the Object, Counter, and Instance information we pass along.
Below is an example of my script:
Dim oArgs, sNicName
Set oArgs = WScript.Arguments
sNicName = oArgs(0)
' Get the properties of the NIC and the values of BytesTotalPerSec and CurrentBandwidth and calculate the network util
dim oNIC, sUtil
Set oNIC = GetObject("winmgmts:root\cimv2:Win32_PerfFormattedData_Tcpip_NetworkInterface.Name='" & sNicName & "'")
sUtil = FormatNumber(((oNIC.BytesTotalPerSec*8)/oNIC.CurrentBandwidth)*100,2)
' Create PropertyBag object
Dim oAPI, oBag
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreatePropertyBag()
oBag.AddValue "PerfValue", sUtil
This script take a single parameter – the name of the Network Card (since computers can have multiple NICS).
Then, it connects to WMI, and gets the Win32_PerfFormattedData_Tcpip_NetworkInterface data where the name = the parameter we passed. The it performs the calculation we discussed above.
Finally, it submits this calculated value in a Propertybag, which is a form that OpsMgr can use, and map this to a made up Object\Counter\Instance just like perfmon data.
Lets get started writing the performance collection rule:
Open the authoring console. File > New > Empty Management Pack. I will give mine an ID of Example.Network.Utilization
Next > Give the MP a good Display Name > Create.
Next up – we will need to borrow some properties of the Network Adapter from the Base OS System Library, so we need to add a reference for that.
File > Management Pack Properties > References Tab > Add Reference. Browse to the location where your Base OS System library is – which is Microsoft.Windows.Server.Library.mp. When done it should look like below. Click OK.
Select the Health Model pane > Rules > New > Collection > Performance Based > Script Based Performance Collection
Give the Rule a unique ID, Display Name, and Description. For the target – choose Microsoft.Windows.Server.NetworkAdapter. Set the category of the rule to PerformanceCollection.
Click Next. Change the frequency to once every 5 minutes.
***Note – on a script based rule or monitor – we must be careful not to run these too frequently – as these will use considerable resources (cumulatively) for each script to execute and spin up a cscript.exe process per script execution.
Click Next. Give the script a good name that makes sense, set the timeout to a value that it should always be able to complete in. Past in your script code from above.
On the Parameters – we need to pass a single parameter to the script – the name of the Network Card. In this case – there is a discovered property of the chosen target class (Microsoft.Windows.Server.NetworkAdapter) which is named “Performance Monitor Instance Name”
Select that option, which will populate the parameter section for the script. This value for this variable can be seen when viewing the discovered properties of your network adapters in Discovered Inventory in the monitoring pane of the console.
Now – we MUST place this whole variable in QUOTES – because this will be passed as a command line argument and if there are any spaces in the name that will cause issues:
Click OK, then Next.
This will bring up the Performance Mapper screen. On this screen – we need to “map” the typical Perfmon object/counter/instance/value data. Since this is not a real perfmon counter – we can just make up values for this.
- Object: Network Interface (this is the same as would be in Perfmon)
- Counter: % Network Utilization (I made this up – sounds good)
- Instance: Use the flyout and choose “Performance Monitor Instance Name” again.
- Value: Leave the default of “$Data/Property[@Name='PerfValue']$”. This matches what we used in the propertybag in the script.
Click Finish – and we are done!
Import the MP and you will be able to start seeing your performance data if you create a performance view for this:
You will also be able to create ad-hoc reports, using Performance Top Objects – to quickly identify the machines with the most utilized network interfaces:
Not surprisingly – my Hyper-V servers and my primary SQL database are the most utilized.
Now – what's bad about this example?
Well I am glad you asked!
The problem with this example is that this script will execute one time for each NIC in a computer, every 5 minutes. This means on a system with 4 discovered network cards – we will execute the script 4 times – simultaneously. This is because we targeted a multi-instance object (Network Adapter) and we did not specifically write our script (data source) to support Cookdown. Cookdown is further discussed here: http://www.authormps.com/dnn/Concepts/WorkflowBasics/CookDown/tabid/117/Default.aspx
Essentially – OpsMgr has a native way of running a single script – one time, and populating this data for each instance. Instead of running 4 times simultaneously for a computer with 4 network cards, it would only run once, and the script and rule would be modified to support this concept.
If we don’t support cookdown – it isn't the end of the world… you will just see more resources consumed (memory, CPU) for the multiple simultaneous script executions, every 5 minutes. This becomes more and more critical in examples where we want to run the script more frequently, or share the script across several different rules and monitors.
The next article in this series will be taking this same MP and modifying it to support cookdown.
Below – you will find this example MP attached.