Script to create article from KM article template

Mike Hashemi
Kilo Sage

I have the following PowerShell script, which I am using to move documentation from another system, into ServiceNow. This works fine when I am creating a regular old HTML article. Now I have a template and need to find a way to:

  1. Get the template fields
  2. Create a new article, specifying that it is to be created "from the template"

I can get the templates from kb_article_template and the custom template fields from kb_article_template_definition.

 

How do I modify my existing script to use the template info?

 

$ServiceNowBaseUri = 'https://<instance>.service-now.com'
$ServiceNowCredential = Get-Credential
$ArticleBody = '' # HTML
$KnowledgeBaseSysId = '' # sys_id
$ArticleName = '' # String
$ArticleCategory = '' # sys_id


$articleUri = "$ServiceNowBaseUri/api/now/table/kb_knowledge"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $ServiceNowCredential.UserName, $ServiceNowCredential.GetNetworkCredential().Password)))
$headers = @{
    'Authorization' = ('Basic {0}' -f $base64AuthInfo)
    'Accept'        = 'application/json'
    'Content-Type'  = 'application/json'
}

$articleObj = [PsCustomObject]@{
    text                = $ArticleBody
    sys_created_by      = '<author name>'
    author              = '<author sys_id>'
    active              = 'true'
    kb_knowledge_base   = $KnowledgeBaseSysId
    topic               = 'General'
    short_description   = $ArticleName
    article_type        = 'text'
    kb_category         = $ArticleCategory
    display_attachments = $true
}

Try {
    $response = Invoke-WebRequest -Headers $headers -Method 'POST' -Uri $articleUri -Body ($articleObj | ConvertTo-Json -EscapeHandling EscapeNonAscii) -ErrorAction Stop
    $result = ($response.Content | ConvertFrom-Json).result
    $articleSysId = $result.sys_id
} Catch {
    ("{0}: Error creating article `"{1}`". Error: {2}" -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"), $ArticleName, $_.Exception.Message)

    Return 1
}
#endregion Create new article

If ($response.StatusCode -In @(200, 201)) {
    ("{0}: Successfully created the article ({1})." -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"), $articleSysId)
} Else {
    ("{0}: Failed to create the document. Response: {1}" -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"), $($response | Out-String).Trim())

    Return 1
}

#region Publish article
("{0}: Publishing the article." -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"))

$uiActionSysId = '94f1b81d77424110dc25a5ed5b5a9943' # Sys_id for the Publish UI action
$queryParams = "?sysparm_table=kb_knowledge&sysparm_sys_id=$(($response.content | ConvertFrom-Json).result.sys_id)&api=api"
$commandParams = @{
    Uri        = "$ServiceNowBaseUri/api/now/ui/ui_action/$uiActionSysId$queryParams"
    Credential = $ServiceNowCredential
    Method     = 'POST'
    Headers    = $headers
    Body       = ([PsCustomObject]@{
            fields = @(
                @{
                    name = ''
                }
            )
        } | ConvertTo-Json)
}

Try {
    $response = Invoke-WebRequest @commandParams -ErrorAction Stop
} Catch {
    If ($response.StatusCode -NotIn @(200, 201)) {
        ("{0}: Unexpected error publishing article. Error: {1}." -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"), $_.Exception.Message)

        Return 1
    }
}

If ($response.StatusCode -In @(200, 201)) {
    ("{0}: Successfully published the article." -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"))
} Else {
    ("{0}: Article-publish failed. Response: {1}." -f ([datetime]::Now).ToString("yyyy-MM-ddTHH:mm:ss"), $($response | Out-String).Trim())

    Return 1
}
#endregion Publish article
1 REPLY 1

Vishal Jaswal
Giga Sage

Hello @Mike Hashemi 

 

In your Powershell script, you need to make the following changes:

 

1. You need to fetch the sys_id of the template you want to use from kb_article_template.

 

2. Now, fetch the template fields from kb_article_template_definition using the sys_id of the template.

 

3. Modify the article creation:

 

  article_type        = 'template'   kb_article_template = $templateSysId

 

Using your code for point#1

 

$templateName = "<Template Name>" # Specify the template name
$templateUri = "$ServiceNowBaseUri/api/now/table/kb_article_template?sysparm_query=name=$templateName&sysparm_limit=1"

$templateResponse = Invoke-WebRequest -Headers $headers -Method 'GET' -Uri $templateUri -ErrorAction Stop
$templateResult = ($templateResponse.Content | ConvertFrom-Json).result

if ($templateResult.Count -eq 0) {
Write-Host "Template not found: $templateName"
return 1
}

$templateSysId = $templateResult[0].sys_id

 

 

Using your code for point#2:

 

$templateFieldsUri = "$ServiceNowBaseUri/api/now/table/kb_article_template_definition?sysparm_query=kb_article_template=$templateSysId"

$templateFieldsResponse = Invoke-WebRequest -Headers $headers -Method 'GET' -Uri $templateFieldsUri -ErrorAction Stop
$templateFieldsResult = ($templateFieldsResponse.Content | ConvertFrom-Json).result

 

 


Hope that helps!