Jun
10

Custom console tasks: Part 2

By

In the first part of the “Custom console tasks” series i described a very simple but powerful way to use the “Tasks” functionality in the Service Manager console to reboot an affected computer of an incident. This time I’m going to show you how we can use PowerShell scripting and some custom Cmdlets I’ve published on Codeplex to create a task that can re-activate (open) a closed incident, something that isn’t possible to do in the console out-of-the-box. Before we go on, please note that according to most process frameworks you shouldn’t re-open a closed incident.

Updated 2011-01-04 since there was a typo in step 6, parameters argument

  1. The first thing you need is the custom Service Manager Cmdlets i published on Codeplex (download here). You can follow the instructions here to install the Cmdlets. Using these cmdlets you’re able to update some incident properties, most importantly for this scenario the “Status” property.
  2. Secondly you need a powershell script that uses the Cmdlets to do all the magic. I’ve written a script that forces the status of an incident to “Active” (no matter previous Status). Since this is kind of hardcore, and should be considered as an override, I wanted to prompt the user for a “reason”. The script accomplishes this by running some C# code that renders a dialog where the user can provide a reason for running the task on the incident. If the user click the “Cancel” button I abort the action and leave the status “as is”. If the user click the “OK” button I go ahead and change status to “Active” (the reason is logged in the action log). 
  3. 2010-11-19 Updated script to work with SMLets Beta 1 or later

    ?View Code POWERSHELL
    param($ID)
    Import-module smlets -Force
     
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
     
    $objForm = New-Object System.Windows.Forms.Form
    $objForm.Text = "Force Incident Status"
    $objForm.Size = New-Object System.Drawing.Size(400,200)
    $objForm.StartPosition = "CenterScreen"
     
    $objForm.KeyPreview = $True
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
        {$x=$objTextBox.Text;$objForm.Close()}})
    $objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
        {$objForm.Close()}})
     
    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(125,120)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close();$result="OK"})
    $objForm.Controls.Add($OKButton)
     
    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(200,120)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$objForm.Close()})
    $objForm.Controls.Add($CancelButton)
     
    $objLabel = New-Object System.Windows.Forms.Label
    $objLabel.Location = New-Object System.Drawing.Size(10,20)
    $objLabel.Size = New-Object System.Drawing.Size(360,20)
    $objLabel.Text = "Please enter a reason for forcing the incident status to Active:"
    $objForm.Controls.Add($objLabel) 
     
    $objTextBox = New-Object System.Windows.Forms.TextBox
    $objTextBox.Location = New-Object System.Drawing.Size(10,40)
    $objTextBox.Size = New-Object System.Drawing.Size(360,60)
    $objTextBox.Multiline = "True"
    $objForm.Controls.Add($objTextBox) 
     
    $objForm.Topmost = $True
     
    $objForm.Add_Shown({$objForm.Activate()})
    [void] $objForm.ShowDialog()
     
    if($result -eq "OK")
    {
        Set-SCSMIncident -ID $ID -Status Active
        Write-Host "Incident status forced to Active"
        if($x -gt 0)
        {
        	Write-Host "Reason for action: $x"
        }
        else
        {
        	Write-Host "No reason provided"
        }
    }
    else
    {
        Write-Host "Force to active status aborted"
    }
  4. Place the script in a local folder, I use “C:\PowerShell Scripts”
  5. Create a new task in the Service Manager console: Administration – Library – Tasks
    1. Name: Force Activate
    2. Description: Used to force status of incident to active, can be used on closed incidents!
    3. Target Class: Incident
    4. Category: Incident Management Folder Tasks
    5. Command Line: powershell.exe
    6. Parameters: &'.\ForceActivate.ps1' $Context/Property[Type='WorkItem!System.WorkItem']/Id$
    7. Working Directory: C:\PowerShell Scripts\
    8. Log in action log when this task is run: True
    9. Show output when this task is run: True

You’re done! You’re now able to break all the rules and open closed incidents…

This was an example of how powerful tasks can be built using PowerShell and the Service Manager SDK (used by the Cmdlets) to customize the console functionality in Service Manager. I plan to write a final part of this series where we go all the way and use managed code only to create a custom task including a custom WPF form.

Comments

  1. Dan says:

    Its a shame that microsoft does not provide apropriate documentation for authoring custom solutions for SCSM, and you need to create your own code.

    Other service desk manufacturers provide easy to use customization toll for their solution that works, and even a poweruser can use it. With microsoft i see only a developer can customize the product to the clients requirements.

    That raises the implementation price a lot.

  2. German Minicucci says:

    Works like a charm! Thanks!

  3. Fletcher Kelly says:

    Hi,

    Just another quick note.
    Tried to run it in on a machine that had the console installed, not the Server.
    Ran into an issue about the Data Access Service.

    Easy Fix, copy SDK folder from Server to same location on the workstation.
    Add -computername “servername/ip” to set-scsmincident cmdlet.

    Works like a CHARM :)

    Awesome stuff guys :)

  4. [...] once it has been closed, should a user come back and claim that the case is NOT Resolved, click here for the [...]

  5. Craig says:

    NIce tutorial however once i click create task i receive

    Failed to validate item: Consoletask.7ef4b20c29ab44129a7a39c6374a8ec3

    I recently upgraded to Sp1. Could that be the problem?

  6. Roman says:

    Hi !

    The Powershell script is cool, will probably try.

    It was a 5 Minutes Task to do this via Opalis and SCSM 2010 SP1 CU3.

    What i will implement now for my client is a approval Workflow which will send an e-Mail to the OPLIA Mailbox.
    Opalis will pick-up the Mail and reopen (activate) the corresponding Incident.

    Worked well during tesing already.
    Roman

Leave a Reply