This post is part of a series on Service Manager PowerShell. Be sure to check out the Overview Page for all posts in this series.
In the previous post, Creating Configuration Items, we saw how to create configuration items using the Service Manager PowerShell Cmdlets. Now, in this post, we are going to look into creating work items with these Cmdlets.
Creating Work Items using the Service Manager PowerShell Cmdlets is very similar to creating configuration items, with one major difference. When creating work items you have to deal with the work item Id. Since creating configurations items and work items are so similar, I am not going to cover the detailed steps of determining the properties and creating the hash table to input the values you want to use. If you need a refresher on these items please refer to the Creating Configuration Items post.
As I mentioned earlier, when creating work items there are certain considerations you need to take regarding the work item Id. If you look at the properties of any of the work item classes, you’ll see that Id is a key field. This means that it is a required field and cannot be changed after creation. So how do you know what the next available Id is? Luckily, you don’t have to. You can use the value of “{0}” which tells the system to use the next available number.
*Service Manager Note
If you look at your Incidents in the console, you may have noticed that the Ids are not always sequential. This is because the Ids are set on the Work Item level, and not the inherited classes, such as Incident and Service Request. Therefore, every time any work item is created the work item Id is incremented. For example, if you create an incident and the Id is IR120, next you create a Service Request its Id would be SR121, then you create another incident, it would be IR122.
So using what we know we can create an Incident by setting the Id field equal to {0}, but there is a catch. If you actually run this, it will create the incident, however it will not contain the incident class prefix. So instead of creating incident IR125 it will create incident 125. To prevent this you can simply add the IR prefix in front of the {0}. So your id property would be set to “IR{0}”. You can see this in the example below.
1234567891011121314151617 | # Get the Incident class$IRClass = get-scsmclass -name system.workitem.incident# Set the properties$Property = @{Id=”IR{0}” Title=”Test Incident” Description=”Test please ignore” Urgency=”System.WorkItem.TroubleTicket.UrgencyEnum.Medium” Source=”IncidentSourceEnum.Email” TierQueue=”IncidentTierQueuesEnum.Tier3″ Classification=”IncidentClassificationEnum.CIOverride” Impact=”System.WorkItem.TroubleTicket.ImpactEnum.Medium” Status=”IncidentStatusEnum.Active” }# Create the IncidentNew-SCSMClassInstance -Class $IRClass -Property $Property -PassThru |
As you know it is never good idea to hard code settings, like we just did with the Incident prefix. This is because different environments can have different prefixes. So to make your script truly portable and future proof, you should query the system to get the work item class’s prefix. To get the prefix for a specific class you need to get the class instances of the settings class. For the incident class the settings are in the class System.WorkItem.Incident.GeneralSetting. In the script below you can see the PrefixForId property being saved to the variable $prefix. The prefix variable is then added to the value for the Id property.
1234567891011121314151617181920 | # Get the Incident class$IRClass = get-scsmclass -name system.workitem.incident# Get the Incident class prefix$prefix = (Get-SCClassInstance -class (Get-SCClass -Name System.WorkItem.Incident.GeneralSetting)).PrefixForId# Set the properties$Property = @{Id=”$prefix{0}” Title=”Test Incident” Description=”Test please ignore” Urgency=”System.WorkItem.TroubleTicket.UrgencyEnum.Medium” Source=”IncidentSourceEnum.Email” TierQueue=”IncidentTierQueuesEnum.Tier3″ Classification=”IncidentClassificationEnum.CIOverride” Impact=”System.WorkItem.TroubleTicket.ImpactEnum.Medium” Status=”IncidentStatusEnum.Active” }# Create the IncidentNew-SCSMClassInstance -Class $IRClass -Property $Property -PassThru |
For your convenience, I have listed all the out-of-box work item class’s prefix settings below.
1234567891011121314151617181920212223242526272829303132 | # Activity Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityIdPrefix# Dependent Activity Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityDependentActivityIdPrefix# Manaual Acitivty Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityManualActivityIdPrefix# Parallel Activity Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityParallelActivityIdPrefix# Review Activity Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityReviewActivityIdPrefix# Squential Activity Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivitySequentialActivityIdPrefix# Incident Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.WorkItem.Incident.GeneralSetting)).PrefixForId# Change Request Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ChangeSettings)).SystemWorkItemChangeRequestIdPrefix# Problem Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ProblemSettings)).ProblemIdPrefix# Release Record Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ReleaseSettings)).SystemWorkItemReleaseRecordIdPrefix# Service Request Prefix(Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ServiceRequestSettings)).ServiceRequestPrefix |
Now we can take this, and what we learned in the Working with Relationships post, and add different relationships to the work items we created. In the example below we are taking the same incident creation script that we used above, but this time we are saving it to a variable, then adding an Affected User relationship to it.
1234567891011121314151617181920212223242526272829 | # Get the Incident class$IRClass = get-scsmclass -name system.workitem.incident# Get the Incident class prefix$prefix = (Get-SCClassInstance -class (Get-SCClass -Name System.WorkItem.Incident.GeneralSetting)).PrefixForId# Set the properties$Property = @{Id=”$prefix{0}” Title=”Test Incident” Description=”Test please ignore” Urgency=”System.WorkItem.TroubleTicket.UrgencyEnum.Medium” Source=”IncidentSourceEnum.Email” TierQueue=”IncidentTierQueuesEnum.Tier3″ Classification=”IncidentClassificationEnum.CIOverride” Impact=”System.WorkItem.TroubleTicket.ImpactEnum.Medium” Status=”IncidentStatusEnum.Active” }# Create the Incident$IR = New-SCSMClassInstance -Class $IRClass -Property $Property -PassThru# Get the Affected User Relationship$AffectedRel = get-scsmrelationship -Name ‘System.WorkItemAffectedUser’# Get the Affected User$AffectedUser = Get-SCSMClassInstance -class (Get-SCSMClass -name System.User) | ?{$_.UserName -eq “Your User name or variable”}# Created the relationship between the Incident and the Affected UserNew-SCRelationshipInstance -RelationshipClass $AffectedRel -Source $IR -Target $AffectedUser |
In this next example we are getting an existing Service Request. Then creating and relating a Manual Activity to it.
12345678910111213141516171819202122 | # Get the required classes$SRClass = Get-SCSMClass -name System.WorkItem.ServiceRequest$MAClass = Get-SCSMClass -name System.WorkItem.Activity.ManualActivity# Manaual Acitivty Prefix$MAPrefix = (Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityManualActivityIdPrefix# Get the Service Request$SR = Get-SCSMClassInstance -Class $SRClass | ?{$_.ID -eq “SR29”}# Get the Contains Activity relationship$ActivityRelationship = Get-SCRelationship -name System.WorkItemContainsActivity# Set the properties for the Manual Activity$MAProperty = @{ Id = “$MAPrefix{0}” SequenceId = 2 Title = “Test MA” }# Create the Manaual Activity and Relate it to the Service RequestNew-SCRelationshipInstance -RelationshipClass $ActivityRelationship -Source $SR -TargetClass $MAClass -TargetProperty $MAProperty -PassThru |
*Service Manager Note
You may have noticed the SequenceId property in the example above. The Sequence Id determines the order in which the activities are set in the parent work item, starting with 0. You will want to make sure that you are adding your activities in the appropriate order using this property. Therefore, if we want to add the new activity we need to know where to place it. To help with this I have written a function that can be used to add an activity anywhere in a parent work item.
All you need to do is pass the work item’s Id, then specify if you want your activity to be first, last, or in a specific position. If you use the First switch, it will increment every activity SequenceId, then return 0 for you to use as your SequenceId. If you use the Last switch, then it will simply return the next available SequenceId. If you use the SequenceId switch you will need to specify what position you want. Remember the first one starts at 0. The function will increment every activity greater than and equal to the one you specified, and return the SequenceId you entered. Then all you need to do is set this returned variable as the SequenceId property in your script. The example below uses the same script we used to earlier to create the manual activity, but this time we are going to specify that it goes in SequenceId 3.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 | $ID = “SR29″Function Sequence-Activities{ param ( [Parameter(Mandatory=$True,Position=1)] [string]$Id, [parameter(Mandatory=$True,ParameterSetName=”set1″)] [int]$SequenceId, [parameter(Mandatory=$True,ParameterSetName=”set2″)] [System.Management.Automation.SwitchParameter]$First, [parameter(Mandatory=$True,ParameterSetName=”set3”)] [System.Management.Automation.SwitchParameter]$Last ) # Get the Work Item $WI = Get-SCSMClassInstance -Class $SRClass | ?{$_.ID -eq $Id} # Get the Contains Activity relationship $ActivityRelationship = Get-SCRelationship -name System.WorkItemContainsActivity # Get Related Activities $Activities = $WI.GetRelatedObjectsWhereSource($ActivityRelationship.ID).EnterpriseManagementObject.Id.Guid if($Activities) { If($First) { # Increment all existing activities by 1 and return 0 Get-SCClassInstance -id $Activities | %{$_.SequenceId=$($_.SequenceId+1);$_} | Update-SCClassInstance Return 0 } elseif($Last) { # Get the last SequenceId and increment it $SequenceId = (Get-SCClassInstance -id $Activities | sort SequenceId | select -Last 1).SequenceId $SequenceId++ Return $SequenceId } else { Get-SCClassInstance -id $Activities | ?{$_.SequenceId -ge $SequenceId} | %{$_.SequenceId=$($_.SequenceId+1);$_} | Update-SCClassInstance Return $SequenceId } } else { Return 0 }}# Get the Sequence Id$SequenceId = Sequence-Activities -Id $Id -SequenceId 3# Get the required classes$SRClass = Get-SCSMClass -name System.WorkItem.ServiceRequest$MAClass = Get-SCSMClass -name System.WorkItem.Activity.ManualActivity# Manaual Acitivty Prefix$MAPrefix = (Get-SCClassInstance -class (Get-SCClass -Name System.GlobalSetting.ActivitySettings)).SystemWorkItemActivityManualActivityIdPrefix# Get the Service Request$SR = Get-SCSMClassInstance -Class $SRClass | ?{$_.ID -eq $ID}# Get the Contains Activity relationship$ActivityRelationship = Get-SCRelationship -name System.WorkItemContainsActivity# Set the properties for the Manual Activity$MAProperty = @{ Id = “$MAPrefix{0}” SequenceId = $SequenceId Title = “Test MA with Function postion 3” }# Create the Manaual Activity and Relate it to the Service RequestNew-SCRelationshipInstance -RelationshipClass $ActivityRelationship -Source $SR -TargetClass $MAClass -TargetProperty $MAProperty -PassThru |
In this post you have seen how to create work items using the Service Manager PowerShell. Be sure to check the Overview Post for more content in this series.