SOLUTION - How to attach a file to a record using Windows PowerShell (Invoke-WebRequest)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-20-2018 08:38 AM
**I started this thread as a question...but figured it out along the way. I guess I should make this an article...but I have already put everything here and don't want to lose my code again...so sorry if this is in bad form.
GOAL: Attach a file to an existing (or new) incident using Windows PowerShell.
Start with adding a new record in this case to the incident table.
Add (POST) New Record Using PowerShell:
##############################################
##### NEW RECORD #####
##############################################
# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "admin"
# 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://dev53556.service-now.com/api/now/table/incident"
# Specify HTTP method
$method = "post"
# Specify request body
#{request.body ? "$body = \"" :""}}{\"short_description\":\"Added using PowerShell...\",\"caller_id\":\"a8f98bb0eb32010045e1a5115206fe3a\"}"
# Could't get above line to work...seems like this example from the REST API Explorer is buggy...lots of posts on it not working...ended up using the approach below
$body = @{
'short_description' = 'Added using PowerShell'
'caller_id' = 'a8f98bb0eb32010045e1a5115206fe3a'
}
$bodyJson = $body | ConvertTo-Json
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $bodyJson
# Print response
$response.RawContent
# Other methods
$response2 = $response.Content | ConvertFrom-Json
# Now you can select specific fields as PowerShell Objects. Example:
$response2.result | Select category, state, impact
#Example of adding specific field to a string
$response2.result | % {Write-host "SysID: $($_.sys_id)"}
**Remember for later that you can get the sys_id of the newly created record from the response2.result var/object.
The next thing I did was to update an existing record:
Update (PATCH) Existing Record Using PowerShell:
##############################################
##### PATCH RECORD #####
##############################################
# Eg. User name="admin", Password="admin" for this code sample.
$dateNow = Get-Date
$user = "admin"
$pass = "admin"
# 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://dev53556.service-now.com/api/now/table/incident/935ca5d74f2023002bd2224f9310c783"
# Specify HTTP method
$method = "patch"
$body = @{
'short_description' = ' <<== Last Modified -- using $method via PowerShell'
'caller_id' = 'f298d2d2c611227b0106c6be7f154bc8'
}
$bodyJson = $body | ConvertTo-Json
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $bodyJson
# Print response
$response.RawContent
**If needed you can paste in that response2 code from the 'add new record' example to get at specific fields in the updated record.
And finally now I want to add an attachment to an existing incident record. Note that in this example the URI path changes somewhat from the other two operations. Ensure that you add the right table name ("table_name=") and then the sys id ("table_sys_id") for the record you want to attach files to. Note that "table_sys_id" is not the sys id for the table...but the sys id for the record you want to attach the file to.
Upload (POST) File Attachment to Existing Record Using PowerShell:
##############################################
##### FILE UPLOAD #####
##############################################
# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "admin"
# 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')
# $headers.Add('Content-Type','text/plain') ??didn't seem to need this
# Specify endpoint uri
$uri = "https://dev53556.service-now.com/api/now/attachment/file?table_name=incident&table_sys_id=935ca5d74f2023002bd2224f9310c783&file_name=MySampleDoc.txt"
# Specifiy file to attach
$fileToAttach = "c:\Users\ericroberts\sample.txt"
# Specify HTTP method (POST, PATCH, PUT)
$method = "POST"
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -InFile $fileToAttach
# Print response
$response.RawContent
Last thing is adding a file attachment or attachments to a new record. Using the add new record method allows you to get the response variable where you can get the sys_id of the newly created record. From that you can then attach an associated file to that new record. In the final example I made variables out of the constants like instance, table name, etc.
Add New Record And Immediately Attach a File To It:
##############################################
##### ADD NEW RECORD THEN ATTACH FILE #####
##############################################
# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "admin"
# 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')
#Define instance and table names
$instanceName = "dev53556"
$tableName = "incident"
# Specify endpoint URI for creating new record
$newRecordURI = "https://$($instanceName).service-now.com/api/now/table/$($tableName)"
# Specify HTTP method
$method = "POST"
$body = @{
'short_description' = 'New Incident Record that will get a file attachment.'
'caller_id' = 'a8f98bb0eb32010045e1a5115206fe3a'
}
$bodyJson = $body | ConvertTo-Json
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $newRecordURI -Body $bodyJson
# Take response and get at the fields just created:
$response2 = $response.Content | ConvertFrom-Json
#Capture the sysID of the newly created record
$newRecordSysID = $response2.result.sys_id
##############################################
##### FILE UPLOAD #####
##############################################
# Specify endpoint URI for attaching a file
$recordSysID = $newRecordSysID
$fileName = "190685.docx"
$uriForFileAttach = "https://$($instanceName).service-now.com/api/now/attachment/file?table_name=$($tableName)&table_sys_id=$($recordSysID)&file_name=$($fileName)"
# Specifiy file to attach
$fileToAttach = "c:\Users\ericroberts\$($fileName)"
# Specify HTTP method (POST, PATCH, PUT)
$method = "POST"
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uriForFileAttach -InFile $fileToAttach
Hope this helps someone some day.
Thanks,
ER
- 8,708 Views
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-03-2019 12:28 AM
Hey Thanks for sharing the script. That worked for me for ´Upload (POST) File Attachment to Existing Record Using PowerShell´
Would like to know how can we pass the Credentials in a secure way through powerhsell script rather than passing the Hardcoded values in the above mentioned file.
I am passing as arguments to powershell script the Username, password, Uri and FileToAttach. User name and password to be passed in a secure way.
Can some one help me on this?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-29-2019 04:42 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-17-2020 11:29 AM
Just in case you did not find a solution for this it looks like the MID Server account was used and it may not have had the needed permissions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-28-2020 02:42 PM
Eric - you saved my day 🙂 thx a lot 🙂
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-14-2020 11:07 AM
These worked for me but I have the same question as So199787, is there anyway to pass the creds via the PS cmdlet Get-Credential?