403 Forbidden attaching file to kb_knowledge

Mike Hashemi
Kilo Sage

I am using a PowerShell script (see below) to create an article, then add an attachment. The article-creation piece works fine, but I am getting 403 Forbidden (User is unauthorized to write to record: kb_knowledge.<article sys_id>) when I try to attach a file.

 

The script is using the same account to create the article and to attach the file, and has both the admin and knowledge admin roles.

 

Any idea what is going on? We have a business rule that automatically moves articles created by this user from "draft" to "review", which triggers the Auto Publish workflow. The only thing I can think of is that, because the article is published, it cannot be modified, but I do not see anything in the API documentation (https://developer.servicenow.com/dev.do#!/reference/api/utah/rest/c_AttachmentAPI) about checking-out an article.

 

 

$cred = Get-Credential
$content = Get-Content -Path c:\it\test.html
$uri = "https://instance.service-now.com/api/now/table/kb_knowledge"
$method = "POST"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $cred.UserName, $cred.GetNetworkCredential().Password)))
$headers = @{
    'Authorization' = ('Basic {0}' -f $base64AuthInfo)
    'Accept'        = 'application/json'
    'Content-Type'  = 'application/json'
}

$tempObj = [PsCustomObject]@{
    text                = ($content | Out-String).Trim()
    sys_created_by      = 'serviceAccount'
    author              = '<serviceAccount sys_id>'
    active              = 'true'
    kb_knowledge_base   = '<kb sys_id>'
    topic               = 'General'
    short_description   = 'Testing Attachments'
    article_type        = 'text'
    kb_category         = '<category sys_id>'
    workflow_state      = 'draft'
    display_attachments = $true
}

$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body ($tempObj | ConvertTo-Json) -ErrorAction Stop
$result = ($response.Content | ConvertFrom-Json).result

If ($result.number) {
    $articleSysId = $result.sys_id
    $method = "POST"
    $tableName = 'kb_knowledge'
    $fileName = 'test.txt'
    $filePath = 'C:\it\test.txt'
    $uri = "https://instance.service-now.com/api/now/attachment/file?table_name=$tableName&table_sys_id=$articleSysId&file_name=$fileName"

    $headers = @{
        'Accept'       = 'application/json'
        'Content-Type' = 'text/plain'
    }

    # Read file content as binary
    $fileContent = [System.IO.File]::ReadAllBytes($filePath)

    # Convert the file content to Base64
    $fileContentBase64 = [System.Convert]::ToBase64String($fileContent)

    $response = Invoke-RestMethod -Uri $uri -Method $method -Headers $headers -Credential $cred -Body $fileContentBase64
}

 

5 REPLIES 5

DrewW
Mega Sage
Mega Sage

I would do two things

1 - Try using an account that has admin access and if it works its not a code issue its a permissions issue.

2 - Login to the instance as the user you are using and see if you can use the interface to do it.  If not then you can turn on ACL debugging and then impersonate the user to see which ACL is blocking adding attachments.

 

  1. I noted in the original post, that the service account has the admin and knowledge admin roles assigned. When you say, "Try using an account that has admin access..." are you referring to something else?
  2. I had to turn of "web services only" for the service account. After that, I impersonated the user and added an attachment in the UI, without issue (after checking-out the article).

I found an unpublished article and WAS able to add an attachment with the code above. So it appears that my thought about the document being published is the problem. How would one check-out a document with the Attachment API (or workaround the checkout requirement)? 

Ya you cannot update a published KBA.  So you are going to have to make a call to check the state and then decide if you are going to check it out or not push the attachment.

 

Personally I would remove the BR that automatically updates the state and I would have your script do that once you have pushed the attachments to the KBA's.

 

I idea how to either check-out (then check-in) using one of the APIs (I cannot find one) or how to trigger publish without the BR? I have tried changing the workflow_state from "draft" to both "review" and "published", but the articles never get picked up by the workflow and sit, unavailable to users.