On SAS, 4k Native Disks, and Dell Optiplex Workstations

EDIT: The information in this page is wrong. The Optiplex line does _not_ support 4k native drives. More info asap.

___________________________________________

Hi there,

Recently I ran into a couple scenarios where I needed to use either 4k native drives and/or SAS 12Gb drives in a Dell Optiplex 9020. Here’s what I learned.

Here are the drives I was using:

  • ST6000NM0014 – Seagate SAS12 4k native 6TB
  • ST6000NM0004 – Seagate SATA 4k native 6TB

About 4k native drives

The 4k Native SATA drives work great in Optiplex 9020 using onboard SATA. I configured the drives in RAID. I know for sure that the onboard SATA for Optiplex 990 machines and below will not support 4k native disks. I haven’t tried the Optiplex 9010.

I was wrong, the Optiplex line does _not_ support 4k native drives.

SAS Controllers that did not work

As far as 4k Native SAS drives, I know for sure that the following RAID controllers will not work.

  • Dell Perc H700
  • LSI MegaRaid SAS 9240-4I
  • LSI MegaRaid SAS 9260-16i

SAS Controller that did work (yay)

This one DOES work! It’s the cheapest SAS controller I could find. It doesn’t support a BBU or SSD Caching. For that, you need to step up to the more expensive 93xx model. This card costs ~$200, the more expensive one costs a few hundred dollars more.

  • 3Ware 4-Port MegaRAID SAS 9341-4I Controller Card

About SAS drives and connectors

The Seagate drives come with a SFF-8482 connector. The MegaRAID SAS 9431 comes with a SFF-8643 connector. I could find two cables on the market that will match both ends. One is made by LSI, and the other by Adaptec.

For the Optiplex 9020 case, as well as an HP workstation case, the LSI cable’s drive-side adapters were the tiniest bit too big for the case to close. I could not find a way to make it work.

This cable does NOT work. The connectors are too big for the case to shut.

  • LSI Internal Cable SFF8643 to x4 SAS8482 w power, 0.6m. Mfg Part #: LSI00412.

This cable does work (yay!):

  • Adaptec 2280100-R HD SAS Cable, Mfg Part#: 2280100-R.

I hope this saves you some trouble🙂.

SCSM Email – Part 5.1.1 – Create Work Items from Email

Navigation:

Alright! We’ve got inbound and outbound email configured for SCSM. Pretty sweet. Now let’s look at work item creation straight from the email client.

Here’s what it will look like:

  • Create two folders in your helpdesk email account: create-new-incident and create-new-service-request.
  • When you want to create a new work item from an email, just move the email to the corresponding folder.

Here’s what we need to make SCORCH do:

  • Check an email account’s specific subfolders.
  • Create a corresponding work item with a title based off of the email’s subject line.
  • If the work item is to be a service request, create a new review activity, modify its properties, and add it to the work item.
  • Figure out who the affected user should be based on the sender’s address, and relate it to the work item.
  • (optional) Figure out who’s ‘department group’ that the user belongs to in AD, and relate it to the work item. We do this for accounting and reporting purposes.
  • Write the contents of the email body into a comment, and relate it to the work item.

To do this, we’ll use five runbooks:

  1. SMMail_CreateNewIR
  2. SMMail_CreateNewSR
  3. SMMail_CreateNewSRActivity
  4. SMMail_RelateAffectedUser
  5. SMMail_RelateAffectedGroups

These runbooks will be detailed in subsequent blog posts.

Part 4.1.3 – Receiving Comments – Runbook Design – SMMail_ProcInboundComments

Navigation:

Introduction

Alright! We’re ready to actually process the inbound comment emails. This will be a fairly long runbook.

Overview

We want a runbook that does the following:

  1. Accepts one parameter: emailID
  2. Gets the email by ID.
  3. Enters the email’s body text into the appropriate ticket.
  4. Generates and sends an email to the support team.

Branch Overview

We will need two branches, one for incidents, and one for service requests (big surprise).

  • Main
    • Branch 1 – Incidents
    • Branch 2 – Service Requests

Global Variables

  1. SCSM Scripts Account Username
    1. Username of AD account which can run SCSM SMLets on your SCSM server. It should have local admin rights on the SCSM server.
  2. SCSM Scripts Account Password
    1. Password to the account username given in the global variable ‘SCSM Scripts Account Username’.
    2. Make sure to check the ‘Encrypted Variable’ checkbox.
  3. SCSM Email Notification BCC Addresses
    1. semi-colon delimited list of email address to bcc all messages to.
  4. Email Scratch File Folder
    1. Folder to store a temp files for processing the email body text.

Activities Overview

Main Branch

  1. Initialize Data
    Type: Initialize Data
    Parameter 1 Name: emailID
  2. Get Email
    Type: Exchange User -> Get Items
    Configuration: helpdesk mailbox
    Filter: ID equals {emailID from “Initialize Data”}
  3. Smart Link
    Include: Subject from Get Email matches pattern “.*SR[0-9]+.*”
    Include: Subject from Get Email matches pattern “.*IR[0-9]+.*”
    Exclude: Get Email returns Warning,Failed
  4. Sanitize Subject
    Type: Data Manipulation -> Replace Text
    Input String: {Subject from Get Email}
    Pattern: ” (double-quotes)
    Replacement Text: (nothing)
    Use Regular Expression: True

Branch 1 – Incidents

  1. Smart Link from Sanitize Subject
    Include: Subject from Get Emails matches pattern “.*IR[0-9]+.*”
  2. (IR) Get ID from Email Subject
    Type: Data Manipulation -> Match Pattern
    Input String: {Subject from Get Email}
    Pattern: “IR[0-9]+”
    Case Sensitive: False
    Return Match Number: 0
  3. Get Incident
    Type: SC 2012 Service Manager -> Get Object
    Class: Incident
    Filters: ID equals {Match String from (IR) Get ID from Email Subject}
  4. (IR) Generate Comment GUID
    Type: Runbook Control -> Invoke Runbook
    Runbook: Generate GUID
    Invoke by path: True (checked)
    Wait for completion: True (checked)
  5. (IR) Write Email Body to Temp Folder
    Type: Text File Management -> Append Line
    File: {Email Scratch File Folder}scratch-{GUID from “(IR) Generate Comment GUID”}.txt
    File encoding: Auto
    Text: {Body from “Get-Email”}
  6. (IR) Parse HTML Email Body Content
    Type: System -> Run .Net Script
    Language: Powershell
    Script: See script section below “(IR) Parse HTML Email Body Content”.
    Published Data 1 Name: Plain Text Output
    Published Data 1 Variable: retval
  7. (IR) Replace Text
    Input String: {Plain Text Output from “(IR) Parse HTML Email Body Content”}
    Pattern: ” (double-quotes)
    Replacement Text: (nothing)
    Use Regular Expression: True
  8. (IR) Compile Comment
    Type: System -> Run .Net Script
    Language: Powershell
    Script: See script section below “(IR) Compile Comment”.
    Published Data 1 Name: Final Comment Text
    Published Data 1 Variable: comment
  9. (IR) Write Analyst Comments to Work Item
    Type: SC 2012 Service Manager -> Create Related Object
    Source Class: Incident
    Target Class: Trouble Ticket Analyst Comments
    Relationship Type: Has Analyst Comment
    Source Object Guid: {SC Object Guid from “Get Incident”}
    Comment: {Final Comment Text from “(IR) Compile Comment”}
    Entered by: {Sender from “Get-Email”}
    Entered date: {Date/Time Received from “Get Email”}
    ID: {GUID from “(IR) Generate Comment GUID”}
    Is private: True
    Display Name: {GUID from “(IR) Generate Comment GUID”}
  10. (IR) Forward to Admins
    Type: Exchange User -> Forward Item
    Body Prefix: The following message was processed and added to work item {Match String from “(IR) Get ID from Email Subject”} with title “{Title from “Get Incident”}.
    ID: {ID from “Get Email”}
    To: {SCSM Email Notification BCC Addresses}
  11. (IR) Move to Completed
    Type: Exchange User -> Move Item
    Configuration: helpdesk connector
    ID: {ID from “Get Email”}
    Copy: False
    Destination Folder: processing-complete

Branch 2 – Service Requests

I’m only going to detail the items in this section that are significantly different.

  1. Smart Link from Sanitize Subject
    Include: Subject from Get Emails matches pattern “.*SR[0-9]+.*”
  2. (SR) Get ID from Email Subject
  3. Get SR
  4. (SR) Generate Comment GUID
  5. (SR) Write Email Body to Temp Folder
  6. (SR) Parse HTML Email Body Content
  7. (SR) Replace Text
  8. (SR) Compile Comment
  9. (SR) Write Analyst Comments to Work Item
    Type: SC 2012 Service Manager -> Create Related Object
    Source Class: Service Request
    Target Class: Trouble Ticket Analyst Comments
    Relationship Type: Work Item Has Comment Log
    Source Object Guid: {SC Object Guid from “Get SR”}
    Comment: {Final Comment Text from “(SR) Compile Comment”}
    Entered by: {Sender from “Get-Email”}
    Entered date: {Date/Time Received from “Get Email”}
    ID: {GUID from “(SR) Generate Comment GUID”}
    Is private: True
    Display Name: {GUID from “(SR) Generate Comment GUID”}
  10. (SR) Forward to Admins
  11. (SR) Move to Completed

Error Notifications

Alright, great. But what if something goes wrong? We need to add some error logging. For this, we’ll need to create several sub-branches.

Create the following branches:

Error Branch 1 (IR)

  1. Smart Link from ‘Get Incident’
    Include: Number of Objects from Get Incident equals 0
    Include: Get Incident returns warning or failed
  2. (IR) Generate Missing WI Msg Properties
    Type: System -> Run .Net Script
    Language: Powershell
    Script:

    $message = "The subject line of this email contains the Work Item ID {Match String from "(SR) Get ID from Email Subject"}. However, this work item could not be found in SCSM. The email's ID is {ID from "Get Email"} and has been moved to 'processing-failed' folder."

    Published Data 1 Name: message
    Published Data 1 Variable: message

  3. (IR) Forward to Admins 1
    Type: Exchange User -> Forward Item
    ID: {ID from “Get Email”}
    To: {SCSM Email Notification BCC Addresses}
    Body Prefix: {message from “(IR) Generate Missing WI Msg Properties”}
  4. Move to Failed
    Type: Exchange User -> Move Item
    Configuration: helpdesk connector
    ID: {ID from “Get Email”}
    Copy: False
    Destination Folder: processing-failed

ERROR BRANCH 2 (IR)

  1. Smart Link from (IR) Parse HTML Email Body Content
    Include: Plain Text Output from (IR) Parse HTML Email Body Content equals failed
    Include: (IR) Parse HTML Email Body Content returns warning or failed
  2. (IR) Replace Text (failure)
    Input String: {Plain Text Output from “(IR) Parse HTML Email Body Content”}
    Pattern: ” (double-quotes)
    Replacement Text: (nothing)
    Use Regular Expression: True
  3. (IR) Generate Missing WI Msg Properties
    Type: System -> Run .Net Script
    Language: Powershell
    Script:

    $message = "There was a problem parsing the body contents of the email mesage. The Powershell parse script returned the following output "{Replacement Text from (IR) Replace Text (failure)"}."

    Published Data 1 Name: message
    Published Data 1 Variable: message

  4. (IR) Forward to Admins 2
    Type: Exchange User -> Forward Item
    ID: {ID from “Get Email”}
    To: {SCSM Email Notification BCC Addresses}
    Body Prefix: {message from “(IR) Generate Missing WI Msg Properties”}
  5. Move to Failed
    Type: Exchange User -> Move Item
    Configuration: helpdesk connector
    ID: {ID from “Get Email”}
    Copy: False
    Destination Folder: processing-failed

ERROR BRANCH 3 (IR)

  1. Smart Link from ‘(IR) Compile Comment’
    Include: Number of Objects from Get Incident equals 0
    Include: Get Incident returns warning or failed
  2. (IR) Generate Comment Compile Failed Msg
    Type: System -> Run .Net Script
    Language: Powershell
    Script:

    $message = "There was a problem compiling the comment for the email mesage. The Powershell parse script returned the following output {Error summary text from "(SR) Compile Comment"}."

    Published Data 1 Name: message
    Published Data 1 Variable: message

  3. (IR) Forward to Admins 3
    Type: Exchange User -> Forward Item
    ID: {ID from “Get Email”}
    To: {SCSM Email Notification BCC Addresses}
    Body Prefix: {message from “(IR) Generate Missing WI Msg Properties”}
  4. Move to Failed
    Type: Exchange User -> Move Item
    Configuration: helpdesk connector
    ID: {ID from “Get Email”}
    Copy: False
    Destination Folder: processing-failed

ERROR BRANCH 4 (IR)

  1. Smart Link from ‘(IR) Write Analyst Comments to Work Item’
    Include: Number of Objects from Get Incident equals 0
    Include: Get Incident returns warning or failed
  2. (IR) Generate Write Comment Failed Msg
    Type: System -> Run .Net Script
    Language: Powershell
    Script:

    $message = "There was a problem writing the comment the SR. The email has been moved to the 'processing-failed' folder. Email ID: {ID from "Get Email}. Work item ID: {ID from "(SR) Write Analyst Comments to WI}. Error message: {Error summary text from "(IR) Write Analyst Comments to Work Item}."

    Published Data 1 Name: message
    Published Data 1 Variable: message

  3. (IR) Forward to Admins 3
    Type: Exchange User -> Forward Item
    ID: {ID from “Get Email”}
    To: {SCSM Email Notification BCC Addresses}
    Body Prefix: {message from “(IR) Generate Missing WI Msg Properties”}
  4. Move to Failed
    Type: Exchange User -> Move Item
    Configuration: helpdesk connector
    ID: {ID from “Get Email”}
    Copy: False
    Destination Folder: processing-failed

I recommend that you duplicate these error branches for the ‘Service Request’ branch of this runbook as well.

Scripts

Note: The (SR) scripts are basically the same as these below, but with different SCSM variables linked in.

(IR) Parse HTML Email Body Content

$retval = Powershell {
$filename = "{File Path from "(IR) Write Email to Temp File"}"
If(test-path $filename) {
  $body = Get-Content "$filename" -Raw 
  $html = New-Object -ComObject "HTMLFile"
  $htmlBody = Get-Content "$filename" -Raw
  $html.IHTMLDocument2_write($htmlBody)
  $plainOutput = $html.body.innertext
}
Else{$plainOutput = $false}

#limit to 3750 characters, scsm can only handle 4k
If($plainOutput.Length -gt 3800) {$plainOutput = $plainOutput.Substring(0,3750)}
#remove non-xml char's since we're passing it back in
$plainOutput = [System.Text.RegularExpressions.Regex]::Replace($plainOutput,"[^1-9a-zA-Z_:.\\\/\-\!\@\#\$\%\^\&\*\(\)\+\=\,]"," ")
$plainOutput
}

(IR) Compile Comment

$From = "{From from "Get Email"}"
$sent = "{Date/Time Sent from "Get Email"}"
$to = "{To from "Get Email"}"
$Subject = "{Subject from "Get Email"}"

#$BodyFilePath = ""
#$Body = PowerShell { Get-Content "$BodyFilePath" -Raw }

$Body = "{Output String from "(IR) Replace Text"}"
$Comment = "From: " + $from + "`n"
$comment += "Sent: " + $sent + "`n"
$comment += "To: " + $to + "`n"
$comment += "Subject: " + $subject + "`n"
$comment += "`n"
$comment += $body

Conclusion

Here is an image of the final runbook!

413-1

Part 4.1.2 – Receiving Comments – Runbook Design – ‘Process Email – General Routing’ – Rev2

Navigation:

Introduction

This is a continuation of a series of posts about SCSM Email Integration. In this post, we will assume that SCORCH is already configured per the previous posts.

Our goal now is to extend the ‘Email General Routing’ runbook that we made previously.

Original Goals for this runbook:

  1. Check an email account for emails matching a specific template
  2. Forwards trigger information to a child runbook

Additional Goals:

  1. If an email arrives with a subject line containing [IR####] or [SR####], write the email to the corresponding ticket as a comment.

Runbook Name: Process Email – General Routing

Activities

Add the following activities:

  1. Link from ‘Every Minute’
  2. Get Items from Inbox
    Type: Exchange User -> Get Items
    Configuration: helpdesk
  3. Smart Link from ‘Get Items from Inbox’
    Include: Subject from ‘Get Items from Inbox’ matches pattern “.*SR[0-9]+.*”
    Include: Subject from ‘Get Items from Inbox’ matches pattern “.*IR[0-9]+.*”
    Exclude: Subject from ‘Get Items from Inbox’ starts with “SCSM_Trigger”.
  4. ProcInbondComments
    Type: Invoke Runbook
    Runbook Name: SMMail_ProcInboundComments
    Parameter 1 Name: emailID
    Parameter 2 Value: ID from ‘Get Items from Inbox’

Here is an image of the final runbook:

412-1

How I Handle SCSM Email Integration – Navigation

This is the master navigation table for this series.

Navigation:

SCSM Email Integration Part 4.1.1 – Receiving Comments

Navigation:

Introduction

Alright! So SCSM now emails out, but what about receiving emails?

The goal for this section is to enable the following feature: emails to a help-desk account which contain a work item ID in their subject line should be automatically added as a work item comment.

Overview:

  1. Email arrives at help desk email mailbox.
  2. Email contains a subject line with a work item ID such as ‘IR123’.
  3. SCORCH checks the mailbox and finds such messages.
  4. SCORCH processes the messages appropriately and adds SCSM comments.

The interesting thing about this workflow is that it doesn’t require any configuration on the SCSM side beyond what we’ve already done. The next blog posts will outline the SCORCH runbooks required to make all this work.

SCSM Email Integration Part 3.2.3 – Runbook Design – SMMail_Send-WiCommentEmail

Navigation:

Introduction

Alright! We’re ready to actually generate and send comment update emails. This will be a long post filled with child runbooks. Brace yourself.

Overview

We want a runbook that does the following:

  1. Accepts two parameters:
    1. a work item ID such as “IR123”.
    2. a comment GUID.
  2. Generates an email.
  3. Sends the email.

Branch Overview

We will need two branches, one for incidents, and one for service requests.

  • Main
    • Branch 1 – Incidents
    • Branch 2 – Service Requests

Global Variables

  1. SCSM Scripts Account Username
    1. Username of AD account which can run SCSM SMLets on your SCSM server. It should have local admin rights on the SCSM server.
  2. SCSM Scripts Account Password
    1. Password to the account username given in the global variable ‘SCSM Scripts Account Username’.
    2. Make sure to check the ‘Encrypted Variable’ checkbox.
  3. SCSM Email Notification BCC Addresses
    1. semi-colon delimited list of email address to bcc all messages to.

Activities Overview

Main Branch

  1. Initialize Data
    Parameter 1 Name: workItemId
    Parameter 2 Name: commentGuid

Branch 1 – Incidents

  1. Smart Link
    From: Initialize Data
    Include: workItemId from Initialize Data starts with IR
  2. Get IR
    Type: SC 2012 Service Manager -> Get Object
    Filter: ID equals {workItemId from Initialize Data}
  3. (IR) Get Work Item Affected User Email
    Type: System -> Run .Net Script
    Language: PowerShell
    Script: see Script section below.
    Published Data Parameter 1 Name: affectedUserEmailAddr
    Published Data Parameter 1 Variable: retval
  4. (IR) Generate – Email Subject Line
    Type: System -> Run .Net Script
    Language: PowerShell
    Script: see Script section below.
    Published Data Parameter 1 Name: affectedUserEmailAddr
    Published Data Parameter 1 Variable: retval
  5. (IR) Generate Email Message
    Type: System -> Run .Net Script
    Language: PowerShell
    Script: see Script section below.
    Published Data Parameter 1 Name: htmlEmailBody
    Published Data Parameter 1 Variable: retval
  6. (IR) Create and Send E-Mail
    Type: Exchange User -> Create and Send E-Mail
    To: {affectedUserEmailAddr from (IR) Get Work Item Affected User Email}
    Subject: {subject from (IR) Generate – Email Subject Line}
    Body: {htmlEmailBody from (IR) Generate Email Message}
    Body Type: HTML
    Bcc: {SCSM Email Notification BCC Addresses}
  7. (IR) Return Data
    Type: Runbook Control -> Return Data

Branch 2 – Service Requests

Identical to Branch 1, replacing all (IR) with (SR).

Scripts

(IR) Get Work Item Affected User Email

$ErrorActionPreference = "Stop"
try
{
    $username = "{SCSM Scripts Account Username}"
    $password = "{SCSM Scripts Account Password}"
    $scObjGuid = "{scObjectGuid from Get IR}"
    $scObjType = "incident"
    $targetServer = "Your-SCSM-Server"
    $securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
    $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$securePassword
    $retval = Invoke-Command -Credential $creds -ComputerName $targetServer  -ScriptBlock {
        $scObjGuid = $args[0]
        $scObjType = $args[1]
        & C:\Scripts\Get-ScsmWiAffectedUserEmailAddr.ps1 "$scObjGuid" "$scObjType"
    } -ArgumentList $scObjGuid, $scObjType
}
Catch
{
    Throw $_.Exception
}

Get-ScsmWiAffectedUserEmailAddr.ps1

Import-Module SMLets
$scObjGuid = $args[0]
$scObjType = $args[1]

Switch($scObjType) {
	"incident" {
		$wiClassName = "System.WorkItem.Incident$"
		$relationshipClassName = "System.WorkItemAffectedUser$"
	}
	"service request" {
		$wiClassName = "System.WorkItem.ServiceRequest$"
		$relationshipClassName = "System.WorkItemAffectedUser$"
	}
}

If($wiClassName -ne $null) {
	$wiClass = Get-SCSMClass $wiClassName
	$relationshipClass = Get-SCSMRelationshipClass $relationshipClassName
}

If($wiClass -ne $null -and $relationshipClassName -ne $null) {
	$wiFilter = "Id -eq '" + $scObjGuid + "'"
	$scObj = Get-SCSMObject -Class $wiClass -filter $wiFilter
	If ($scObj -ne $null) {
		$affectedUser = Get-SCSMRelatedObject -SMObject $scObj -Relationship $relationshipClass
	}
}

$emailAddr = ""
#ref: http://blogs.litware.se/?p=796
If($affectedUser -ne $null) {
	$userGUID = $affectedUser.Get_ID()
	$userPref = Get-SCSMRelationshipClass "System.UserHasPreference$"
	$endPoint = Get-SCSMRelatedObject -SMObject $affectedUser -Relationship $userPref|?{$_.DisplayName -like "*SMTP"}
	$readEmailaddr = $endPoint.TargetAddress
	If($readEmailaddr.length -ge 0) {
		$emailAddr = $readEmailAddr
	}
	Else {}
}

$emailAddr

(IR) Generate Email Subject Line

$subject = "IT Support [" + "{ID from Get IR}" + "]: " + "{Title from Get IR}"

(IR) Generate Email Message

$ErrorActionPreference = "Stop"
try
{
    $username = "{SCSM Scripts Account Username}"
    $password = "{SCSM Scripts Account Password}"
    $scObjGuid = "{scObjectGuid from Get IR}"
    $scObjType = "incident"
    $targetServer = "Your-SCSM-Server"
    $commentGuid = "{CommentGuid from Initialize Data}"
    $securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
    $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$securePassword
    $retval = Invoke-Command -Credential $creds -ComputerName $targetServer -ScriptBlock {
        $scObjGuid = $args[0]
        $scObjType = $args[1]
        $commentGuid = $args[2]
        & C:\Scripts\generate-WorkItemCommentNotification.ps1 "$scObjGuid" "$scObjType" "$commentGuid"
    } -ArgumentList $scObjGuid, $scObjType, $commentGuid
}
Catch
{
    Throw $_.Exception
}

Generate-WorkItemCommentNotification.ps1

Note, you will need to heavily modify this script to suit your needs, and to strip out my information. I’ll have a templated version up as soon as I can, but am providing this in the meantime.

Here is what the final output looks like. I created the template in MS Word, then saved it as HTML, changed the formatting, and inserted it into the PowerShell script below. I got the idea for the template from another blog post which I cannot find. I try to always credit folks, so if you notice something familiar please let me know. Cross-linking and credit benefits everyone!

2.2.4-2

$scObjGuid = $args[0]
$scObjType = $args[1]
$commentGuid = $args[2]
$emailBodyText = ""

Import-Module SMLets

#get the classes all lined up
Switch($scObjType) {
	"incident" {
		$wiClassName = "System.WorkItem.Incident$"
		$commentRelationshipClass = "System.WorkItem.TroubleTicketHasAnalystComment$"
		$queueProperty = "Impact"
	}
	"service request" {
		$wiClassName = "System.WorkItem.ServiceRequest$"
		$commentRelationshipClass = "System.WorkItemHasCommentLog$"
		$queueProperty = "Priority"
	}
}

#get the scsm work item (wi) object
If($wiClassName -ne $null) {
	$wiClass = Get-SCSMClass $wiClassName
	$wiFilter = "ID -eq '" + $scObjGuid + "'"
	$scObj = Get-SCSMObject -Class $wiClass -Filter $wiFilter
}

#get the WI info and body text
If($scObj -ne $null) {
	$commentRelationship = Get-SCSMRelationshipClass $commentRelationshipClass
	$commentObj = Get-SCSMRelatedObject -SMObject $scObj -Relationship $commentRelationship | ?{$_.ID -eq $commentGuid}
	$commentStr = $commentObj.Comment
	$commentAuthor = $commentObj.EnteredBy
	$commentDate = $commentObj.EnteredDate
	$emailBodyText = $null
	If($commentStr -ne $null -and $commentStr -ne "") {
		#sanitize a little
		While($commentStr -like "*>*") {$commentStr = $commentStr.Replace(">","")}
		While($commentStr -like "*<*") {$commentStr = $commentStr.Replace("<","")}
		While($commentStr -like "*""*") {$commentStr = $commentStr.Replace("""","")}
		While($commentStr -like "*'*") {$commentStr = $commentStr.Replace("'","")}
		$commentStr = $commentStr.Replace("`n","<br>")
		$emailBodyText = $commentStr
	}
	$wiTitle = $scObj.Title
	$wiUrgency = $scObj.Urgency.DisplayName
	$wiQueue = $scObj.$queueProperty.DisplayName
	$wiStatus = $scObj.Status.DisplayName
	$wiId = $scObj.ID
	$wiCreatedDate = $scObj.CreatedDate

	#$affectedUserClassName = "System.Domain.User$"
	#$affectedUserClassObj = Get-SCSMClass $affectedUserClassName
	$affectedUserRelationshipClassName = "System.WorkItemAffectedUser$"
	$affectedUserRelationshipClassObj = Get-SCSMRelationshipClass $affectedUserRelationshipClassName
	$affectedUserObj = Get-SCSMRelatedObject -SMObject $scObj -Relationship $affectedUserRelationshipClassObj
	If($affectedUserObj -ne $null) {
		$affectedUserDisplayName = $affectedUserObj.DisplayName
	}
	Else {
		$affectedUserDisplayName = "ESL Member"
	}
}

$htmlBody = ""
$htmlBody += "<html>

<head>
<meta http-equiv=Content-Type content=""text/html; charset=windows-1252"">
<meta name=Generator content=""Microsoft Word 15 (filtered)"">
<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:""Cambria Math"";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin-top:0in;
	margin-right:0in;
	margin-bottom:8.0pt;
	margin-left:0in;
	line-height:105%;
	font-size:11.0pt;
	font-family:""Calibri"",sans-serif;}
a:link, span.MsoHyperlink
	{color:#0563C1;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:#954F72;
	text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
	{margin-top:0in;
	margin-right:0in;
	margin-bottom:8.0pt;
	margin-left:.5in;
	line-height:105%;
	font-size:11.0pt;
	font-family:""Calibri"",sans-serif;}
p.msolistparagraphcxspfirst, li.msolistparagraphcxspfirst, div.msolistparagraphcxspfirst
	{mso-style-name:msolistparagraphcxspfirst;
	margin-top:0in;
	margin-right:0in;
	margin-bottom:0in;
	margin-left:.5in;
	margin-bottom:.0001pt;
	line-height:105%;
	font-size:11.0pt;
	font-family:""Calibri"",sans-serif;}
p.msolistparagraphcxspmiddle, li.msolistparagraphcxspmiddle, div.msolistparagraphcxspmiddle
	{mso-style-name:msolistparagraphcxspmiddle;
	margin-top:0in;
	margin-right:0in;
	margin-bottom:0in;
	margin-left:.5in;
	margin-bottom:.0001pt;
	line-height:105%;
	font-size:11.0pt;
	font-family:""Calibri"",sans-serif;}
p.msolistparagraphcxsplast, li.msolistparagraphcxsplast, div.msolistparagraphcxsplast
	{mso-style-name:msolistparagraphcxsplast;
	margin-top:0in;
	margin-right:0in;
	margin-bottom:8.0pt;
	margin-left:.5in;
	line-height:105%;
	font-size:11.0pt;
	font-family:""Calibri"",sans-serif;}
p.msochpdefault, li.msochpdefault, div.msochpdefault
	{mso-style-name:msochpdefault;
	margin-right:0in;
	margin-left:0in;
	font-size:12.0pt;
	font-family:""Calibri"",sans-serif;}
p.msopapdefault, li.msopapdefault, div.msopapdefault
	{mso-style-name:msopapdefault;
	margin-right:0in;
	margin-bottom:8.0pt;
	margin-left:0in;
	line-height:105%;
	font-size:12.0pt;
	font-family:""Times New Roman"",serif;}
span.apple-converted-space
	{mso-style-name:apple-converted-space;}
.MsoChpDefault
	{font-size:10.0pt;
	font-family:""Calibri"",sans-serif;}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
-->
</style>

</head>

<body lang=EN-US link=""#0563C1"" vlink=""#954F72"">

<div class=WordSection1>

<p class=MsoNormal>Dear "

$htmlBody += $affectedUserDisplayName
$htmlbody += ",</p>

<p class=MsoNormal>The comment (below) has been added to your work item. Please feel free to reply
to this message; it will be immediately forwarded to the ESL IT support team.</p>

<p class=MsoNormal><b>Written by "

$htmlBody += $commentAuthor
$htmlBody += " at "
$htmlBody += $commentDate
$htmlBody += ", comment reads:</b></p>

<table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0
 style='border-collapse:collapse;border:none'>
 <tr>
  <td width=935 valign=top style='width:467.5pt;border:solid windowtext 1.0pt;
  padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><span style='color:#0070C0'>"

$htmlBody += $emailBodyText
$htmlBody += "</span></p>
  </td>
 </tr>
</table>

<p class=MsoNormal> </p>

<p class=MsoNormal>Quick Notes:</p>

<p class=MsoListParagraph style='margin-bottom:0in;margin-bottom:.0001pt;
text-indent:-.25in;line-height:106%'><span style='font-family:Symbol'>·</span><span
style='font-size:7.0pt;line-height:106%;font-family:""Times New Roman"",serif'>      
</span>You can track the status of this work item at the <a
href=""https://scsm-esl-wc1.osuesl.net/SMPortal/SitePages/My%20Requests.aspx"">ESL
Service Manager Self-Service Web Portal</a>. (Note: requires Internet Explorer and an ESL LAN or VPN connection).</p>

<p class=MsoListParagraph style='margin-bottom:0in;margin-bottom:.0001pt;
text-indent:-.25in;line-height:106%'><span style='font-family:Symbol'>·</span><span
style='font-size:7.0pt;line-height:106%;font-family:""Times New Roman"",serif'>      
</span>The full work list of the ESL IT Support Team is available on the <a
href=""http://sharepoint.osuesl.net"">ESL SharePoint Helpdesk Website</a>. Choose 'IT Request Billboard'
from the left navigation list. (Note: requires ESL LAN or VPN connection).</p>

<p class=MsoListParagraph style='margin-bottom:0in;margin-bottom:.0001pt;
text-indent:-.25in;line-height:106%'><span style='font-family:Symbol'>·</span><span
style='font-size:7.0pt;line-height:106%;font-family:""Times New Roman"",serif'>      
</span>Make sure to place all new text for a reply at the top of the message
or it will not be read.</p>

<p class=MsoNormal> </p>

<p class=MsoNormal>More Information on the Work Item:</p>

<table class=MsoTable15List1LightAccent1 border=0 cellspacing=0 cellpadding=0
 style='border-collapse:collapse'>
 <tr>
  <td width=189 valign=top style='width:94.25pt;border:none;border-bottom:solid #9CC2E5 1.0pt;
  padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>Title </b></p>
  </td>
  <td width=585 valign=top style='width:292.5pt;border:none;border-bottom:solid #9CC2E5 1.0pt;
  padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>"
$htmlBody += $wiTitle
$htmlBody += "</b></p>
  </td>
 </tr>
 <tr>
  <td width=189 valign=top style='width:94.25pt;background:#DEEAF6;padding:
  0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>ID</b></p>
  </td>
  <td width=585 valign=top style='width:292.5pt;background:#DEEAF6;padding:
  0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'>"
$htmlBody += $wiID
$htmlBody += "</p>
  </td>
 </tr>
 <tr>
  <td width=189 valign=top style='width:94.25pt;padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>Status</b></p>
  </td>
  <td width=585 valign=top style='width:292.5pt;padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'>"
$htmlBody += $wiStatus
$htmlBody += "</p>
  </td>
 </tr>
 <tr>
  <td width=189 valign=top style='width:94.25pt;background:#DEEAF6;padding:
  0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>Urgency</b></p>
  </td>
  <td width=585 valign=top style='width:292.5pt;background:#DEEAF6;padding:
  0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'>"
$htmlBody += $wiUrgency
$htmlBody += "</p>
  </td>
 </tr>
 <tr>
  <td width=189 valign=top style='width:94.25pt;padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'><b>Created Date</b></p>
  </td>
  <td width=585 valign=top style='width:292.5pt;padding:0in 5.4pt 0in 5.4pt'>
  <p class=MsoNormal style='margin-bottom:0in;margin-bottom:.0001pt;line-height:
  normal'>"
$htmlBody += $wiCreatedDate
$htmlBody += "</p>
  </td>
 </tr>
</table>

<p class=MsoNormal> </p>

<p class=MsoNormal>Thank you,</p>

<p class=MsoNormal><img border=0 width=336 height=67 id=""Picture 1""
src=""http://osu.edu/assets/site/images/logos/osu-emailsig.png""
alt=""The Ohio State University""><span style='font-size:9.0pt;line-height:107%;
font-family:""Arial"",sans-serif;color:#333333'><br>
</span><b><span style='font-size:9.0pt;line-height:107%;font-family:""Arial"",sans-serif;
color:#BB0000;background:white'><span style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'>John Puskar, MCP</span></span></b><span style='font-size:
9.0pt;line-height:107%;font-family:""Arial"",sans-serif;color:#333333'><br
style='-webkit-user-select: none;orphans: auto;text-align:start;widows: auto;
-webkit-text-stroke-width: 0px;word-spacing:0px'>
<span style='background:white'><span style='orphans: auto;text-align:start;
widows: auto;-webkit-text-stroke-width: 0px;float:none;word-spacing:0px'>Sr.
Systems Manager</span></span><br style='-webkit-user-select: none;orphans: auto;
text-align:start;widows: auto;-webkit-text-stroke-width: 0px;word-spacing:0px'>
</span><span style='font-size:9.0pt;line-height:107%;font-family:""Arial"",sans-serif;
color:#BB0000;background:white'><span style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'>College of Engineering</span></span><span
class=apple-converted-space><span style='font-size:9.0pt;line-height:107%;
font-family:""Arial"",sans-serif;color:#333333;background:white'><span
style='orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
float:none;word-spacing:0px'> </span></span><span style='font-size:9.0pt;
line-height:107%;font-family:""Arial"",sans-serif;color:#333333;background:white'>Electroscience
Lab</span></span><span style='font-size:9.0pt;line-height:107%;font-family:
""Arial"",sans-serif;color:#333333'><br style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'>
<span style='background:white'><span style='orphans: auto;text-align:start;
widows: auto;-webkit-text-stroke-width: 0px;float:none;word-spacing:0px'>Room
240, 1330 Kinnear Road, Columbus, OH 43212</span></span><br style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'>
<span style='background:white'><span style='orphans: auto;text-align:start;
widows: auto;-webkit-text-stroke-width: 0px;float:none;word-spacing:0px'>614-292-5545
Office / 614-769-1231 Mobile</span></span><br style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'>
</span><a href=""mailto:puskar.4nokspam@osu.edu"" style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'><span style='font-size:9.0pt;line-height:107%;font-family:
""Arial"",sans-serif;background:white'>puskar.4nokspam@osu.edu</span></a><span
class=apple-converted-space><span style='font-size:9.0pt;line-height:107%;
font-family:""Arial"",sans-serif;color:#333333;background:white'><span
style='orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
float:none;word-spacing:0px'> </span></span></span><a
href=""http://electroscience.osu.edu/"" style='-webkit-user-select: none;
orphans: auto;text-align:start;widows: auto;-webkit-text-stroke-width: 0px;
word-spacing:0px'><span style='font-size:9.0pt;line-height:107%;font-family:
""Arial"",sans-serif;background:white'>electroscience.osu.edu</span></a></p>
</div>

</body>

</html>"

$htmlBody

Awesome! Your should now be getting pretty sweet emails every time a non-private comment is entered. Here’s a screenshot of the final runbook:

3.2.3-1

The exported runbooks will be available upon completion of this series.