Getting data from Service Manager – a scripted approach   Leave a comment

In one of my earlier posts, I said that you needed some C# to get data from Service Manager because of the way some of our methods use generics. It was pointed out to me that I was wrong, wrong, wrong. So I thought I better post a completely scripted approach for retrieving data from Service Manager.

The following script will return all instances of the class that’s passed as a parameter.

param ( $classname )
$emg      = new-object microsoft.enterprisemanagement.enterprisemanagementgroup localhost
$class    = $emg.EntityTypes.GetClasses()|?{$_.name -eq $classname}
if ( ! $class )
{
    Write-Error "`nERROR: Class '$classname' not found, exiting."
    exit
}
$DEFAULT  = [Microsoft.EnterpriseManagement.Common.ObjectQueryOptions]::Default
$EMOT     = [Microsoft.EnterpriseManagement.Common.EnterpriseManagementObject]
# Retrieve the interface for EntityObjects, which we'll use when we create our generic method
$IMGMT    = $emg.EntityObjects.GetType()
# the types of the parameters, this is so we can find the right method
[type[]]$TYPES = [Microsoft.EnterpriseManagement.Configuration.ManagementPackClass],
                 [Microsoft.EnterpriseManagement.Common.ObjectQueryOptions]
# Retrieve the method
$ObjectReader = $IMGMT.GetMethod("GetObjectReader",$TYPES)
# Create a generic method
$GenericMethod = $ObjectReader.MakeGenericMethod($EMOT)
# Invoke the method with our arguments
[array]$arguments = [Microsoft.EnterpriseManagement.Configuration.ManagementPackClass]$class,$DEFAULT
$GenericMethod.invoke($emg.EntityObjects,$arguments) | %{
    # Create a custom object based on the original object
    $o = new-object psobject $_
    # elevate the properties in the Values collection to the top level
    $o.values|%{ $o | add-member -force NoteProperty $_.Type $_.Value }
    # assign a synthetic typename to the object, so we can use our formatting
    # more easily
    $name = $_.GetLeastDerivedNonAbstractClass().name
    $o.psobject.typenames.Insert(0, "EnterpriseManagementObject#$name")
    # now, emit the object!
    $o
    }

It uses reflection to retrieve the method that I want and then uses that to create a generic method, which can then be invoked with the parameters that I want.  In this case, it’s fairly straightforward, since I want to retrieve all instances of a particular class, I use the overload of GetObjectReader which takes a ManagementPackClass and then provide a default ObjectQueryOptions.

The last thing of interest is how I make the object more useful.  First by using each one of the Values property on EnterpriseManagementObject and creating a note property, it lets me see the “real” properties of the object (the ones on the Service Manager class).  By adding the name of the class to the TypeNames collection of the psobject, I can then use that with a formatting .ps1xml file so I can customize the output by the Service Manager class.

PS> get-smobject.ps1 microsoft.windows.computer|ft DisplayName,LastModified -au

DisplayName                   LastModified
-----------                   ------------
Computer2.woodgrove.com       8/14/2009 10:48:24 PM
Computer5.woodgrove.com       8/14/2009 10:48:24 PM
WIN-752HJBSX24M.woodgrove.com 8/13/2009 8:09:02 PM
Computer1.woodgrove.com       8/14/2009 10:48:24 PM
Computer4.woodgrove.com       8/14/2009 10:48:24 PM
Computer3.woodgrove.com       8/14/2009 10:48:24 PM
Advertisements

Posted August 17, 2009 by jtruher3 in ServiceManager

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: