Archive for Service Manager

A few months back I was part of creating a new course for the Microsoft Virtual Academy which is an introduction course for Service Manager. My contribution to the course was to present the “Automated Service Manager-” and “Extending Service Manager” modules when we did the recording in Las Vegas during MMS. I had a great time presenting and I hope you guys will have good use of the content!

The topics for the “System Center 2012 Service Manager: Planning, Deploying, Managing” course are:

  1. Architecture & Design
  2. Connectors
  3. Incident Management
  4. Problem Management
  5. Knowledge Management
  6. Automated Service Manager
  7. Extending Service Manager
  8. Change Management
  9. Release Management
  10. Service Requests
  11. Reporting & Data Warehouse

Go take the free course at: http://j.mp/scsm-mva

Categories : Service Manager
Comments (0)

If you like me upgraded your Lync client to 2013 a while back and started to run into annoying freezes in the Service Manager console read this!

If you have a Lync client installed Service Manager provides some integration with Lync to show status of a user and provide a way of initiating e.g. an IM session with the affected user of an incident. Since installing Lync 2013 several people have reported that the Service Manager console started to freeze on opening a form where there was a user declared (Affected User, Primary User etc.). Seems like the problem only occurred if the old Lync client was left uninstalled!! So, if you’re experiencing freezes like the one described above, make sure you uninstall the old Lync client and give it a go. Hopefully this helps!

Categories : Service Manager
Comments (0)
Oct
25

SendEmail for Service Requests

Posted by: | Comments (2)

From time to time I see questions regarding the use of “SendEmail” with Service Requests. For those not familiar with SendEmail it’s a console task for Service Manager that can be used by an analyst to send emails to other users regarding an incident. A common usage scenario is to request additional information from the affected user of an incident. In combination with the Exchange Connector this results in a really nice solution that documents the communication between the two parties in the action log of the incident.

Since the original version of SendEmail (part of the Exchange Connector download that can be found here) didn’t support usage with Service Requests I’ve now created a dialect of the solution that’s made for usage with Service Requests.

image

image

You can find the solution at the TechNet Gallery here: TechNet Gallery – SendEmail for Service Request Fulfillment

If you like the solution please rate it at the Gallery!

Oct
06

“Quick Create Incident”

Posted by: | Comments (5)

A couple of weeks ago one of my customers were asking if it was possible to get a console task that was bound to a specific incident template. They wanted to avoid the step where they have to go search/browse for the template in the “Template Picker” when creating a new incident. I came to think about the “Incident Quick Templates” solution which gives you a “fly-out-menu” of templates when you need to apply a frequently used template on an existing incident, but that solution can’t be used to create new incidents. So I went ahead and created a custom console task that solves the problem. Here it is, my “Quick Create Incident” console task.

image

The solution allows you to specify any number of templates you want to be able to pick from a “fly-out-menu” when creating a new incident.

Download: TechNet Gallery: Quick Create Incident

Setting up the solution

To be able to use your preferred templates in the “fly-out-menu” you need to know the internal Id of the templates you want to use.

Locate a Template ID

To locate the ID of a template, follow these steps:

  1. Start the “Service Manager Shell” (within the Service Manager Console go to AdministrationStart PowerShell Session)
  2. Use the following command to locate the ID of a template (replace “incident” with any word that is part of the display name of the template you’re looking for, *=wildcard)

Get-SCSMObjectTemplate -DisplayName *Incident*|ft DisplayName,Id

  1. Make a note of the Id  for the templates you want to have access to in the “fly-out-menu”
Wiring up your templates to the “fly-out-menu”

To add menu items (which are actually separate console tasks) wired to your templates, download the solution from here: TechNet Gallery: Quick Create Incident . Extract the zip archive to “C:\Temp\QuickCreateIncident”. Now, to define which templates you want to have access to in the “fly-out-menu”, open “C:\Temp\QuickCreateIncident\Litware.IncidentManagement.QuickCreate.Library.xml” in your favorite XML editor.

In the management pack I’ve wired-up two templates as examples to the “fly-out-menu”, the “Hardware Incident Template” and the “Network Incident Template”. Each of these menu items are defined as a <ConsoleTask> in the MP, see example below.

<ConsoleTask ID="Litware.Incident.QuickCreate.Network.Task" Accessibility="Public" Enabled="true" Target="Litware.Incident.QuickCreate.GroupTask" RequireOutput="false">
        <Assembly>EnterpriseManagement!SdkDataAccessAssembly</Assembly>
        <Handler>Microsoft.EnterpriseManagement.UI.SdkDataAccess.ConsoleTaskHandler</Handler>
        <Parameters>
          <Argument Name="Assembly">Litware.SCSM.QuickCreate</Argument>
          <Argument Name="Type">Litware.SCSM.QuickCreate.TaskHandlers.QuickCreateIncidentCommand</Argument>
          <Argument Name="TemplateId">4cf10508-c474-94fd-55df-28cb7a6f3fb3</Argument>
        </Parameters>
      </ConsoleTask>

Each menu item is actually defined as separate Console Tasks that has the same Target, which is a parent Console Task. There are three important things to notice in the example above:

  • The Console Task ID needs to be unique
  • The Target needs to be Litware.Incident.QuickCreate.GroupTask
  • The TemplateID is the reference used to define which template that will be used to create the new incident
To add your own menu items
  1. Copy the XML for one of the example <ConsoleTasks> (“Network” or “Hardware”)
  2. Give the new Console Task a new Console Task ID (which is uniqe)
  3. Change the TemplateId value to the Id the template you want to use (that you located using the Get-SCSMObjectTemplate command earlier)
Setting the display name of a menu item

To add a display name of a console task, follow these steps.

  1. Locate the Console Task ID for which Console Task you want to set the display name
  2. Make sure there is a <DisplayString> defined, as below, where the Console Task ID matches the ElementID

<LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        …
        <DisplayString ElementID="Litware.Incident.QuickCreate.Network.Task">
            <Name>Network Incident</Name>
            <Description />
        </DisplayString>
        …
      </DisplayStrings>
</LanguagePack>

  1. The value of the <Name> tag will be the name shown in the Service Manager console

Note: In the example above we’ve added/updated the English display string. To add display strings for other languages. See the following blog post: Localizing Management Pack Content. Also, if you delete a console task, make sure you delete the <DisplayString> as well since you will not be able to import the MP if it contains display strings that refers to deleted elements.

Setting the icon of a menu item

To specify an icon for a menu item, in the <ImageReferences> section, add a line as the example below but make sure the ElementID matches the Console Task ID of your Console Task (menu item) that you want to set the icon for.

<ImageReference ElementID="Litware.Incident.QuickCreate.Network.Task" ImageID="SMIncident!IncidentMgmt_CreateIncidentFromTemplate_16" />

Finalizing

To be able to use the custom Console Task you need to bundle the provided assembly file with Management Pack. Before doing this though, you should seal the Management Pack (otherwise an annoying confirmation dialog will show up each time you click one of the menu items).

  1. Start the “Service Manager Shell”, within the Service Manager Console go to AdministrationStart PowerShell Session)
  2. Execute the following command:

cd C:\Temp\QuickCreateIncident

  1. Execute the following command to Seal the Management Pack:

Protect-SCManagementPack  -ManagementPackFile .\Litware.IncidentManagement.QuickCreate.Library.xml -KeyFilePath .\QuickCreateKey.snk -CompanyName Litware -OutputDirectory ./

  1. Execute the following command to bundle the sealed Management Pack with the assembly containing the custom Console Task:

New-SCManagementPackBundle -ManagementPack .\Litware.IncidentManagement.QuickCreate.Library.mp -Name Litware.IncidentManagement.QuickCreate.Library.mpb -Resource .\Litware.SCSM.QuickCreate.dll

  1. Finally, import the Management Pack Bundle using the console or using the following command:

Import-SCSMManagementPack .\Litware.IncidentManagement.QuickCreate.Library.mpb

You’re done! If you like the solution rate it at the gallery: TechNet Gallery: Quick Create Incident

Note: The example menu items “Hardware Incident” and the “Network Incident” are bound to out-of-the-box templates. If you’ve deleted the templates these examples are refering to since installing Service Manager these examples will not work and should be deleted. If you decide to delete them (the ConsoleTask elements), remember to delete all elements refering to them as well (display strings and image references).

A while back I created some “custom form templates” to be used with the Service Manager Authoring Tool (2010). The purpose was to enable “authors” to re-use some of the existing controls in Service Manager like the “Related Items Tab” and the “History Tab” when creating new forms in the Authoring Tool. By request I’ve updated these to support Service Manager 2012. So far I’ve just added two templates that contain the “Related Items Tab” and the “History Tab”. One template is for Work Items and one is for Configuration Items.

SNAGHTMLc125cb

If you just want to try the templates out you can go ahead and download this example bundle: Litware.SCSM.FormsExample.mpb. After importing it you can use any of the following two views to try out the forms using the Create MyWorkItem or Create MyConfigItem task:

  • Work Items > My Work Items > All My Work Items
  • Configuration Items > My Config Items > All My Config Items

To learn how to use the custom templates in the Service Manager Authoring Tool let’s create two simple classes and a form for each of them (based on the templates).

Creating the Example Manangement Pack

  1. Create a folder called C:\Temp\MyCustomForms
  2. Copy Litware.SCSM.CustomFormTemplates.dll to C:\Temp\MyCustomForms
  3. Start the Service Manager Authoring Tool
  4. Create a new Management Pack called “Litware.SCSM.FormsExample.xml” in “C:\Temp\MyCustomForms

Creating a custom Configuration Item class

  1. Right click Classes and select “Create Configuration Item Class…
    image
  2. In the Create Class dialog, name the class “MyConfigItem” and click Create.
  3. Add a new property by clicking “Create Property…”, name the property “PrincipalName”.
  4. While having the new property selected, mark it as Key in the Details pane.
    image
  5. Delete the property that was automatically added (called something like Property_…) when you created the class.
    image
  6. In the confirmation dialog, click yes to delete the property.

Creating a custom Work Item class

  1. Right click Classes and select “Create Work Item Class…
  2. In the Create Class dialog, name the class “MyWorkItem” and click Create.
  3. Delete the property that was automatically added (called something like Property_…) when you created the class.

We don’t have to add a new key property to the custom Work Item class since we’re already inheriting a key property.

Using the Configuration Item Form Template

  1. Right click Forms in the Management Pack explorer, select Add Custom
    image
  2. In the Base Class dialog, select your custom class called MyConfigItem and click OK
  3. In the Add custom fom dialog, name your form MyConfigItemForm, select the following assembly C:\Temp\MyCustomForms\Litware.SCSM.CustomFormTemplates.dll
  4. Still in the Add custom form dialog, in the type selection drop down select CITemplate (which contains both a related items and the history tab) and click Create
    SNAGHTML74e66a
  5. In the the “Form Designer”, add a Label and a TextBox to General tab.
  6. Change the Content of the Label to “Principal Name”
  7. Change the Binding Path of the TextBox to PrincipalName
    image

Using the Work Item Form Template

  1. Right click Forms in the Management Pack explorer, select Add Custom
  2. In the Base Class dialog, select your custom class called MyWorkItem and click OK
  3. In the Add custom fom dialog, name your form MyWorkItemForm, select the following assembly C:\Temp\MyCustomForms\Litware.SCSM.CustomFormTemplates.dll
  4. Still in the Add custom form dialog, in the type selection drop down select WITemplate (which contains both a related items and the history tab) and click Create
  5. In the the “Form Designer”, add a Label and a TextBox to General tab.
  6. Change the Content of the Label to “Title”
  7. Change the Binding Path of the TextBox to Title
  8. Save all changes and exit the Service Manager Authoring Tool

Wiring up a working binding source

Since the control used for the Related Items tab requires a type projection with specific components to work, let’s go through the steps required to make sure we provide that.

  1. Open up C:\Temp\MyCustomForms\Litware.SCSM.FormsExample.xml in an XML editor
  2. In the <References> section, make sure you have the following references:

    <Reference Alias="WorkItem">
            <ID>System.WorkItem.Library</ID>
            <Version>7.5.1561.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> 
    </Reference> 
    <Reference Alias="SupportingItem">
            <ID>System.SupportingItem.Library</ID>
            <Version>7.5.1561.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> 
    </Reference> 
    <Reference Alias="CoreKnowledge">
            <ID>System.Knowledge.Library</ID>
            <Version>7.5.1561.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> 
    </Reference> 
    <Reference Alias="ConfigurationManagement">
            <ID>ServiceManager.ConfigurationManagement.Library</ID>
            <Version>7.5.1561.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> 
    </Reference>

    Note: If you already have references to any of these Management Packs, make sure the alias of the existing reference matches the alias in the XML above.

  3. In the <EntityTypes> section (below the <ClassTypes> section) add the following two type projections encapsulated in the <TypeProjections> tag
  4. <TypeProjections>
            <TypeProjection ID="MyConfigItem.Projection" Accessibility="Public" Type="MyConfigItem">
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToConfigItem' SeedRole='Target']$" Alias="ImpactedWorkItem" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem' SeedRole='Target']$" Alias="RelatedWorkItem" />
              <Component Path="$Context/Path[Relationship='SupportingItem!System.ConfigItemHasFileAttachment']$" Alias="FileAttachment" />
              <Component Path="$Context/Path[Relationship='System!System.ConfigItemRelatesToConfigItem']$" Alias="RelatedConfigItem" />
              <Component Path="$Context/Path[Relationship='System!System.ConfigItemRelatesToConfigItem' SeedRole='Target']$" Alias="RelatedConfigItemSource" />
              <Component Path="$Context/Path[Relationship='CoreKnowledge!System.EntityLinksToKnowledgeDocument']$" Alias="RelatedKnowledgeArticles" />
    </TypeProjection>

    <TypeProjection ID="MyWorkItem.Projection" Accessibility="Public" Type="MyWorkItem">
              <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemHasFileAttachment']$" Alias="FileAttachments">
                <Component Path="$Target/Path[Relationship='SupportingItem!System.FileAttachmentAddedByUser']$" Alias="FileAttachmentAddedBy" />
              </Component>
              <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem']$" Alias="RelatedWorkItems">
                <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="RWIAffectedUser" />
                <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="RWIAssignedUser" />
              </Component>
              <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem' SeedRole='Target']$" Alias="RelatedWorkItemSource">
                <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="RelatedWorkItemAssignedTo" />
              </Component>
              <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem']$" Alias="RelatedConfigItems" />
              <Component Path="$Target/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem' TypeConstraint='CoreKnowledge!System.Knowledge.Article']$" Alias="RelatedKnowledgeArticles" />
            </TypeProjection>
    </TypeProjections>

  5. Now let’s wire up the forms to each of the type projections. For the Config Item form, find the <Form> with ID="MyConfigItemForm" and replace Target="MyConfigItem" with Target="MyConfigItem.Projection"
  6. For the Work Item form, find the <Form> with ID="MyWorkItemForm" and replace Target="MyWorkItem" with Target="MyWorkItem.Projection"
  7. Save the file and exit the XML editor.

Creating the Management Pack Bundle

Before we’re ready to go we need to create a Management Pack Bundle which contains the Management Pack and the dll that contains the form templates.

  1. Open up a PowerShell command prompt
  2. Execute the following commands:
    import-module smlets
    cd C:\Temp\MyCustomForms
    New-MPBFile.ps1 .\Litware.SCSM.FormsExample.xml .\Litware.SCSM.FormsExample –computername SCSMComputerName

Note: I just loaded up smlets to get access to New-MPBFile.ps1, nothing else. Smlets can be found at http://smlets.codeplex.com

Taking the custom forms for a spin

  1. Import the Management Pack Bundle: Litware.SCSM.FormsExample.mpb
  2. Restart the console
  3. Create views for the custom classes (in the example files available as download in the top of the blog post I’ve already added the views)
  4. Use the console tasks Create MyConfigItem or Create MyWorkItem to try out the forms.

In Part 2 I’ll show you how the templates were created!

Important: Throughout this blog post I’m storing date model resources like managment pack classes in unseald management packs. You should always avoid this in production scenarios but since this is just to demo the templates I didn’t go through the extra steps required. Normally I would have created a separate managment pack with all data model resources within and selad that before starting up the creation of forms.

A couple of days ago Anders Bengtsson over at contoso.se asked me if I could help out and create a solution that could be used to help automate the task of saving file attachments to the file system. After spending some time messing around with memory streams in PowerShell I’ve managed to come up with a script that can be used to save all files “attached” to a work item or configuration item in Service Manager.

#
#Author: Patrik Sundqvist, www.litware.se
#Description: Can be used to archive attached files
#
 
param([Guid] $Id = $(throw "Parameter `$Id is required. This should be the internal id of a work item or config item which attached files you want to archive."),
[string]$ArchiveRootPath = $(throw "Parameter `$ArchiveRootPath is required. A folder containing all file attachments will be created in this folder."),
[string]$ComputerName = "localhost")
 
$WIhasAttachMent = "aa8c26dc-3a12-5f88-d9c7-753e5a8a55b4"
$CIhasAttachMent = "095ebf2a-ee83-b956-7176-ab09eded6784"
 
#Adjust path
$ArchiveRootPath = $ArchiveRootPath.TrimEnd("\")
 
#Make sure path exists
if(!(Test-Path $ArchiveRootPath))
{
    Write-Error "Provided archive path $ArchiveRootPath doesn't exists" -ErrorAction Stop
}
 
#Making sure smlets is loaded
if(!(get-module smlets))
{
    import-module smlets -Force -ErrorAction Stop    
}
 
#Get Emo
$Emo = Get-SCSMObject -Id $Id -ComputerName $ComputerName
 
 
#Check if this is a work item or config item
$WIhasAttachMentClass = Get-SCSMRelationshipClass -Id $WIhasAttachMent -ComputerName $ComputerName
$WIClass = Get-SCSMClass System.WorkItem$ -ComputerName $ComputerName
#Figure out if this is a work item or a config item to make sure we use the correct relationship
if($Emo.IsInstanceOf($WIClass))
{
    $files = Get-SCSMRelatedObject -SMObject $Emo -Relationship $WIhasAttachMentClass -ComputerName $ComputerName
}
else
{
    $CIhasAttachMentClass = Get-SCSMRelationshipClass -Id $CIhasAttachMent -ComputerName $ComputerName
    $CIClass = Get-SCSMClass System.ConfigItem$ -ComputerName $ComputerName
    if($Emo.IsInstanceOf($CIClass))
    {
        $files = Get-SCSMRelatedObject -SMObject $Emo -Relationship $CIhasAttachMentClass -ComputerName $ComputerName
    }
    else
    {
        Write-Error "Instance isn't of supported type" -ErrorAction Stop
    }
}
 
#For each file, archive to entity folder
if($files -ne $Null)
{
    #Create archive folder
    $nArchivePath = $ArchiveRootPath + "\" + $Emo.Id
    New-Item -Path ($nArchivePath) -ItemType "directory" -Force|Out-Null
 
    $files|%{
            Try
            {
                $_.DisplayName
                $fs = [IO.File]::OpenWrite(($nArchivePath + "\" + $_.DisplayName))
                $memoryStream = New-Object IO.MemoryStream
                $buffer = New-Object byte[] 8192
                [int]$bytesRead|Out-Null
                while (($bytesRead = $_.Content.Read($buffer, 0, $buffer.Length)) -gt 0)
                {
                    $memoryStream.Write($buffer, 0, $bytesRead)
                }        
                $memoryStream.WriteTo($fs)
            }
            Finally
            {
                $fs.Close()
                $memoryStream.Close()
            }
    }
}

Get-FileAttachments.ps1 requires “smlets” which can be downloaded at smlets.codeplex.com.

Remember to unblock the script after downloading, if you want to be able to run it that is :)

Using smlets you can simply search for configuration items or work items and pass on their internal ids to the script to have all their attachments archived nice and easy in a folder of your choice. In the example below I’m searching for all incidents in Service Manager that has a title containing the word “computer”. I pass on their internal id, a folder to use for archiving and the computer name of my Service Manager management server to the script. The script then checks for attachments and, in the case of finding attachments, creates a folder for each incident that has attachments and save the files in them.

?View Code POWERSHELL
Import-module smlets
$class = get-scsmclass system.workitem.incident$ -ComputerName sm2
$incidents = Get-SCSMObject -Class $class -Filter "DisplayName -like '*test*'" -computerName sm2
foreach ($incident in $incidents)
{
    .\Get-FileAttachments.ps1 -Id $incident.Get_Id() -ArchiveRootPath "C:\SCSM\Archive" -computername sm2    
}
Comments (10)

A few weeks back I was awarded the “System Center Cloud and Datacenter Management” MVP Award. I just wanted to shout out a big thanks to Microsoft, my wife (for putting up with all the late hours), colleagues, fellow community contributors and Anders Bengtsson (www.contoso.se, for all the fun work we’ve done together on collaborating posts).

logo_mvp

Categories : MVP, Service Manager
Comments (4)

In the new self-service portal (SSP) in Service Manager 2012 you have the option to validate input using a custom regular expression. To possibly save you some time when doing so I would like to share something important with you.

Always start you expression with caret (^) and end with a dollar sign ($). This makes sure that the input given by the user is an exact match to your expression.
^ – A caret matches the position at the beginning of the input string.
$ – A dollar sign matches the position at the end of the input string.

Example expression:
\d

The expression above can be used to find all digits in a text. If you would use that as a validation expression for a text field in Service Manager, according to Service Manager the input would be valid as long as a digit is written into the field. Here’s a pitfall, this means that a user can write whatever he/she wants before and after the digit. Normally this probably isn’t what you’re looking for when validating the input. Normally you would want to validate the complete input. Adding the caret and the dollar sign (^\d$) will make sure that nothing else goes into the text field than a digit.

If you want to try your expressions out before implementing them, here’s one of my favorites:
http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

Other resources:
http://msdn.microsoft.com/en-us/library/ff650303.aspx
http://www.regular-expressions.info

Categories : Service Manager
Comments (0)
Feb
24

SMLets – Enum and wildcards

Posted by: | Comments (11)

I’ve seen the question two times now, and that’s two times too many :)
The script below will show you how you can locate all Incident (as an example) that has an Classification value matching a Incident Classification that has a display name that matches *problem*.

?View Code POWERSHELL
Import-module smlets -Force
 
$class = get-scsmclass system.workitem.incident$
 
#Try to narrow the next search down by getting the root value for the enums you're interested in.
$rootEnum = Get-SCSMEnumeration IncidentClassificationEnum$
 
#Might be performance heavy depending on how many child enums the parent enum has.
$matchingEnums = get-scsmchildenumeration -Enumeration $rootEnum|?{$_.DisplayName -like '*problem*'}
 
$Filter = ""
$matchingEnums|%{$Filter +="Classification -eq '$($_.Id)' -or " }
$Filter = $Filter.TrimEnd("-or ")
 
Get-SCSMObject $class -Filter $Filter

Remember that the display name used when matching the filter is the localized display name used by the current process (if you run this in a workflow).
If you haven’t already got it, you’ll find SMLets at http://smlets.codeplex.com

When using smlets (smlets.codeplex.com) to work with Service Manager using PowerShell, small details can have huge impact on performance.

Server side vs. Client side filtering

The number one thing is to use server side filtering as far as possible. This has been described before but cannot be told too many times.

Example of client side filtering:

?View Code POWERSHELL
$class = Get-SCSMclass system.workitem.incident$ 
Get-SCSMObject -class $class|?{$_.Title -like '*printer*'}

Example of server side filtering:

?View Code POWERSHELL
$class = Get-SCSMclass system.workitem.incident$
Get-SCSMObject $class -Filter "Title -like *printer*"

In my test lab the server side filtering above is 50 times faster than client side. The reason for that is that client side filtering in the example above, in fact means bringing over all objects of the specific class to the client side and finding the matches there. Not a good idea!

Read more about the gain and tips about server side filtering in these excellent blog posts from Travis Wright and Jim Truher:
Properly Querying SCSM Using SMLets Get-SCSMObject cmdlet
Retrieving projection data with PowerShell

Choosing the lighter type projection

What I want to add to the above is how choosing the proper type projection will affect the performance.

As an example, let’s say we want to retrieve all Incidents that are currently Active and Un-Assigned (assigned to user is not set).

We can do this by using the following PowerShell commands:

?View Code POWERSHELL
#Get type projection
$IncidentProjection = Get-SCSMTypeProjection System.WorkItem.Incident.ProjectionType$
#Create criteria
$criteria = new-object $CTYPE $cc,$IncidentProjection.__Base,$IncidentProjection.managementgroup
#Get incidents matching the criteria
$incidents = Get-SCSMObjectProjection -Criteria $criteria

Note: I cut out the part of defining the criteria “$cc”, you can find it in the download available in the bottom of the post.

Depending on which type projection you choose the time for execution of the commands can differ greatly. The reason for this is that different type projections bring a different amount of data back from the server. A type projection is a definition of what data you want to wrap around the seed class instance (in this case the Incident). When choosing which type projection to use we have to think about how we want to define the criteria and which data we want to retrieve. In our example above we just want to see which incidents are Active and Un-assigned. This basically means that we only require a type projection (read more about type projections here) that has the seed class “Incident” and has one component, the AssignedUser. Let’s look at the effect of choosing two different type projections in the example above.

To see which type projections are available for a specific type you can use the following command:

?View Code POWERSHELL
Get-scsmtypeprojection|?{$_.TargetType.Name -eq "System.WorkItem.Incident"}

Note: Client side filtering is perfectly fine in usage like this of course. Another great way to study type projections is to export management packs and look at the xml directly. Also, if you do not find a suitable type projection you can also define your own, but that’s a different story.

After looking at the type projections let’s say that we choose to use the one called “System.WorkItem.Incident.ProjectionType” since this one contains all the components we’ll ever need. Actually it’s the projection that is used out of the box for the Incident form, which means it contains all the components used by the form like: Assigned User, Primary User, Activities, Affected User etc.

Executing the query for all Incidents with status Active which are Un-Assigned, using the type projection above, in my lab environment (over a medium slow connection) takes about 30s.

Now we might be perfectly fine with that, but let’s take a look at what would happen if we would have chosen a “lighter” type projection (fewer components wrapping the incident). As discussed earlier this scenario really only required one component, the AssignedUser, since we’re using the AssignedUser in our criteria.

The out-of-the-box type projection that has the least components and includes the AssignedUser is the projection called “System.WorkItem.Incident.View.ProjectionType”. This projection actually only contains two components: AssignedUser and AffectedUser. Using this projection for the same query for data as the previous, with the same setup takes 10s.

So by choosing a more suitable type projection we managed to cut two thirds of the time used for retrieving the incidents we were looking for.

So remember folks:

  • Use server side filtering
  • Use the type projection with the least components that fulfill your needs.
    Based on components used by your criteria and what data you want to retrieve.

One last thing, when creating views in Service Manager you can use the exact same reasoning regarding which components are required to achieve as good performance as possible. This has been described on its own in this great blog post by Travis Wright: Why is My Custom Incident View So Slow?

You can download my measurement script here: smletsDataQueryTest.ps1

Comments (0)