So far in these blogs, I’ve not addressed one of the main focuses of Service Manager which is how to manage incidents. In Service Manager, incidents are more than simple instances, they’re what’s called a “projection”. Jakub has some great postings on projections (here and here), so I’m not going to go into detail about what a projection is, but rather how it affects PowerShell. The object model of the projection makes it a little tricky to work with from PowerShell, but can be done.
Here’s what the incident view looks like in the console.
That’s my target – create a script that has output similar to the console.
The script is constructed into two sections:
- The BEGIN section makes sure that the assemblies we need are loaded and creates functions that the script will use.
- The code in lines 20 to 50 make sure Microsoft.EnterpriseManagement.Core.dll is loaded and that we have a successful connection to the Data Access Service.
- The Get-SMIncident function does the actual work of retrieving the incident from the Data Access Service. It’s a little tricky because the Service Manager 2010 SDK uses generics, so we need a bit of reflection to invoke the method. This function also creates the criteria that we use to retrieve the incident. This way we filter on the server side rather than the client side which will be much faster if we have any reasonable number of incidents.
- The Get-AdaptedEMO function converts the EnterpriseManagementObject to something more idiomatic for PowerShell. I’ve mentioned this before, but since the actual interesting information is actually in the Values property of the EnterpriseManagementObject, this function creates a PSCustom object to which we add NoteProperties. This will help us later when we start formatting.
- This is done by adapting the main object of the projection (the object property on the projection) and the EnterpriseManagementObjects that represent the various relationships which is in line 166 of the script. It takes advantage of the fact that a projection object has an enumerator. Line 166 retrieves the keys which are then used in the foreach loop in 167-174 to retrieve each related object of the projection. That object is then adapted for PowerShell use and added as a property to the PSCustom object which represents the incident.
- Lines 176-188 promote some of the properties of the main object (the incident’s Object property) as well as some of the related objects properties so we can create the formatting we want more easily.
- Finally, the adapted incident is output (line 190)
|
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
#requires -version 2.0
# Get-Incident # Retrieve Service Manager Incidnents # The IncidentString may need to include a trailing ‘%’ # examples: # Get-Incident IR17% # Retrieves incidents that have a displayname which starts with ‘IR17′ [CmdletBinding(SupportsShouldProcess=$true)] param ( [Parameter(Position=0)][string]$IncidentString = "%", [Parameter()][String]$ComputerName = "localhost", [Parameter()]$Credential ) # Set up the enviroment # Create the connection to the ManagementGroup and use a # Create some variables that we need for our script # this function retrieves incidents from the Server. It uses reflection to try # this function takes an instance of an EnterpriseManagementObject and } # END BEGIN END # Construct an adapted object for the main object of the incident # for each one of the component parts of the incident, add an # Add some members to the adapted incident |
When we run the script, we provide an incident ID to reduce the amount of data returned from the Data Access Service.
PS> ./get-incident IR17%
Object : @{LastModified=1/28/2010 1:30:24 AM; LastModifiedBy=7431e155-3d9e-4724-895e-c03ba951a352; Leas
tDerivedNonAbstractManagementPackClassId=a604b942-4c7b-2fb2-28dc-61dc6f465c68; TargetResolutio
nTime=; Escalated=False; Source=IncidentSourceEnum.Console; Status=IncidentStatusEnum.Active;
ResolutionDescription=; NeedsKnowledgeArticle=False; TierQueue=; HasCreatedKnowledgeArticle=Fa
lse; LastModifiedSource=IncidentSourceEnum.Console; Classification=IncidentClassificationEnum.
Hardware; ResolutionCategory=; Priority=9; Impact=System.WorkItem.TroubleTicket.ImpactEnum.Hig
h; Urgency=System.WorkItem.TroubleTicket.UrgencyEnum.High; ClosedDate=; ResolvedDate=; Id=IR17
; Title=my computer is brokeked; Description=it don't work; ContactMethod=; CreatedDate=1/18/2
010 10:58:23 PM; ScheduledStartDate=; ScheduledEndDate=; ActualStartDate=; ActualEndDate=; Dis
playName=IR17 - my computer is brokeked}
AppliesToTroubleTicket : {@{LastModified=1/28/2010 1:02:44 AM; LastModifiedBy=7431e155-3d9e-4724-895e-c03ba951a352; Lea
stDerivedNonAbstractManagementPackClassId=dbb6a632-0a7e-cef8-1fc9-405d5cd4d911; ActionType=Sys
tem.WorkItem.ActionLogEnum.RecordReopened; Title=Action log from 01/27/2010 17:02:44; Descript
setStatus=; Notes=; DisplayName=Domain Admninistrator}}
. . .
RequestedWorkItem : {@{Id=642feed0-7e9a-b516-81cc-7f94be6bce91; LastModified=11/18/2009 5:30:17 PM; LastModifiedBy
=8bb08d83-64f1-4230-a8c9-e022beae2819; LeastDerivedNonAbstractManagementPackClassId=eca3c52a-f
273-5cdc-f165-3eb95a2b26cf; Domain=WOODGROVE; UserName=blesh; DistinguishedName=CN=Bruce Lesh,
CN=Users,DC=woodgrove,DC=com; SID=S-1-5-21-2548544548-3952215810-4123597018-1129; FQDN=woodgro
ve.com; UPN=blesh@woodgrove.com; FirstName=Bruce; Initials=; LastName=Lesh; Company=; Departme
nt=; Office=; Title=; EmployeeId=; StreetAddress=; City=; State=; Zip=; Country=; BusinessPhon
e=; BusinessPhone2=; HomePhone=; HomePhone2=; Fax=; Mobile=; Pager=; ObjectStatus=System.Confi
gItem.ObjectStatusEnum.Active; AssetStatus=; Notes=; DisplayName=Bruce Lesh}}
Id : IR17
Title : my computer is brokeked
Description : it don't work
DisplayName : IR17 - my computer is brokeked
Priority : 9
CreatedDate : 1/18/2010 10:58:23 PM
LastModified : 1/28/2010 1:30:24 AM
Status : Active
AssignedTo : Domain Admninistrator
AffectedUser : Bruce Lesh
These results look pretty bad, it’s difficult to see what’s really important and what isn’t. However we can create a table view which can mimic the view that we see in the console. Here’s the formatting does it.
. . .
<View>
<Name>IncidentView</Name>
<ViewSelectedBy>
<TypeName>EnterpriseManagementObjectProjection#System.WorkItem.Incident.ProjectionType</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize />
<TableHeaders>
<TableColumnHeader><Label>Id</Label></TableColumnHeader>
<TableColumnHeader><Label>Title</Label></TableColumnHeader>
<TableColumnHeader><Label>AssignedTo</Label></TableColumnHeader>
<TableColumnHeader><Label>Status</Label></TableColumnHeader>
<TableColumnHeader><Label>Priority</Label><Alignment>Right</Alignment></TableColumnHeader>
<TableColumnHeader><Label>AffectedUser</Label></TableColumnHeader>
<TableColumnHeader><Label>LastModified</Label></TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem><PropertyName>Id</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>Title</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>AssignedTo</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>Status</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>Priority</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>AffectedUser</PropertyName></TableColumnItem>
<TableColumnItem><PropertyName>LastModified</PropertyName></TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
. . .
update the format directives with update-formatdata, and voila!
PS> update-formatdata GetIncident.format.ps1xml PS> ./get-incident IR17% Id Title AssignedTo Status Priority AffectedUser LastModified -- ----- ---------- ------ -------- ------------ ------------ IR17 my computer is brokeked Domain Admninistrator Active 9 Bruce Lesh 1/28/2010 1:30:24 AM PS> ./get-incident IR% Id Title AssignedTo Status Priority AffectedUser LastModified -- ----- ---------- ------ -------- ------------ ------------ IR17 my computer is brokeked Domain Admninistrator Active 9 Bruce Lesh 1/28/2010 1:30:24 AM IR2 email is brokoken Domain Admninistrator Closed 9 Al Young 12/15/2009 11:41:57 PM IR13 more busted 2 Domain Admninistrator Closed 9 Carlos Garcia 1/28/2010 12:55:28 AM IR15 busted 3 Domain Admninistrator Closed 9 Greg Adams 1/5/2010 6:50:11 PM
that looks pretty good!