Building Service Now Functions for adding to existing automation scripts.

I have been working on some bigger automation projects here lately. And ran into the need to learn more about Service Now and how to create Incidents and Change Requests via PowerShell and also how to add them to the Scripts I was already working on. So in good fashion, there was not much out there already so here is my rendition of what I needed.

This script is taking what I already did in the last 3 Service Now posts and creatingSNDev functions. This allowing for quick plug and play into the scripts going forward. Just in case you have not read them here are the previous posts that give some background on where this all came from.

Service Now Incident Creation and Updating with PowerShell

Service Now Change Request Creation and Updating with PowerShell

Using the ServiceNow Rest API Explorer

This script is broken into 3 main functions. Create, Update and Get. For my use case, I was creating an Incident and then creating a Change Request with the Incident as the parent.

# Build Service Now Functions for Create, Update, and Get Incidents and Changes

# Chris Hildebrandt

# 11-25-2018

# Ver 1.0

# Script will create a new ServiceNow Incident and Change, Update existing Incidents and Changes, and Get all details of Incidents and Changes via Powershell

#______________________________________________________________________________________

#______________________________________________________________________________________

#ServiceNow Varibles

$SNAddress = "https://YOURSERVICENOW.service-now.com"

#______________________________________________________________________________________

#Incident Varribles

$SNINCCallerID = "Caller Sys_ID"

$SNINCUrgency = "2" #Look this up in your Service Now instance

$SNINCImpact = "3" #Look this up in your Service Now instance

$SNINCPriority = "4" #Look this up in your Service Now instance

$SNINCContactType = "email" #Look this up in your Service Now instance

$SNINCNotify = "2" #Look this up in your Service Now instance

$SNINCWatchlist = "Watch List Sys_ID" #Can do comma seperated users Sys_ID's

$SNINCServiceOffering = "Service Offering" #Look this up in your Service Now instance

$SNINCProductionImpact = "No" #Well I hope its a No.

$SNINCCategory = "Your Catagory" #Look this up in your Service Now instance

$SNINCSubcategory = "Your SubCat" #Look this up in your Service Now instance

$SNINCItem = "request" #Look this up in your Item menu

$SNINCAssignmentGroup = "Assignment Group Sys_ID"

$SNINCAssignedTo = "Assigned To Sys_ID"

$SNINCShortDescription = "Short Discription"

$SNINCDescription = "Full Discription"

$SNINCWorkNotes = "Work Notes"

$SNINComments = "Notes"

#______________________________________________________________________________________

#Change Varribles

$SNCHGRequestedBy = "Requested By Sys_ID"

$SNCHGCategory = "Change Catagory" #Look this up in your Service Now instance

$SNCHGServiceOffering = "Service Offering" #Look this up in your Service Now instance

$SNCHGReason = "Change Reason" #Look this up in your Service Now instance

$SNCHGClientImpact = "No" #Look this up in your Service Now instance

$SNCHGStartDate = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss') #date in string format. Only way it works.

$SNCHGEndDate = (Get-Date).AddHours($RCTimeDelay2+24).ToString('yyyy-MM-dd HH:mm:ss') #24 hour delay of right now (Can Change if needed) Has to be as a string

$SNCHGWatchList = "Watch List Sys_ID" #Can do comma seperated users Sys_ID's

$SNCHGUrgency = "2" #Look this up in your Service Now instance

$SNCHGRisk = "4" #Look this up in your Service Now instance

$SNCHGType = "Standard" #Look this up in your Service Now instance

$SNCHGState = "1" #Look this up in your Service Now instance

$SNCHGAssignmentGroup = "Assignment Group Sys_ID"

$SNCHGAssignedTo = "Assigned To Sys_ID"

$SNCHGShortDescription = "Short Description"

$SNCHGDescription = "Description Test"

$SNCHGJustification = "Justification Notes"

$SNCHGChangePlan = "Change Plan"

$SNCHGTestPlan = "Test Plan Notes"

$SNCHGBackoutPlan = "Back Out Plan Notes"

$SNCHGChangeSummary = "Change Summary Notes"

#______________________________________________________________________________________

#Create Service Now Creds if they do not already exist

if(-Not (Test-Path -Path "C:\VDI_Tools\Scripts\SNAccount.txt" ))

{

Get-Credential-Message "Enter Your ServiceNow Account! Username@domain"|Export-Clixml"C:\VDI_Tools\Scripts\SNAccount.txt"

Write-Host"Created Secure Credentials for ServiceNow"

}

#______________________________________________________________________________________

#Import Service Now Creds

$SNCreds = Import-Clixml "C:\VDI_Tools\Scripts\SNAccount.txt"

Write-Host "Imported Secure Credentials for ServiceNow from Text file"

#______________________________________________________________________________________

#Decrypt Password to imput into ServiceNow

$SNTextPass = $SNCreds.Password | ConvertFrom-SecureString

$SNTextPassPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR( (ConvertTo-SecureString $SNTextPass) ))

Write-host "Decrypt Master Password to clear text for import into VM"

#______________________________________________________________________________________

#Create ServiceNow Creds Varribles

$SNuser = $SNCreds.Username

$SNpass = $SNTextPassPlain

#______________________________________________________________________________________

#ServiceNow Method Varibles Do not edit these

$SNMethodPost = "post"

$SNMethodGet = "get"

$SNMethodPut = "put"

$SNMethodPatch = "patch"

$SNINCAddress = "$SNAddress/api/now/table/incident"

$SNCHGAddress = "$SNAddress/api/now/table/change_request"

#______________________________________________________________________________________

#ServiceNow Build Auth Headers

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $SNuser, $SNpass)))

#______________________________________________________________________________________

#ServiceNow Set Header

$SNheaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$SNheaders.Add('Authorization',('Basic {0}' -f $base64AuthInfo))

$SNheaders.Add('Accept','application/json')

$SNheaders.Add('Content-Type','application/json')

Function Create-Incident()

{

# Specify request body

$SNCreateINCBody = @{ #Create Body of the Post Request

caller_id=$SNINCCallerID

urgency=$SNINCUrgency

impact=$SNINCImpact

priority=$SNINCPriority

contact_type=$SNINCContactType

notify=$SNINCNotify

watch_list=$SNINCWatchlist

service_offering=$SNINCServiceOffering

u_production_impact=$SNINCProductionImpact

category=$SNINCCategory

subcategory=$SNINCSubcategory

u_item=$SNINCItem

assignment_group=$SNINCAssignmentGroup

assigned_to=$SNINCAssignedTo

short_description=$SNINCShortDescription

description=$SNINCDescription

work_notes=$SNINCWorkNotes

comments=$SNINComments

}

$SNCreateINCbodyjson = $SNCreateINCBody | ConvertTo-Json

# POST to API

Try

{

# Send API request

$SNCreateIncResponse = Invoke-RestMethod -Method $SNMethodPost -Uri $SNINCAddress -Body $SNCreateINCbodyjson -TimeoutSec 100 -Headers $SNheaders -ContentType "application/json"

}

Catch

{

Write-Host $_.Exception.ToString()

$error[0] | Format-List -Force

}

return $SNCreateIncResponse

}

Function Create-Change()

{

#Specify Change Request Body

$SNCreateCHGbody = @{ #Create Body of the Post Request

requested_by=$SNCHGRequestedBy

category=$SNCHGCategory

service_offering=$SNCHGServiceOffering

reason=$SNCHGReason

u_client_impact=$SNCHGClientImpact

start_date=$SNCHGStartDate

end_date=$SNCHGEndDate

watch_list=$SNCHGWatchList

parent=$SNIncidentSysID

urgency=$SNCHGUrgency

risk=$SNCHGRisk

type=$SNCHGType

state=$SNCHGState

assignment_group=$SNCHGAssignmentGroup

assigned_to=$SNCHGAssignedTo

short_description=$SNCHGShortDescription

description=$SNCHGDescription

justification=$SNCHGJustification

change_plan=$SNCHGChangePlan

test_plan=$SNCHGTestPlan

backout_plan=$SNCHGBackoutPlan

u_change_summary=$SNCHGChangeSummary

}

$SNCreateCHGbodyjson = $SNCreateCHGbody | ConvertTo-Json

# POST to API

Try

{

# Send API request

$SNCreateChangeResponse = Invoke-RestMethod -Method $SNMethodPost -Uri $SNCHGAddress -Body $SNCreateCHGbodyjson -TimeoutSec 100 -Headers $SNheaders -ContentType "application/json"

}

Catch

{

Write-Host $_.Exception.ToString()

$error[0] | Format-List -Force

}

return $SNCreateChangeResponse

}

Function Update-Change($SNCHGUpdateComments)

{

# Specify request body

$SNUpdateCHGbody = @{ #Create Body of the Post Request

comments=$SNCHGUpdateComments

}

$SNUpdateCHGbodyjson = $SNUpdateCHGbody | ConvertTo-Json

# Send API request

$SNUpdateChangeResponse = Invoke-RestMethod -Method $SNMethodPatch -Uri "$SNCHGAddress\$SNChangeSysID" -Body $SNUpdateCHGbodyjson -TimeoutSec 100 -Headers $SNheaders -ContentType "application/json"

}

Function Update-Incident($SNINCUpdateWorkNotesUpdate)

{

# Specify request body

$SNUpdateINCbody = @{ #Create Body of the Post Request

work_notes=$SNINCUpdateWorkNotesUpdate

}

$SNUpdateINCbodyjson = $SNUpdateINCbody | ConvertTo-Json

# Send API request

$SNUpdateIncidentResponse = Invoke-RestMethod -Method $SNMethodPatch -Uri "$SNINCAddress\$SNIncidentSysID" -Body $SNUpdateINCbodyjson -TimeoutSec 100 -Headers $SNheaders -ContentType "application/json"

}

Function Get-Incident($SNGetIncidentSysID)

{

# Build URI

$SNGetINCAddress = "$SNINCAddress/$SNGetIncidentSysID" + "?sysparm_fields=parent%2Ccaused_by%2Cwatch_list%2Cu_aging_category%2Cu_call_back_number%2Cupon_reject%2Csys_updated_on%2Cu_resolved_by_tier_1%2Cu_ud_parent%2Cu_resolved_within_1_hour%2Cu_routing_rule%2Capproval_history%2Cskills%2Cu_actual_resolution_date%2Cnumber%2Cu_related_incidents%2Cu_closure_category%2Cstate%2Csys_created_by%2Cknowledge%2Corder%2Cdelivery_plan%2Ccmdb_ci%2Cimpact%2Cu_requested_for%2Cactive%2Cpriority%2Cgroup_list%2Cbusiness_duration%2Cu_template%2Capproval_set%2Cwf_activity%2Cu_requested_by_phone%2Cshort_description%2Cu_itil_watch_list%2Cdelivery_task%2Ccorrelation_display%2Cwork_start%2Cu_ca_reference%2Cadditional_assignee_list%2Cnotify%2Cservice_offering%2Csys_class_name%2Cfollow_up%2Cclosed_by%2Creopened_by%2Cu_csv_comments%2Cu_planned_response_date%2Creassignment_count%2Cassigned_to%2Csla_due%2Cu_actual_response_date%2Cu_sla_met%2Cu_closure_ci%2Cu_reopen_count%2Cescalation%2Cupon_approval%2Cu_service_category%2Ccorrelation_id%2Cu_resolution_duration%2Cu_requested_by_name%2Cmade_sla%2Cu_requested_by_email%2Cu_item%2Cu_svc_desk_created%2Cresolved_by%2Cu_business_service%2Csys_updated_by%2Cuser_input%2Copened_by%2Csys_created_on%2Csys_domain%2Cu_quality_impact%2Cu_req_count%2Ccalendar_stc%2Cclosed_at%2Cu_relationship%2Cu_parent_incident%2Cu_comments_and_work_notes%2Cu_requested_by_not_found%2Cu_requested_by%2Cbusiness_service%2Cu_agile_incident_ref%2Cu_symptom%2Crfc%2Ctime_worked%2Cexpected_start%2Copened_at%2Cwork_end%2Creopened_time%2Cresolved_at%2Ccaller_id%2Cu_client%2Cwork_notes%2Csubcategory%2Cu_ah_incident%2Cclose_code%2Cassignment_group%2Cbusiness_stc%2Cdescription%2Cu_planned_resolved_date%2Ccalendar_duration%2Cu_on_hold_type%2Cu_source%2Cclose_notes%2Cu_closure_subcategory%2Cu_previous_assignment%2Csys_id%2Ccontact_type%2Curgency%2Cproblem_id%2Cu_itil_group_list%2Cu_response_duration%2Cu_best_number%2Ccompany%2Cactivity_due%2Cseverity%2Cu_production_impact%2Ccomments%2Capproval%2Cdue_date%2Csys_mod_count%2Csys_tags%2Clocation%2Ccategory"

# Specify request body

$SNGetINCbody = @{

}

$SNGetINCbodyjson = $SNGetINCbody | ConvertTo-Json

# Send API request

$SNGetIncidentResponse = Invoke-RestMethod -Method $SNMethodGet -Headers $SNHeaders -Uri $SNGetINCAddress

Return $SNGetIncidentResponse

}

Function Get-Change($SNGetChangeSysID)

{

To run the code you can do something like this…

$SNCreateIncResponseReturn = Create-Incident

$SNIncidentID = $SNCreateIncResponseReturn.result.number
$SNIncidentSysID = $SNCreateIncResponseReturn.result.sys_id

Write-Host $SNIncidentSysID
Write-Host $SNIncidentID

Above will create an Incident and then populate the IncidentID and SysID variables. That gives you your INC number and your Sys_ID of the incident.

You can do the same thing with the change. Keep in mind that my code uses the IncidentSysID to create a change with the parent of the Incident we just created.

$SNCreateChangeResponseReturn = Create-Change

$SNChangeID = $SNCreateChangeResponseReturn.result.number
$SNChangeSysID = $SNCreateChangeResponseReturn.result.sys_id

Write-Host $SNChangeSysID
Write-Host $SNChangeID

Same as above this will create the change and give you your Change Number and Sys_ID number.

You can update Incident you created running just the simple command of:

update-incident "Update the change Notes"

Or if you want to import a file contents you can run the following command.

update-incidents $content = [IO.File]::ReadAllText("File Path and name")

This will read all the contents of the file and post it into the Incident Comments. Great when you uploading logs.

Can do the same thing with the change.

update-change "Update Change Work Notes"

or the import file contents

update-incidents $content = [IO.File]::ReadAllText("File Path and name")

Next is the Get Incident and Change. For me, I wanted to save all the change and incident info in a log file for reference later if I ever had an issue.

Get-Incident $SNIncidentSysID

This will write on the console all the contents of the Incident. or you can run the same thing for the Change Request

Get-Change $SNChangeSysID

There are a massive amount of other things you can do with the Service Now API explorer. Maybe as I have time I will dig more into it.

All the contents to this script are posted on my GitHub repo HERE. Along with my other Service Now stuff from the other blogs.

About childebrandt42

I am a jack of all trades and a master of a few things. Manage a enterprise VDI deployment for a living. Automate things, work on my media server and fish for hobbies. Monkey tamer at home!
This entry was posted in CLI and Powershell, Random Crap, Service Now and tagged , , . Bookmark the permalink.