Skip to content

Instantly share code, notes, and snippets.

@brettmillerb
Last active September 13, 2019 06:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brettmillerb/d8459161762d1c3bb7c4e524fdbb67d5 to your computer and use it in GitHub Desktop.
Save brettmillerb/d8459161762d1c3bb7c4e524fdbb67d5 to your computer and use it in GitHub Desktop.
ServiceNow Helper
using namespace System.Net
using namespace System.Management.Automation
# Input bindings are passed in via param block.
param (
$Request,
$TriggerMetadata
)
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'
# Interact with query parameters or the body of the request.
$instance = $Request.Query.Instance
if (-not $instance) {
$instance = $Request.Body.Instance
}
if ($instance) {
$status = [HttpStatusCode]::OK
# Build PSCredential objects to obtain oAuth Token
Write-Host 'Creating ServiceNow Credential Objects'
$userCreds = [pscredential]::new(
$env:SNOWUserName,
(ConvertTo-SecureString -String $Env:SNOWUserPass -AsPlainText -Force)
)
$clientCreds = [pscredential]::new(
$env:SNOWClientID,
(ConvertTo-SecureString -String $env:SNOWClientPass -AsPlainText -Force)
)
# Get a Bearer Token to be used in subsequent calls
$getServiceNowOAuthSessionSplat = @{
Instance = $instance
ClientCredential = $clientCreds
UserCredential = $userCreds
}
$userCreds.GetNetworkCredential().Password
$clientCreds.GetNetworkCredential().Password
Write-Host ('Obtaining Bearer Token from {0}' -f $getServiceNowOAuthSessionSplat.Instance)
$oauthResult = Get-ServiceNowOAuthSession @getServiceNowOAuthSessionSplat
# Look up the serviceNow user from the slack email address for assignedTo property
$getServiceNowUserSplat = @{
EmailAddress = $request.Query.slack_user_email
Instance = $oauthResult.Instance
BearerToken = $oauthResult.BearerToken
}
Write-Host 'Looking up Slack user in ServiceNow'
$getServiceNowUserResult = Get-ServiceNowUser @getServiceNowUserSplat
# Build parameters to create the problem record
$newServiceNowProblemRecordSplat = @{
BearerToken = $oauthResult.BearerToken
Instance = $oauthResult.Instance
ShortDescription = $request.Query.short_description
Description = $request.Query.description
AssignmentGroup = $request.Query.assignment_group
AssignedTo = $getServiceNowUserResult.result.sys_id
Service = $request.Query.live_services_product
Classification = $request.Query.classification
}
$newServiceNowProblemRecordSplat
Write-Host 'Creating Problem Record in ServiceNow'
$problemRecord = New-ServiceNowProblemRecord @newServiceNowProblemRecordSplat
# Collate result information to be passed to Slack Function
$irmSlackFunction = $problemRecord.result | Select-Object -Property @(
'number'
'sys_created_on'
'sys_id'
'short_description'
'description'
@{name='opened_by';expression={$_.opened_by.display_value}}
@{name='assigned_to';expression={$_.assigned_to.display_value}}
@{name='assignment_group';expression={$_.assignment_group.display_value}}
@{name='zoom_link';expression={$request.query.zoom_link}}
) | ConvertTo-Json -Depth 99
$body = Invoke-RestMethod -Uri $env:slackfunctionurl -Body $irmSlackFunction
}
else {
$status = [HttpStatusCode]::BadRequest
$body = "Please pass a servicenow instance name on the query string or in the request body."
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $status
Body = $body
})
function Get-ServiceNowOAuthSession {
param (
[String]
$Instance = 'dev.service-now.com',
[Parameter(Mandatory)]
[System.Management.Automation.PSCredential]
$ClientCredential,
[Parameter(Mandatory)]
[System.Management.Automation.PSCredential]
$UserCredential
)
# Build a URI
$URI = 'https://{0}/oauth_token.do' -f $Instance
# Build content
$postData = "grant_type=password&"
$postData += "client_id={0}&" -f $ClientCredential.username
$postData += "client_secret={0}&" -f $ClientCredential.GetNetworkCredential().Password
$postData += "username={0}&" -f $UserCredential.username
$postData += "password={0}&" -f $UserCredential.GetNetworkCredential().Password
# Headers
$headers = @{
"X-Requested-With" = "powershell"
}
# Fire Request
$invokeRestMethodSplat = @{
Uri = $URI
Method = 'Post'
Headers = $headers
Body = $postData
}
$result = Invoke-RestMethod @invokeRestMethodSplat
# Return access token (string)
[PSCustomObject]@{
BearerToken = $result.access_token
Instance = $Instance
}
}
function New-ServiceNowProblemRecord {
[CmdletBinding(SupportsShouldProcess = $true,
ConfirmImpact = 'Medium')]
Param (
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
$BearerToken,
[String]
$Instance = 'dev.service-now.com',
[Parameter(Mandatory)]
[string]
$ShortDescription,
[Parameter(Mandatory)]
[string]
$Description,
[Parameter(Mandatory)]
[string]
$AssignmentGroup,
[Parameter(Mandatory)]
[string]
$AssignedTo,
[Parameter(Mandatory)]
[string]
$Service,
[String]
$Classification = 'FYI'
)
process {
$headers = @{
Accept = 'application/json'
'Content-Type' = 'application/json'
Authorization = 'Bearer {0}' -f $BearerToken
}
$uri = 'https://{0}/api/now/v2/table/problem?sysparm_display_value=true' -f $Instance
$Body = @{
short_description = $ShortDescription
description = $Description
assignment_group = $AssignmentGroup
assigned_to = $AssignedTo
u_live_services_product = $Service
u_classification = $Classification
}
$invokeRestMethodSplat = @{
Uri = $uri
Method = 'POST'
Headers = $headers
Body = ($Body | ConvertTo-Json -Depth 99)
}
if ($pscmdlet.ShouldProcess("$Instance", "Creating new problem record")) {
Invoke-RestMethod @invokeRestMethodSplat
}
}
}
function Get-ServiceNowUser {
param (
[Parameter(Mandatory)]
[string]
$EmailAddress,
[string]
$instance = 'dev.service-now.com',
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
$BearerToken
)
$invokeRestMethodSplat = @{
Uri = 'https://{0}/api/now/table/sys_user?sysparm_query=email={1}&sysparm_limit=1' -f @(
$instance,
$EmailAddress
)
Headers = @{
Authorization = 'Bearer {0}' -f $BearerToken
}
Method = 'Get'
ContentType = 'application/json'
}
Invoke-RestMethod @invokeRestMethodSplat
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment