I’ve written a number of fairly complicated scripts for Service Manager over the last few months, and while talking to a team-mate about something he wanted to do, it looked like it was just 1-line PowerShell script. That got me thinking about what other things in Service Manager could be handled by a really simple (say less than 5 lines) of PowerShell. The list is good sized, so I thought it would be good if I shared them.
The problem we had at hand was how I could help one our development partners figure out in which management pack a particular class resides. It turns out it was 3 lines of script to find out.
PS> [reflection.assembly]::LoadWithPartialName("Microsoft.EnterpriseManagement.Core") GAC Version Location --- ------- -------- True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.EnterpriseManagement.Core\7.0.5000.0__31bf3856ad364e35\... PS> $EMG = new-object Microsoft.EnterpriseManagement.EnterpriseManagementGroup localhost PS> $EMG.EntityTypes.GetClasses()|ft name,{$_.GetManagementPack().Name} Name $_.GetManagementPack().Name ---- --------------------------- System.Entity System.Library System.Collections System.Library System.ConfigItem System.Library System.LogicalEntity System.Library . . .
the business end of the script is just the last line. The first two lines are just what I need to get access to the Service Manager Data Access Service. I do this so much that put those two lines in my $profile.
After that, it’s just a matter of adding a filter to find out the actual class of interest.
PS> $EMG.EntityTypes.GetClasses()|?{$_.name -match "System.Knowledge.Article"}|ft name,{$_.GetManagementPack().Name}
Name $_.GetManagementPack().Name
---- ---------------------------
System.Knowledge.Article System.Knowledge.Library
Now, the label for the second column may not pretty, but I’m not fussed about that, I’ve got the data that I need. The next thing I needed to figure out was the properties of this class. That’s another one liner:
PS> $emg.entitytypes.GetClasses()|?{$_.name -match "System.Knowledge.Article"}|
>> select -expand propertycollection|ft name,key,type -au
>>
Name Key Type
---- --- ----
ArticleType False enum
ArticleTemplate False string
ArticleOwner False string
Category False enum
Comments False string
CreatedDate False datetime
CreatedBy False string
PrimaryLocaleID False int
Status False enum
Tag False enum
VendorArticleID False string
Title False string
Abstract False string
Keywords False string
ArticleId True string
EndUserContent False binary
AnalystContent False binary
ExternalURLSource False string
ExternalURL False string
(ok, so it’s a long line, but it’s still a single pipeline)
This doesn’t quite tell the whole story, because if I wanted to create one of these classes, I may have more properties available to me (based on the base classes for the class I want). That’s just *2* lines:
PS> $class = $emg.entitytypes.GetClasses()|?{$_.name -match "System.Knowledge.Article"}
PS> (new-object microsoft.enterprisemanagement.common.CreatableEnterpriseManagementObject $emg,$class).GetProperties()|
>> ft name,key,type -au
>>
Name Key Type
---- --- ----
ArticleType False enum
ArticleTemplate False string
ArticleOwner False string
Category False enum
Comments False string
CreatedDate False datetime
CreatedBy False string
PrimaryLocaleID False int
Status False enum
Tag False enum
VendorArticleID False string
Title False string
Abstract False string
Keywords False string
ArticleId True string
EndUserContent False binary
AnalystContent False binary
ExternalURLSource False string
ExternalURL False string
ObjectStatus False enum
AssetStatus False enum
Notes False richtext
DisplayName False string
I save the class and then use it to create the object I want with new-object.
Sometimes, I need to know which management pack an enumeration is in. Another 1 liner:
PS> $emg.EntityTypes.GetEnumerations()|?{$_.name -match "high"}|ft name,{$_.getmanagementpack().name} -au
Name $_.getmanagementpack().name
---- ---------------------------
System.WorkItem.TroubleTicket.ImpactEnum.High System.WorkItem.Library
System.WorkItem.TroubleTicket.UrgencyEnum.High System.WorkItem.Library
System.ServiceManagement.ServicePriority.High ServiceManager.ServiceMaps.Configuration
IncidentResolutionCategoryEnum.FixedByHigherTierSupport ServiceManager.IncidentManagement.Configuration
ChangePriorityEnum.High ServiceManager.ChangeManagement.Configuration
ChangeRiskEnum.High ServiceManager.ChangeManagement.Configuration
ActivityPriorityEnum.High ServiceManager.ActivityManagement.Configuration
One of my early examples for retrieving management packs. That’s a 1 liner:
PS> $emg.ManagementPacks.GetManagementPacks()|ft Sealed,Version,Name Sealed Version Name ------ ------- ---- False 7.0.5228.0 Microsoft.SystemCenter.ServiceManager.Connector.Configuration True 7.0.5228.0 Microsoft.SystemCenter.Internal True 7.0.5228.0 ServiceManager.Reporting.Help True 7.0.5228.0 Microsoft.SystemCenter.Report.Library True 7.0.5228.0 ServiceManager.LinkingFramework.Library True 7.0.5228.0 System.ApplicationLog.Library True 7.0.5228.0 ServiceManager.IncidentManagement.Library.Datawarehouse True 7.0.5228.0 Microsoft.EnterpriseManagement.ServiceManager.UI.Console True 7.0.5228.0 ServiceManager.ActivityManagement.Library.Datawarehouse True 7.0.5228.0 ServiceManager.ChangeManagement.Library True 7.0.5228.0 ServiceManager.IncidentManagement.Report.Library True 7.0.5228.0 ServiceManager.ChangeManagement.Report.Library . . .
What if I wanted to remove a management pack? Before I do, I had better find out whether it’s possible, as if other Management Packs depend on the one I want to remove. So I need to find the dependent management packs - 2 lines!
PS> $crLib = $emg.ManagementPacks.GetManagementPacks()|?{$_.name -eq "System.WorkItem.ChangeRequest.Library"}
PS> $emg.ManagementPacks.GetDependentManagementPacks($crLib)|ft sealed,version,name -au
Sealed Version Name
------ ------- ----
True 7.0.5228.0 ServiceManager.ActivityManagement.Library.Datawarehouse
True 7.0.5228.0 ServiceManager.ChangeManagement.Library
True 7.0.5228.0 ServiceManager.ChangeManagement.Report.Library
True 7.0.5228.0 ServiceManager.ServiceMaps.Library
True 7.0.5228.0 ServiceManager.ChangeManagement.Library.Datawarehouse
False 7.0.5228.0 ServiceManager.ConfigurationManagement.Configuration
True 7.0.5228.0 ServiceManager.ChangeManagement.Help
True 7.0.5228.0 Microsoft.SystemCenter.ServiceManager.Portal
False 7.0.5228.0 ServiceManager.ChangeManagement.Configuration
In this case, I won’t be able to remove the ChangeRequest Library, because of all the dependencies, but if I have a management pack that is not needed by other management packs, removing the management pack is another one-liner:
PS> $emg.ManagementPacks.GetManagementPacks()|?{$_.name -eq "MPToRemove"}|
>> %{ $emg.ManagementPacks.UninstallManagementPack($_) }
>>
Perhaps I want to find out how much localization I need to do. To understand how much work I will need to do, I should find out how many lines of text I need to localize. How do I find out how many different English display strings are stored in my management packs? 1 line!
PS> ($emg.LanguagePacks.getlanguagepacks()|?{$_.name -eq "ENU"}|select-object -Expand DisplayStringCollection).count
6456
and if I wanted to know the count of my display strings for each language? 1 line!
PS> $emg.LanguagePacks.getlanguagepacks()|select-object -ExpandProperty DisplayStringCollection | >> Group-Object LanguageCode|format-table Count,Name -au >> Count Name ----- ---- 6456 ENU 6455 DEU 6282 JPN
and what if I wanted to see the actual English display strings from the System.Library management pack? Just another line!
PS> $emg.LanguagePacks.GetLanguagePacks()|?{$_.Name -eq "ENU" -and $_.GetManagementPack().Name -eq "System.Library"}|
>> Select-Object -Expand DisplayStringCollection|ft name,description
>>
Name Description
---- -----------
Display Name Display name
Timeout Seconds
Database Defines the basic properties of databases
Local Application Defines the basic properties of applications that are di...
Reference Defines the basic properties of directed relationships
. . .
yow!

