OpsMgr: Logical Disk free space alerts don’t show percent and MB free values in the alert description


With the latest OS Management packs the logic behind the disks free space monitor has changed with the goal of minimizing flip flops (the condition when a disk is near the attention threshold and you get alerts opening and closing). This change removed the information about MB and % disk free from the alert description, Kevin Holman blogged about this with all the details so I won’t repeat what he has explained much better than I can: http://blogs.technet.com/b/kevinholman/archive/2011/11/17/opsmgr-logical-disk-free-space-alerts-don-t-show-percent-and-mb-free-values-in-the-alert-description.aspx.

His solution is to revert the rules to their old behavior introducing a couple of management packs that disable the new monitors and reinstall the old ones.

I want to follow a different approach to achieve a comparable thus not identical result. The goal is to not modify the original code but rather add a diagnostic and a task to the new monitors that get the MB and % free space. The major difference with Kevin solution is you won’t have the data in the alert description but in the health explorer change state context, on the other hand you should be fairly independent from any new OS MPs release.

But before digging inside the diagnostic code I want to set some points (not necessarily ordered):

  • a diagnostic is a probe that gets executed when a monitor changes its health state from healthy to warning or error. A diagnostic should not change the system state
  • the new monitors lost the ability to report on disk free space because the MPs author decided to keep the old code and then chain a filter module to change the state only if the disk stays under threshold for n (4) samples. Since there’s no generic filter module to do this in OpsMgr the author transformed the data in performance data and then used the performance specific filter System.Performance.ConsecutiveSamplesCondition. This highlights two annoyance:
    • the lack of generic filter modules for non-performance data
    • the need, to overcome this limitation, to implement persistence, when it’s needed, in every single script. The MP author should have chose this way to implement the new monitor.

But let’s return to the diagnostic stuff, we need:

  • a probe to return disk data (%free space, MB free and anything else we thing can be useful)
  • a couple of diagnostic for the warning and error states
  • a task, since it comes for free once we get the probe done

The net effect is the following:

image

Once you have the probe the syntax for the diagnostic is as follows:

    <Diagnostics>
      <Diagnostic ID="Progel.Windows.Server.2008.LogicalDisk.FreeSpace.Error.Diagnostic" Comment="List current disk allocation." Accessibility="Public" Enabled="true"
                  Target="Win2008!Microsoft.Windows.Server.2008.LogicalDisk" Monitor="Win2008Mon!Microsoft.Windows.Server.2008.LogicalDisk.FreeSpace" ExecuteOnState="Error" Remotable="true" Timeout="300">
        <Category>Maintenance</Category>
        <ProbeAction ID="PA" TypeID="QND.Library.DiskSpaceGet.PT">
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <DiskLabel>$Target/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</DiskLabel>
          <ScriptTimeout>120</ScriptTimeout>
        </ProbeAction>
      </Diagnostic>
      <Diagnostic ID="Progel.Windows.Server.2008.LogicalDisk.FreeSpace.Warning.Diagnostic" Comment="List current disk allocation." Accessibility="Public" Enabled="true"
                  Target="Win2008!Microsoft.Windows.Server.2008.LogicalDisk" Monitor="Win2008Mon!Microsoft.Windows.Server.2008.LogicalDisk.FreeSpace" ExecuteOnState="Warning" Remotable="true" Timeout="300">
        <Category>Maintenance</Category>
        <ProbeAction ID="PA" TypeID="QND.Library.DiskSpaceGet.PT">
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <DiskLabel>$Target/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</DiskLabel>
          <ScriptTimeout>120</ScriptTimeout>
        </ProbeAction>
      </Diagnostic>
    </Diagnostics>

I just want to highlight the Diagnostic is state specific, so you have two different diagnostics one for Error state and the other one for Warning state. All the other parameters are pretty straightforward.

You can find the sample MP for Windows 2008 here

– Daniele

This posting is provided "AS IS" with no warranties, and confers no rights.

  1. #1 by Patrik Schumacher on May 15, 2012 - 12:36 pm

    Hello, do you also have an MP with the same Diagnostic Task for Windows Server 2003?

    • #2 by Daniele Grandini on May 17, 2012 - 11:52 am

      Hi Patrik,
      I don’t have one yet. But if you take a llok at the code it should be easy to adapt to Win 2003.

      -Daniele

  2. #3 by Jose A. Hernandez on January 10, 2012 - 12:23 am

    Hi,

    I’m trying to also generate an email address by adding a few lines of vb code to the part of your script that echoes the results:

    If UCASE(sDriveLetter) = UCASE(P_DiskLabel) Then
    ‘Output data
    WScript.Echo String(80, “-“)
    WScript.Echo “Server: ” & TargetComputer & ” Disk: ” & P_DiskLabel
    WScript.Echo String(80, “-“)
    WScript.Echo “Disk Size (MB): ” & Round(nMaxSize / BYTES_IN_MB, 0)
    Wscript.Echo “Disk Free Space (MB): ” & nMBFree
    WScript.Echo “Disk Free %: ” & nPctFree & “%”
    ‘Send email to IOPS Group
    Set objMessage = CreateObject(“CDO.Message”)
    objMessage.Subject = “SCOM Generated a Disk Space Alert for ” & ServerLabel
    objMessage.From = “SCOM-LogicalDisk@company.com”
    objMessage.To = “myemail@company.com”
    objMessage.TextBody = String(80, “-“) & vbCRLF & “Server: ” & ServerLabel & ” Disk: ” & HardDriveLabel & vbCRLF &String(80, “-“) & vbCRLF & “Disk Size (MB): ” & Round(nMaxSize / BYTES_IN_MB, 0) & vbCRLF & “Disk Free Space (MB): ” & nMBFree & vbCRLF & “Disk Free %: ” & nPctFree & “%”
    objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/sendusing”) = 2
    objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserver”) = “smtp.dorseylaw.corp”
    objMessage.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserverport”) = 25
    objMessage.Configuration.Fields.Update
    objMessage.Send
    Set objMessage = Nothing

    I can run this vb code fine outside of SCOM and receive the email. But when I import the mp with this change and the diagnostic task is run, the task still returns the echoed results to the SCOM console but I never get the email. As far as SCOM goes, the diagnostic completes successfully. Any ideas why this simple modification is not working?

    • #4 by Daniele Grandini on January 11, 2012 - 6:50 pm

      Hi Jose,
      the only difference I can think of if the system where the diagnostic is executed and the security context. The diagnostic is executed on the system running the monitor (i.e. the system with the low disk space), it is run under the default action account for the agent, typically LSA. So you should try the script from that system and under that credential (for example use psexec to open a commond prompt as SYSTEM), possibile causes:
      – the smtp server is not reachable / DNS resolvable from the engaed system
      – the smtp server requires authentication and the agent default action account is not authorized to send email

      Let me know if this resolves the issue

      – Daniele

      • #5 by Jose A. Hernandez on January 12, 2012 - 10:13 pm

        Darn, I thought I was going to get closer to this after reading your reply, but no dice. I ran the script from the server running the monitor as SYSTEM using psexec and I still got the email on my inbox. The mail server in question doesn’t require auth, btw.

      • #6 by Daniele Grandini on January 14, 2012 - 11:00 am

        Hum, time for some more troubleshooting. I would suggest adding some tracing just to understand what’s going on.
        Add the follwing code at the top of the script
        Dim e
        Set e = new Error
        After the cdo send method call just add something like this:

        if err.number 0 then
        e.save
        ThrowScriptErrorNoAbort “Send Failed”, e
        err.clear
        end if
        then check which error code is returned in the OPsMgr event log. I would even try to set the cdoauthentication field to anonymous just to be sure no authentication is tried.

        Hope this helps
        Daniele

      • #7 by Jose A. Hernandez on January 26, 2012 - 12:16 am

        Hi Daniele,

        I’m assuming there should be an operator in the statement:

        “if err.number 0 then” such as “if err.number 0 then”, right?

        If so, after adding both snippets of code, re-importing and running the diagnostic task, no error is logged. :(

      • #8 by Jose A. Hernandez on January 26, 2012 - 12:23 am

        haha, I guess the operator was there to begin with, it’s just that wordpress doesn’t seem to handle the greater than / less than symbols.

  3. #9 by Tom Klaver on January 3, 2012 - 9:29 pm

    Hi Daniele, I downloaded and tested your sample MP, but I believe their is an error in the vb script “QND.Library.DiskInfo.vbs” that is added to your sample MP. In the script there are two arguments used. One for variable TargetComputer and one for the variable P_DiskLabel. In the script both variables need to be set with the arguments in the commandline. I noticed that the lines in the script “TargetComputer = oArgs(0)” and “P_DiskLabel = oArgs(1)” are not correct. If the scripts runs I receive the following output:

    Unable to open WMI Namespace ‘winmgmts:\\\root\cimv2’. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists..
    Unable to open WMI Namespace ‘winmgmts:\\\root\cimv2’. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists..
    The Query ‘select * from Win32_LogicalDisk where (DriveType=3 or DriveType=6) and FileSystem != null’ returned an invalid result set. Please check to see if this is a valid WMI Query.. Object required
    The Query ‘select * from Win32_LogicalDisk where (DriveType=3 or DriveType=6) and FileSystem != null’ did not return any valid instances. Please check to see if this is a valid WMI Query.. Object required
    ——————————————————————————–
    Server: Disk: *NOT FOUND*
    ——————————————————————————–

    I believe the two lines must be changed to:
    TargetComputer = WScript.Arguments.Item(0)
    P_DiskLabel = WScript.Arguments.Item(1)

    When I manually run the script I receive to correct output as you describe in your blog post.
    Best regards
    Tom Klaver

    • #10 by Daniele Grandini on January 5, 2012 - 3:01 pm

      Oops Tom you’re right, the script somehow misses a row:
      Set oArgs = WScript.Arguments
      If you add this row just before the TargetComputer assignment you’ll do the trick. I just updated the MP.

      Thanks
      Daniele

    • #11 by Daniele Grandini on January 5, 2012 - 3:01 pm

      Oops Tom you’re right, the script somehow misses a row:
      Set oArgs = WScript.Arguments
      If you add this row just before the TargetComputer assignment you’ll do the trick. I just updated the MP.

      Thanks
      Daniele

  4. #12 by Kevin Holman on November 19, 2011 - 5:51 pm

    Daniele – have you noticed that the new free space script/monitor/solution breaks cookdown? I am almost sure it does, because we are now passing different parameters to the datasource for each disk. Pretty sure that will run one script for each logical disk simultaneously, every 15 minutes. Do you confirm?

    • #13 by Daniele Grandini on November 19, 2011 - 6:17 pm

      Hi Kevin I would say yes, similar to the network bandwith one. For sure the datasource Microsoft.Windows.Server.2003.FreeSpace.Moduletype is not cooked since the disk label is passed as a parameter, the internal script data source on the other hand doesn’t have any specific instance parameters and here I have a doubt. It really depends on how cookdown is implemented, if it analyzes every single module it should have a chanche to cook, if it just check the main datasource signature it won’t. This is an interesting question that’s easy to check with a one line script…

      • #14 by Daniele Grandini on November 19, 2011 - 6:30 pm

        I made up my mind, it won’t cookdown because fork has been already done at the master datasource, so I have the monitor targeted to my server, once I call the DS, since the DS has the disk label in its parameters, one workflow per disk will be created and even if the script is potentially “cookable” it won’t because fork already happened. So far as I understand cookdown. Same story with NetworkAdapter.BandwidthUsed.ModuleType.

  5. #15 by Kevin Holman on November 19, 2011 - 5:43 pm

    I like it. Certainly a better solution if all you really want is the information into Health Explorer.

  1. OpsMgr: Logical Disk free space alerts don’t show percent and MB free values in the alert description – updated for Server 2012 - Kevin Holman's System Center Blog - Site Home - TechNet Blogs
  2. OpsMgr: Logical Disk free space alerts don’t show percent and MB free values in the alert description - Kevin Holman's System Center Blog - Site Home - TechNet Blogs

Leave a reply to Patrik Schumacher Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.