Wednesday, November 13, 2013

SCOM Unit Monitor Based on Memory Percentage %

There technically isn't a perf counter for memory % used/free. You can use the following counters from the Windows Server management packs. They're very good indicators for memory pressure. However, if you want to just know when servers have violated a basic percentage of installed physical memory you have to build your own scripted unit monitor.

In researching this I stumbled on a forum post here.

I highjacked most of this script but made some alterations to leverage more out of the box SCOM functionality.

Take the following script and build a Time Script Three State Monitor (see below)

Option Explicit

Dim oAPI, oBag, oArgs
Dim objWMIService, objItem, colItems
Dim strComputer, strList
Dim memused, mempercent

Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreatePropertyBag()
Set oArgs = WScript.Arguments

On Error Resume Next

strComputer = "."

set objWMIService = GetObject("winmgmts:\\" _
& strComputer & "\root\cimv2")

set colItems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

For Each objItem in colItems

memused = objItem.TotalVisibleMemorySize - objItem.FreePhysicalMemory
mempercent = memused/objItem.TotalVisibleMemorySize
mempercent = mempercent * 100
mempercent = Cint(mempercent)


Call oBag.AddValue("Percent",mempercent)
Call oAPI.Return(oBag)

Best practice is to disable by default. Later you can set overrides for any monitor to enable it where applicable.

Be careful when setting your schedule. I have a fairly aggressive schedule here. This is a fairly light script but the cummulative of monitors can add up to impact performance.

Paste the script above into the script field. Set a file name with a .vbs extension.

Configure your preferred thresholds.

I'm setting a pretty generic override for 2008 Computer Group.


  1. Hi,

    I used the same script as provided by you but no luck , monitor is showing healthy state only and doesnt alert when the memory utilization goes high.
    Any help

    1. Always be careful copying scripts down. I tested copying from this paged into notepad. I tried to save and got this....

      "This file contains characters in Unicode format which will be lost if you save this file as an ANSI encoded text file. To keep the Unicode information, click Cancel below and then select one of the Unicode options from the Encoding drop down list. Continue?"

      If I say OK, close and reopen the script is fine. It drops the Unicode junk. You can test this script manually on any server pretty easily. Just add these lines to it to see what the oBag is returning to SCOM. Put them right between the last "Next" and "Call oBag.AddValue("Percent",mempercent).

      WScript.Echo "Percent: " _
      & mempercent

      This will output the value currently stored in the variable to the screen for you to validate.

  2. Hello and thank you for this post. I am intersted in monitoring physical memory, but i would like the object to change its health only after 3 memory samples were over 90% (to avoid alerting on short spikes). the samples should occur every 2 minutes. can you please advise on how i should do that?

    thanks again,

    1. Problem: The script runs, finishes, and the value in memory is lost. The value reported back to SCOM is stored but the monitor type “Timed Script Two State Monitor” doesn’t support samples. Just a timer. So I think of this as a yes/no sort of monitor. You’re healthy or you’re not.

      WQL doesn't support arithmetic so you can't use a sampling monitor type (hence the script).

      I will tell you that I learned this is a noisy monitor. Little spikes in memory will cause a steady stream of alerts if your threshold is too low or something. A few thoughts…

      1. You could use the native Available Megabytes monitors and just put overrides. You could get really “clever” and build overrides based on groups. i.e. “Servers w/ 4GB” or “Servers w/ 8GB” then calculate what 10% of that is and set it as an override on the group. Your group membership being some dynamic query for systems with X megabytes physical memory installed. Not sure how to do that but it’s an idea.

      2. It’s possible the SCOM authoring tools have some means of creating a custom monitor type that is a script executed over multiple samples. Not sure.

      3. Use some combination of this monitor and an event monitor potentially...Monitor A tracks % and if over 90% generate a warning (two state). At the end of the script have it log something to the event viewer. Monitor B is a Repeated Event Detection monitor on a timer. if it sees X number of the same event in some time span generate a critical alert. Just as noisy in terms of # of alerts. But saves you going into critical right away.

      I don't have a good answer unfortunately. I'm open to suggestions.