Powershell REST - Attachment API - looking for working example

SCOMadmin19
Kilo Contributor

Experts, 

 

I am trying to create some automation with powershell.  Specifically, I am creating an Incident based on alerts generated in System Center Operations Manager.  In this specific example, I am creating an incident for a disk space alert.  I have created a disk space free chart and saved it as a png file.  I would like to attach this image file to the incident after creation.

I have looked for online examples and documentation but powershell does not seem to be the most popular choice for coding to the REST API...  

Looking at the API explorer, it will show sample code right up to the point of trying to attach a binary file.  Then the only available sample code is curl.  

 

The following does not work.  I do not know what I am supposed to do with the body.  Here I am trying to pass the path of the file I want to upload.  Reading some posts online, I see some people converting the binary to a base64 string.  Is that necessary with the new attachment API?  

 

function AttachFiletoIncident {
    $method = "post"
    $uri = "https://mysnow.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=$IncidentResult.IncID&file_name=$ImageName"
    # write-host $uri
    $body = @{'uploadFile'=$ImagePath}
    $bodyJson = $body | ConvertTo-Json
    # write-host $bodyJson
    $response = (Invoke-restmethod -Method $method -Uri $uri -ContentType "application/json" -Headers $imageheaders -Body $bodyJson).result
     
 Return $response
}

 

This code returns a 404 indicating a syntax error.  I have tried a number of different things including trying to wrap the file path in the uri itself; trying to put all attributes directly into the body; using the upload syntax instead of file.  

I have not tried the eccqueue yet, but again would prefer to use the attachment API if it will do what I need.

Any help would be appreciated.

thanks

 

 

 

4 REPLIES 4

Nicolas17
Tera Expert

Dear SCOMadmin19,

I managed to make it work. In my example, I first generate a record. Then I attach a file to it.

Don' focus too much on my file construction exampole. In my original script, I build a CSV file and store it somewhere else before consuming any ServiceNow REST API.

# File Information
$fileName = myFile.csv
$filePath = "c:\Files"
$file = $filePath, $fileName -join "\"

# Basic Authentication credentials
$user = "login"
$pass = "password"

# Build auth header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass)))

# Set proper headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')
$headers.Add('Content-Type','application/json')

# Specify endpoint uri
$uri = "https://yourServiceNowInstance.service-now.com/api/now/table/anyTableofYourChoice?sysparm_fields=sys_id"

# Specify HTTP method
$method = "post"

# Specify request body
$body = @{
    short_description="Some short description"
    description="Some other string"
    # ...
    }

$bodyJson = $body | ConvertTo-Json

# Send HTTP request
$response = (Invoke-RestMethod -Headers $headers -Method $method -Uri $uri -Body $bodyJson).Result

# Save sys_id
$id = $response.sys_id

# ServiceNow attachment
# Specify endpoint uri
$attachUri = "https://yourServiceNowInstance.service-now.com/api/now/attachment/file?table_name=anyTableofYourChoice&table_sys_id=" + $id + "&file_name=" + $fileName

# Send HTTP request
$upload= Invoke-RestMethod -Headers $headers -Uri $attachUri -Method Post -InFile $file -ContentType 'multipart/form-data'

 

Hope this helps!

Hi Nicolas,

 

I have a requirement to attach a file to Service now incident using rest api in Powershell script.

 

I am new to powershell. I looked in to your code shared. Is it that you are uploading/attaching  File.csv to incident ? 

 

If yes, i tried the same code by changing the required Uri, filepaths. Facing an error ..

 

Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\Users\xxx\Documents\xx\TestFileattachment.ps1:47 char:10
+ $upload= Invoke-RestMethod -Headers $headers -Uri $attachUri -Method ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

 

Can you please help on this.

Nicolas17
Tera Expert
Dear So199787,
 
An HTTP 400 Bad Request error means that the server (your ServiceNow instance) doesn't understand what you're trying to achieve. A good thing is that the communication between your computer and ServiceNow seems OK.
 
This kind of error usually means that you have something wrong, like an illegal character somewhere in your request.
 
 
It's complicated to figure out the issue without having a proper look at the code you execute. Which part are you using?
In my code I first create a record in a table, then attach a file to this newly created record.
 
If the record you're trying to attach a file to already exists, all you need is the last few lines (The ServiceNow attachment part). as you only need to know the destination table and record sys_id.
If you create a new record be carafull with the construction of the request body.
Are you able to send the true code you execute?

VaranAwesomenow
Mega Sage

I get same error as well
PS C:\ps> C:\ps\test.ps1
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At C:\ps\test.ps1:33 char:10
+ $upload= Invoke-RestMethod -Headers $headers -Uri $attachUri -Method ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand