More with management packs

Last post, I wrote about retrieving management packs from Service Manager and I don’t really have a lot more to say about retrieving the management pack information, except for provide a way where we don’t have to specify formatting.   Generally, I want to see whether the management pack is sealed, the version number and then name, which translates into using format-table like this:

format-table Sealed,Version,Name -autosize

I’ll create a ServiceManager.Format.ps1xml file which will format the default view of management packs.

<configuration>
 <viewdefinitions>
  <view>
   <name>ManagementPackView</name>
   <viewselectedby>
    <typename>Microsoft.EnterpriseManagement.Configuration.ManagementPack</typename>
   </viewselectedby>
   <tablecontrol>
    <autosize />
    <tableheaders>
     <tablecolumnheader>
      <label>Sealed</label>
     </tablecolumnheader>
     <tablecolumnheader>
      <label>Version</label>
     </tablecolumnheader>
     <tablecolumnheader>
      <label>Name</label>
     </tablecolumnheader>
    </tableheaders>
    <tablerowentries>
     <tablerowentry>
      <tablecolumnitems>
       <tablecolumnitem>
        <propertyname>Sealed</propertyname>
       </tablecolumnitem>
       <tablecolumnitem>
        <propertyname>Version</propertyname>
       </tablecolumnitem>
       <tablecolumnitem>
        <propertyname>Name</propertyname>
       </tablecolumnitem>
      </tablecolumnitems>
     </tablerowentry>
    </tablerowentries>
   </tablecontrol>
  </view>
 </viewdefinitions>
</configuration>

In order to add this to my environment, all I need to do is use the Update-FormatData cmdlet using the filename as an argument.  After that, retrieving management packs will be be in the format that I want.

PS> $MGroup.ManagementPacks.GetManagementPacks()

Sealed Version    Name
------ -------    ----
True   7.0.3683.0 ServiceManager.ServiceMaps.Library
True   7.0.3683.0 Microsoft.SystemCenter.InstanceGroup.Library
...
False  7.0.3683.0 ServiceManager.OpsMgrConnector.Configuration

So less typing for me, yay! 

For even less typing, I’ll create a script called Get-ManagementPack which creates a connection to Service Manager and retrieves the management packs.

here’s the script:

PS> get-content Get-ManagementPack.ps1
param ( $computerName = "localhost" )
$SMDIR = "C:\Program Files\Microsoft System Center\Service Manager 2010"
$COREDLL = "${SMDIR}/SDK Binaries/Microsoft.EnterpriseManagement.Core.dll"
[reflection.assembly]::LoadFile($COREDLL) | out-null
$MGroup = new-object Microsoft.EnterpriseManagement.EnterpriseManagementGroup $computerName
$MGroup.ManagementPacks.GetManagementPacks()

and to run:

PS> Get-ManagementPack

Sealed Version    Name
------ -------    ----
True   7.0.3683.0 ServiceManager.ServiceMaps.Library
True   7.0.3683.0 Microsoft.SystemCenter.InstanceGroup.Library
...
False  7.0.3683.0 ServiceManager.OpsMgrConnector.Configuration

Now we have a simple script and default formatting.  But we’re not done with management packs – if I want to see the contents of a management pack, I can do that via a process called "exporting".  Exporting a management pack lets me create an XML file of the management pack which I can then inspect the various elements of the management pack so I can see what it does (and how it does it).  An object exists for just the purpose of exporting management packs – Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter and using the WriteManagementPack method, I can easily create the XML files.

This is perfect for a foreach pipeline, so for each management pack that I retrieve, I’ll create an XML file of the management pack contents.

PS> Get-ManagementPack | %{
>> $xmlWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter C:\temp 
>> } { 
>> $xmlWriter.WriteManagementPack($_) 
>> }

The first script block in the foreach command creates me an xmlWriter which will used for all the management pack objects that are passed from Get-ManagementPack.   The ManagementPackXmlWriter object has two constructors.  The constructor that I’m using takes a string which points to a directory which will contain the exported xml files.  When invoked, the method returns a string which is the fullname of the exported XML file, so when I execute it, I see the following (ellipses used to save space):

C:\temp\ServiceManager.ServiceMaps.Library.xml
C:\temp\Microsoft.SystemCenter.InstanceGroup.Library.xml
...
C:\temp\ServiceManager.OpsMgrConnector.Configuration.xml

I can easily incorporate this into a script as well:

PS> Get-Content Export-ManagementPack.ps1
param ( $targetDirectory = $( throw "Need a target directory"), [switch]$verbose )
begin {
  if ( $verbose )
  {
    $verbosePreference = "Continue"
  }
  $xmlWriter = new-object Microsoft.EnterpriseManagement.Configuration.IO.ManagementPackXmlWriter $targetDirectory
}
process {
  if ( $_ -is "Microsoft.EnterpriseManagement.Configuration.ManagementPack" )
  {
    $path = $xmlWriter.WriteManagementPack($_)
    if ( $verbose )
    {
      Write-Verbose "Exporting: $path"
    }
  }
  else
  {
    Write-Error "$_ is not a management pack"
  }
}

I’ve also added support for -verbose so I can see what’s being exported if I want, along with just a little checking to be sure that I’ve actually got a management pack.

Now I can run the following:

PS> Get-ManagementPack | Export-ManagementPack C:\temp

or

PS> Get-ManagementPack | Export-ManagementPack C:\temp -verbose

 MPBlog2

and export all my management packs in one simple step.   Next time I’ll discuss importing management packs.