We're reclaiming inactive PDIs to keep them available for active builders. Learn what's changing, who's affected, and how to protect your work. Read More

Script to create article from KM article template

mhashemi
Mega 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
Tera Sage

Hello @mhashemi 

 

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!