About Attachment API and "File Attachment" type fields

Koki
Tera Contributor

Hi,

 

I am a newbie to REST API.

I need to use ServiceNow's Attachment API and PowerShell to upload a file to a field of type "File Attachment" in a certain table.

How do I go about writing the code, etc.?

 

Table name:x_540069_sn21_systemid

"File Attachment" type fields name:u_nw_kouseizu

target record:9fb8d7badb917010c42a8e4748961977

File name to upload:File Attachment test.xlsx

 

Can someone please tell me how to do this?

1 ACCEPTED SOLUTION

Hitoshi Ozawa
Giga Sage
Giga Sage

Fixed the script and was able to execute it from my Windows PC to successfully attach a file to a form in my ServiceNow PDI.

# Eg. User name="admin", Password="admin" for this code sample.
$user = "<username>"
$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('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')

$filePath = "<path to file>/test1.xlsx"

# Specify endpoint uri
$uri = "https://<instance name>.service-now.com/api/now/attachment/file?table_name=<table name>&table_sys_id=<sys_id of record to attach file>&file_name=test1.xlsx"

# Specify HTTP method
$method = "post"




# Send HTTP request
$response = Invoke-RestMethod -Headers $headers -Method $method -InFile $filePath -Uri $uri 

# Print response
$response.RawContent

View solution in original post

14 REPLIES 14

All attachments are uploaded to sys_attachment_doc table and not to a variable.

sys_attachment holds information on table name and sys_id in the table the attachment is related to.

>Also, when I run this code, I get an error and I have no idea why.

What is the error message?

>All attachments are uploaded to sys_attachment_doc table and not to a variable.

So, what is the purpose of specifying the "table name" of Query parameters in the "REST API Explorer"?
I thought it was to specify the table to upload to....

 

 

The error is ...

 

Invoke-RestMethod : リモート サーバーがエラーを返しました: (400) 要求が不適切です
発生場所 C:\Users\FN10020\Desktop\ServiceNow\2022年1月から\uploadTest_2.ps1:24 文字:13
+ $response = Invoke-RestMethod -Headers $headers -Method $method -Uri ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod]、WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Name of the table specified in the atttachment api will update the "Table name" column in sys_attachment table. There's no variable name in sys_attachment table.

Field of type "file attachment" is a reference to a record in sys_attachment table. Attachment api would only insert a record into sys_attachment and sys_attachment_doc tables so the developer would need to update the file attachment field in the table as I've replied in the other post.

I haven't tried this but it may be possible to write a Scripted REST API to accept binary data and then call GlideSysAttachment with the script to create a record in sys_attachment and sys_attachment_doc tables and then update the table's file attachment field to the sys_id.

https://developer.servicenow.com/dev.do#!/reference/api/rome/server/no-namespace/c_GlideSysAttachmen...

There's no direct API to attach a file to a field.

File attachment field contains reference to the sys_attachment table. So, after using Attachment api to upload the file to sys_attachment/sys_attachment_doc table, query to find the record in sys_attachment table and rename the table name by prefixing it with "ZZ_YY" so it won't appear on the top of the form and then, query the table associated with the form and set the attachment field to the sys_id of the record in the sys_attachment table.

e.g.

if the file name is "test.xls", rename the table_name to "ZZ_YYtest.xls" in sys_attachment table.

Then query x_540069_sn21_systemid table and update field u_nw_kouseizu to sys_id of record "test.xls" in the sys_attachment table.

var gr = new GlideRecord('x_540069_sn21_systemid');
gr.addQuery('sys_id', '<sys_id of record>');
gr.query();
if (gr.next()) {
  gr.u_nw_kouseizu = '<sys_id of file test.xlsx in sys_attachment>';
  gr.update();
}