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 posts we saw how to return Work and Configuration Item information. Now in this post, I am going to demonstrate how you can update Work and Configuration Items using the Service Manager PowerShell cmdlets. Just like in the previous posts, Service Manager uses a single cmdlet to update work and configuration items. The cmdlet we will use is Update-SCSMClassInstance.
Using Update-SCSMClassInstance
Unlike the Get-SCSMClassInstance cmdlet, the Update-SCSMClassInstance cmdlet only has a few parameters to choose from. They are Instance, PassThru, Confirm, and WhatIf. Instance allows you to specify an instance of a class to update. This would be an instance that you returned using the Get-SCSMClassInstance. As you’ll see shortly, this parameter is not often used. PassThru, tells the command to pass your results through to a variable or output. Again more on this shortly.
The other two parameters are useful for development and testing. Confirm will pause your script and prompt you to confirm prior to each change being made. WhatIf will output what would happen during execution, but does not actually commit any changes.
If you look at the documentation for the Update-SCSMClassInstance cmdlet, you’ll see that the Instance parameter accepts pipeline inputs. This means that we can use the Get-SCSMClassInstance cmdlet to get the instance to change, then pipe in the changes in the same line. As you’ll see in the example below, the syntax for this will be “Your SCSM Class Instance” | “values to change” | Update-SCSMClassInstance.
12 | $SR = Get-SCSMClassInstance -Class (Get-SCSMClass -Name System.WorkItem.ServiceRequest) | ? {$_.ID -eq “SR4″}$SR | %{$_.title=”SCSM PowerShell Demo”;$_} | Update-SCSMClassInstance |
The example above demonstrates how to update the title of a service request. This could be done on one line, but to make things more readable I’ve broken it down. The first line gets the class instance of the service request, and saves it to the variable $SR. Then $SR is loaded, then a pipe, followed by a foreach statement, which is represented here by a percent sign. This foreach statement is where you specify what value to change, and what to change it to. You can specify multiple values to change at once, by separating them with a semi-colon. At the end a simple $_ is added to tell it to keep everything else the same. Then finally another pipe followed by the Update-SCSMClassInstance cmdlet.
Updating Multiple Items
The previous example showed how to update the title of a single request, but what do you do if you want to change multiple requests at once? The answer to that is simple. You do the same exact thing. In the example below we are returning every incident with the word Test in its title. Then it will set it status to resolved, and add “resolved by script” to the description.
12 | $IR = Get-SCSMClassInstance -Class (Get-SCSMClass -Name System.WorkItem.Incident) | ?{$_.title -like “*Test*”} $IR | %{$_.Status=”IncidentStatusEnum.Resolved”;$_.Description=$($_.Description + ” resolved by script”);$_} | Update-SCSMClassInstance |
There are a few things you will want to make note of in the example above. First, it uses the internal name for setting the status. As we covered in the previous posts, you always want to use the internal name of a list item because display names are not always unique. You will also want to note the variable setting for the description. In this case we wanted to append “resolved by script” to the existing description. If you just set it to “resolved by script”, it would override the existing description with just that. However, the example above takes the existing description, adds the new text to the end, and sets that as the new description value in the incident.
Complex Updates
The great thing about the Update-SCSMClassInstance cmdlet is, no matter what you are updating the underlying syntax stays the same. The format for updating an Incident, is the same as it would be when updating a computer or user object. With a little PowerShell know how you can perform some really time consuming tasks in a matter of seconds.
Take for instance the next example. It shows how you can use the Update-SCSMClassInstance cmdlet in conjunction with some foreach and if statements to perform different updates based on the item. In this example, all user account objects are returned. Then using a foreach statement each object is parsed individually. If the user’s username ends with “_svc”, then write Service to the first name, and Account to the last name. Else if the account does not have a last name, then write the username to the first name and Unknown to the last name field. Also, this example is using the WhatIf parameter so that I can test and see what objects will get updated, before actually performing the update.
12345678910111213 | $Users = Get-SCSMClassInstance -Class (Get-SCSMClass -name Microsoft.AD.User)Foreach($User in $Users){ if($User.UserName -like “*_svc”) { $User | %{$_.FirstName=”Service”;$_.LastName=”Account”;$_} | Update-SCSMClassInstance -WhatIf } elseif(!$User.LastName) { $User | %{$_.FirstName=[string]$_.username;$_.LastName=”Unknown”;$_} | Update-SCSMClassInstance -WhatIf }} |
*PowerShell Tip – You may have noticed in the script above that I put [string] prior to the username variable. This is to force the variable to be a string type, which is what the FirstName field will accept. It is a good habit to ensure that you are inputting the correct type. If not, you may receive a message stating “Simple object value was not the proper type”. When you see this, you need to check to make sure that the value you are updating is using the correct type. You can determine the type of value required, by examining the property collection of the class and its base classes. I’ve included a script below that you can run against a class to return all of its properties, and the type of value they require.
1234567 | $class = Get-SCSMClass -name Microsoft.AD.User$properties = @()foreach ($item in @($Class) + @($Class.GetBaseTypes())) { $properties += $item.PropertyCollection}$properties | FT Name, Type -au |
In this post you have seen how to update objects in SCSM using the Update-SCSMClassInstance cmdlet. Be sure to check the Overview Post for more content in this series.