Random Post: About
RSS .92| RSS 2.0| ATOM 0.3
  • Home
  • About
  •  

    Collecting Performance Data in Operations Manager 2007 and Publishing to SharePoint Part 1

    July 13th, 2008

    It took me a long time to figure out how to collect Performance Data and properly store it in the Data Warehouse using PropertyBags to insert multiple instances in a single bag. It also took me a long to time to figure out how to pull that data from the tables and get it into Reporting Services and finally published into SharePoint. I’ll give you a hint and tell you that it will save you time in the long run if you thoroughly read the whitepapers (such as the one on Report Authoring found here) rather than skimming. I guarantee that you will wind up coming back to them and reading them in their entirety anyway. So to share a little experience and hopefully help some others, I thought I’d post the steps I did to get it to work (a little lengthy).

    Collecting the data…
    Obviously, the first thing we need to do is get some data into the Data Warehouse so we have something to report against. This is done using PropertyBags from the MOM.ScriptAPI object. (Some additional resources on PropertyBags are: MOMScript.API, Marius Sutara-CreateTypedPropertyBag and OtherMethods, Using Property Bags with Custom Scripting).

    First thing to do is create a Performance based rule that will be used to schedule the script. In the Authoring space, right click on Rules and select Create a new rule. Next, select Script (Performance) under the Collection Rules\Probe Based node as the type of rule. We will need to store this in a non-sealed management pack so we can either select a previously created management pack or create a new one.

    In my case, I needed to collect three different pieces of data related to logical drives: total drive space, used drive space, and remaining free space. Because it is only possible to return a single piece of performance information per rule, I had to create three rules to collect all the necessary data. I used a single script with three subroutines in each rule and simply commented out the two subroutines I didn’t need for that particular rule.

    '==========================================================================
    '
    ' NAME: OpsMgrEnumDriveSpace.vbs
    '
    ' AUTHOR: Alan Finn
    ' DATE  : 5/13/2008
    '
    ' COMMENT: Collect spatial information on logical drive objects and return
    '       data to the data warehouse via PropertyBags.
    '
    '==========================================================================
    Option Explicit
     
    Const UNKNOWN       = 0
    Const NOROOT        = 1
    Const REMOVABLE     = 2
    Const LOCAL         = 3
    Const NETWORK       = 4
    Const CDROM         = 5
    Const RAMDISK       = 6
    Const PerfDataType  = 2
     
    Dim oArgs, oAPI, oBag, strServer, objWMIService, objItem, intUsedSpace, _
        intFreeSpace, intCapacity, blnDirtyVolume
     
    Set oAPI = CreateObject("MOM.ScriptAPI")
    Set oArgs = WScript.Arguments
     
    strServer = oArgs.Item(0)
     
    Set objWMIService = GetObject("winmgmts:\\" & strServer & "\root\CIMV2")
    SubCapacity objWMIService, strServer
    'SubFreeSpace objWMIService, strServer
    'SubUsedSpace objWMIService, strServer
    oAPI.ReturnItems
     
    Sub SubCapacity(objWMIService, strServer)
        Dim colDriveNames, objCapacity
        Set colDriveNames = objWMIService.ExecQuery( _
            "SELECT  * FROM Win32_LogicalDisk WHERE DriveType=" & LOCAL & _
            " AND DriveType<>" & CDROM,,48)
        For Each objCapacity In colDriveNames      
            If IsNull(objCapacity.Size) Or objCapacity.Size = "" Then
                'Do Nothing
            Else
                Set oBag = oAPI.CreateTypedPropertyBag(PerfDataType)
                oBag.AddValue "targetName", strServer
                oBag.AddValue "drive", objCapacity.DeviceID
                oBag.AddValue "driveCapacity", CDbl(ConvertByteToGB(objCapacity.Size))
                oAPI.AddItem(oBag)
            End If
        Next 
    End Sub
     
    Sub SubFreeSpace(objWMIService, strServer)
        Dim colDriveNames, objFreeSpace
        Set colDriveNames = objWMIService.ExecQuery( _
            "SELECT  * FROM Win32_LogicalDisk WHERE DriveType=" & LOCAL & _
            " AND DriveType<>" & CDROM,,48)
        For Each objFreeSpace In colDriveNames
            If IsNull(objFreeSpace.FreeSpace) Or objFreeSpace.FreeSpace = "" Then
                'Do Nothing
            Else
                Set oBag = oAPI.CreateTypedPropertyBag(PerfDataType)
                oBag.AddValue "targetName", strServer
                oBag.AddValue "drive", objFreeSpace.DeviceID
                oBag.AddValue "driveFreeSpace", CDbl(ConvertByteToGB(objFreeSpace.FreeSpace))
                oAPI.AddItem(oBag)
            End If
        Next    
    End Sub
     
    Sub SubUsedSpace(objWMIService, strServer)
        Dim colDriveNames, objUsedSpace
        Set colDriveNames = objWMIService.ExecQuery( _
            "SELECT  * FROM Win32_LogicalDisk WHERE DriveType=" & LOCAL & _
            " AND DriveType<>" & CDROM,,48)
        For Each objUsedSpace In colDriveNames
            If IsNull(objUsedSpace.Size) Or objUsedSpace.Size = "" Then
                'Do Nothing
            Else
                Set oBag = oAPI.CreateTypedPropertyBag(PerfDataType)
                oBag.AddValue "targetName", strServer
                oBag.AddValue "drive", objUsedSpace.DeviceID
                oBag.AddValue "driveUsedSpace", CDbl((ConvertByteToGB(objUsedSpace.Size)-ConvertByteToGB(objUsedSpace.FreeSpace)))
                oAPI.AddItem(oBag)
            End If
        Next
    End Sub
     
    Function ConvertByteToGB(sByteCount)
    	If IsNull(sByteCount) Then
    		ConvertByteToGB = "Not Available"
    		Exit Function
    	End If
    	ConvertByteToGB = sByteCount / 1073741824.0
    	ConvertByteToGB = CStr( Round(ConvertByteToGB, 1) )
    End Function

    In this particular version of the script, I used the subroutine to collect the total drive space for a logical drive as the calls to the other two are commented out. The script takes a single argument for the name of the computer so we also need to configure parameters in the rule that will collect the server name and pass it to the script. This is done by clicking the Parameters button on the Script tab of the rule. To get the name of the server we need to insert the path $Target/Property[Type="Windows1!Microsoft.Windows.Computer"]/PrincipalName$ for the principal name.

    In addition to simply collecting the data, we must create a counter for the object for which we are collecting the data. This is done via the Performance Mapper tab in the rule. There are four entries on the page that will make up the object used to store the data. For my rule, I used the following values which I will explain shortly:

    1. Object: DriveSpaceRpt
    2. Counter: TotalCapacity
    3. Instance: $Data/Property[@Name='drive']$
    4. Value: $Data/Property[@Name='driveCapacity']$

    The first value, Object, is the actual object that will be created to store the data. This will group all the similar data together to be used in reporting. For this example, all three rules will use the same value.

    The second value, Counter, is the name given to this specific counter. I could have called it anything, but it obviously makes sense to give it a name relative to the data being stored in this particular counter.

    The third value, Instance, is the name of the particular value item we are collecting; in this case a drive letter. Notice how the name drive in the [@Name='drive']$ section maps to the name we gave the data in the script for this subroutine in the line:
    oBag.AddValue “drive”, objCapacity.DeviceID.

    The fourth value, Value, is the actual collected data the will make up the results of the performance data collected. In this example, it is that actual value for the size of the drive we are currently running the script against. Again, note how the name driveCapacity in the [@Name='driveCapacity']$ section maps to the name we gave the data in the script for this subroutine as well as the previous example:
    oBag.AddValue “driveCapacity”, CDbl(ConvertByteToGB(objCapacity.Size)).

    The Performance Mapper tab should look like the following when complete:
    Performance Mapper

    We now want to go back to the Schedule tab and schedule how often this script will run. Since this particular data doesn’t need to be collected too often to be used in trending or for snapshot information, I chose once per day. Repeat the above steps two more times; once for each other logical drive data we are collecting; used space and remaining free space.

    Viewing the collected data…
    Once the scripts have run and we have collected some data, we move to the Monitoring space and create a View for it. This is done by right clicking on a the custom folder that was created from defining the unsealed custom management pack earlier, selecting New, then Performance View. In the properties of the new view, enter a title for the view. In the Criteria tab, select the target class underneath Show data related to…. We are targeting logical disks, but since we probably also have different versions of Windows in our environment, we will select Windows Computer. Next, click the check box next to with a specific object name. In the Criteria description field, click on the link for specific and change the value to DriveSpaceRpt since that is the name we gave as the object in the Performance Mapper. If you want to view historical data in your graph for trending, click on the Display tab and modify the historical day value appropriately.

    Select the newly created view and then the specific objects you wish to have represented in the graph. The each logical drive will have a representation for each of the three different instances collected upon. Hovering the mouse cursor over each line will give additional details as show below:
    Graph View

    While this is a nifty depiction of the specific data collected here, I also needed a way for different individuals to look up the numeric values of this data rather than guesstimate from a line graph. To facilitate this functionality, I created a simple custom report using a custom SQL query which I then published to a SharePoint portal. I’ll detail the steps to accomplish this using the same data demonstrated here in another post.


    Backup eXc Virtual Agent Config

    June 23rd, 2008

    I work in an environment that is over 90% virtualized on VMWare and to aid in monitoring that environment via OpsMgr 2007, I use Quest Management Xtensions (formerly eXc Virtual Agent). I have not yet had a chance to work with the recently released Operations Manager 2007 Cross Platform Extensions Beta. The Quest product is completely configurable (aside from the base framework) because everything is written in scripting language making calls to the VMWare and Linux kernels via WMI and SNMP and all the configuration files are stored in XML. The developers support custom changes to the script source code and even welcome submission of new ideas/techniques.

    While this makes the software very flexible, it also leaves room to mess things up which I have done a couple of times in the past while learning my way around. I also blew away my configs when I updated to the latest base framework a few months ago because I didn’t have the XML backed up. To prevent this in the future, I wrote a very simple, old-school backup process which captures the configuration files as well as the encrypted password files.

    This process runs on a central server that I use for automating and scheduling custom enterprise scripts and tasks. It consists of two simple files; a command batch script and a simple vbscript listed below. In addition, it requires that 7-zip be installed where the scripts will be run as it is used to compress the configuration files into a single archive.

    @echo off
    REM ======================================================================
    REM
    REM NAME: Backup_eXc_Config.cmd
    REM
    REM AUTHOR: Alan
    REM DATE  : 5/27/2008
    REM
    REM COMMENT: Backs up eXc config settings for XML and encrypted passwords.
    REM
    REM REQUIREMENTS:
    REM     1. 7-Zip must be installed to default location (www.7-Zip.com)
    REM     2. The DeleteFilesGT30Days.vbs script must be in same directory.
    REM ======================================================================
    
    REM SERVER01
    REM Get Date.
    set datestring=%date%
    
    REM Replace forward slashes with underscores.
    set datestring=SERVER01_%datestring:/=_%.zip
    
    REM Replace day with nothing so only date is left.
    set datestring=%datestring:Sun =%
    set datestring=%datestring:Mon =%
    set datestring=%datestring:Tue =%
    set datestring=%datestring:Wed =%
    set datestring=%datestring:Thu =%
    set datestring=%datestring:Fri =%
    set datestring=%datestring:Sat =%
    
    REM Change dir to 7-Zip and compress
    cd "C:\Program Files\7-Zip"
    7z.exe a -tzip "C:\Scripts\Batch\eXcBackup\"%datestring% "<a href="file://\\SERVER01\c$\Program">\\SERVER01\c$\Program</a> Files\eXc Software\WMI Providers\nonWindows\Virtual Agent Library\mom\VMWare" -r -x!*.log* -x!*.mdb -x!*.ldb -aoa
    7z.exe u "C:\Scripts\Batch\eXcBackup\"%datestring% "<a href="file://\\SERVER01\c$\Program">\\SERVER01\c$\Program</a> Files\eXc Software\WMI Providers\nonWindows\Encryption" *.txt
    
    REM Call script to delete old archives.
    cscript //nologo "C:\Scripts\Batch\eXcBackup\DeleteFilesGT30Days.vbs"
    '==========================================================================
    '
    ' NAME: DeleteFilesGT30Days.vbs
    '
    ' AUTHOR: Alan
    ' DATE  : 5/27/2008
    '
    ' COMMENT: Deletes .zip files in current directory older than 30 days.
    '
    '==========================================================================
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" _
        &amp; "{impersonationLevel=impersonate}!\\" &amp; _
            strComputer &amp; "\root\cimv2")
    Set colFiles = objWMIService.ExecQuery _
        ("Select * from CIM_DataFile where Path = '\\Scripts\\Batch\\eXcBackup\\'")
    For Each objFile in colFiles
        If InStr(objFile.Name, ".zip") Then
            Set objZipFile = objFSO.Getfile(objFile.Name)
            If objZipFile.DateCreated &lt; (Now - 30) Then
             objZipFile.Delete
         End If
        End If
    Next

    Starting off easy…

    June 19th, 2008

    I’ve never been much of a blogger but I have learned a lot from reading other technical blogs and felt it might be a good idea to give a little back. In addition, this just makes an easy way for me to post and upload things I’m working on for later referral. Anyway, hope some of the scripts, etc that I post will help some others. Off and running then…

    Let’s start it off with a simple management pack shall we? I am by no means an Operations Manager guru, but frustration does tend to fuel the creative fire, eh? After looking at many frustrating posts from others regarding Symantec’s utter disregard of the multiple requests for a OpsMgr 2007 MP for BackupExec coupled with the fact that I needed one; I took the rules I used from the MOM 2005 MP and created my own for OpsMgr 2007.

    While this works without issue in my environment, I will reiterate that I am not a MP genius and have only written a few custom MP’s with many customizations added to the sealed MP’s. Also, while this works great in my environment, I do not guarantee (nor do I support) results in your environment. Individual mileage will vary. Hope this gets some other frustrated SCOM admins a little relief as it did for me.

    BackupExecMP