Configure SIM settings
- Last Updated: May 1, 2026
- 6 minute read
- Semaphore
- Documentation
This sample PowerShell script automates the configuration of SIM (Semaphore Intelligent Metadata) field settings for a SharePoint list or content type via the Progress Data Cloud API. It is an alternative to manually configuring settings from the Library Settings or Site Content Types tabs in the Progress Data Cloud interface.
Script overview
The Configure-SimSettings.ps1 script applies SIM field configuration using a JSON settings file. It supports two modes:
- ByList: Resolves a Site Library ID for a given site URL and list ID, then posts the SIM settings to the list endpoint.
- ByContentType: Posts the SIM settings directly to a content type endpoint for a given site URL and content type ID.
The workflow is:
- Authenticates to the Progress Data Cloud using an API key.
- Validates and loads the JSON settings file.
- For ByList mode: resolves the Site Library ID via the PDC API.
- Posts the SIM field settings to the appropriate API endpoint.
- Outputs status messages for success or failure.
Prerequisites
Before running the script, ensure the following:
- Windows PowerShell 5.1 or PowerShell 7+.
- A valid Progress Data Cloud API key for an appropriately permissioned user. For information about API key management, see the API key management script in the Use Progress Data Cloud guide.
- A JSON settings file containing the SIM field configuration. See Settings file format for details.
- The site must already be deployed and configured in Progress Data Cloud.
Parameters
Shared parameters
| Parameter | Required | Description |
|---|---|---|
SettingsFile |
Yes | Path to a JSON file containing the SIM field configuration payload. |
CloudUrl |
Yes | The base URI of the Progress Data Cloud API (for example, https://tenant.data.progress.cloud). |
ApiKey |
Yes | The API key used to authenticate with Progress Data Cloud. |
SiteUrl |
Yes | The SharePoint site URL (for example, https://tenant.sharepoint.com/sites/Finance). |
ByList parameters
| Parameter | Required | Description |
|---|---|---|
ListId |
Yes | The SharePoint list GUID whose Site Library ID will be resolved and targeted for SIM configuration. |
ByContentType parameters
| Parameter | Required | Description |
|---|---|---|
ContentTypeId |
Yes | The SharePoint content type ID (for example, 0x0101...) to configure. |
Usage examples
Configure SIM settings for a list:
.\Configure-SimSettings.ps1 `
-SettingsFile .\sim-settings.json `
-CloudUrl 'https://tenant.data.progress.cloud' `
-ApiKey '***' `
-SiteUrl 'https://tenant.sharepoint.com/sites/Finance' `
-ListId '7b9c1f9a-1234-5678-9abc-def012345678' `
-Verbose
Configure SIM settings for a content type:
.\Configure-SimSettings.ps1 `
-SettingsFile .\sim-settings.json `
-CloudUrl 'https://tenant.data.progress.cloud' `
-ApiKey '***' `
-SiteUrl 'https://tenant.sharepoint.com/sites/Finance' `
-ContentTypeId '0x0101AABBCC' `
-Verbose
Preview actions without making changes (WhatIf):
.\Configure-SimSettings.ps1 `
-SettingsFile .\sim-settings.json `
-CloudUrl 'https://tenant.data.progress.cloud' `
-ApiKey '***' `
-SiteUrl 'https://tenant.sharepoint.com/sites/Finance' `
-ContentTypeId '0x0101AABBCC' `
-WhatIf
Important:
For enhanced security, consider storing your API key in a secure keystore rather than passing it as a plain text parameter. You can retrieve the key from your preferred secure storage solution (such as Azure Key Vault, HashiCorp Vault, or Windows Credential Manager).
Settings file format
Create a JSON file containing the SIM field configuration. For example:
{
"articleType": 0,
"bodyType": 0,
"classificationMode": 1,
"clusteringThreshold": null,
"clusteringType": 0,
"csServerId": "f35a8615-a8f2-47d2-a67a-5f0a80aaf250",
"displayName": "Test1",
"fieldId": "0c5f9765-3c37-4934-aca6-e2fc87c4c4d7",
"fieldType": "Note",
"inheritAdvancedOptions": false,
"selectedRulebaseClasses": [
"Vehicle"
],
"threshold": null
}
PowerShell script
<#
.SYNOPSIS
Configures SIM (Semaphore Intelligent Metadata) field settings either by SharePoint list or by
content type, using a settings JSON file and a cloud API.
.DESCRIPTION
This script applies SIM field configuration to a SharePoint field via the Progress Data Cloud API.
It supports two mutually exclusive parameter sets:
- **ByList**: Resolves a Site Library ID (for a given SiteUrl and ListId) and POSTs SIM settings
to /api/sim/list/{siteLibraryId}/field.
- **ByContentType**: Uses the given ContentTypeId and SiteUrl and POSTs SIM settings to
/api/sim/contenttype/{contentTypeId}/field?siteUrl={siteUrl}.
.PARAMETER SettingsFile
Path to a JSON file containing the SIM field configuration payload.
.PARAMETER CloudUrl
The base URI of the cloud API (e.g., https://tenant.data.progress.cloud).
.PARAMETER ApiKey
The API key used to connect to Progress Data Cloud for an appropriately permissioned user.
.PARAMETER SiteUrl
The SharePoint site URL (e.g., https://tenant.sharepoint.com/sites/Finance).
.PARAMETER ListId
(ByList only) The SharePoint list GUID whose Site Library ID will be resolved.
.PARAMETER ContentTypeId
(ByContentType only) The SharePoint content type ID (e.g., 0x0101...).
.INPUTS
None. This script does not accept pipeline input.
.OUTPUTS
Information, Warning, and Verbose messages.
.NOTES
- Requires Windows PowerShell 5.1 or PowerShell 7+.
- REST calls use retry logic with exponential backoff.
- The JSON in SettingsFile is sent as-is with ContentType = 'application/json'.
.EXAMPLE
PS> .\Configure-SimSettings.ps1 -SettingsFile .\sim-settings.json -CloudUrl 'https://tenant.data.progress.cloud' -ApiKey '***' -SiteUrl 'https://tenant.sharepoint.com/sites/Finance' -ListId '7b9c1f9a-1234-5678-9abc-def012345678'
Configures the SIM field settings for the specified list.
#>
#Requires -Version 5.1
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'ByList')]
param(
[Parameter(Mandatory, Position = 0, ParameterSetName = 'ByList')]
[Parameter(Mandatory, Position = 0, ParameterSetName = 'ByContentType')]
[ValidateNotNullOrEmpty()]
[ValidateScript({ Test-Path $_ -PathType Leaf })]
[string]$SettingsFile,
[Parameter(Mandatory, Position = 1, ParameterSetName = 'ByList')]
[Parameter(Mandatory, Position = 1, ParameterSetName = 'ByContentType')]
[ValidateNotNullOrEmpty()]
[uri]$CloudUrl,
[Parameter(Mandatory, Position = 2, ParameterSetName = 'ByList')]
[Parameter(Mandatory, Position = 2, ParameterSetName = 'ByContentType')]
[ValidateNotNullOrEmpty()]
[string]$ApiKey,
[Parameter(Mandatory, Position = 3, ParameterSetName = 'ByList')]
[Parameter(Mandatory, Position = 3, ParameterSetName = 'ByContentType')]
[ValidateNotNullOrEmpty()]
[uri]$SiteUrl,
[Parameter(Mandatory, Position = 4, ParameterSetName = 'ByList')]
[ValidateNotNullOrEmpty()]
[string]$ListId,
[Parameter(Mandatory, Position = 4, ParameterSetName = 'ByContentType')]
[ValidateNotNullOrEmpty()]
[string]$ContentTypeId
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Invoke-WithRetry {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[scriptblock]$ScriptBlock,
[int]$MaxAttempts = 3,
[int]$InitialDelaySeconds = 2
)
$attempt = 0
$delay = $InitialDelaySeconds
while ($attempt -lt $MaxAttempts) {
try {
return & $ScriptBlock
}
catch {
$attempt++
$statusCode = $null
try { $statusCode = $_.Exception.Response.StatusCode.Value__ } catch { }
Write-Verbose ("Attempt {0} failed{1}: {2}" -f $attempt,
($(if ($statusCode) { " (HTTP $statusCode)" } else { "" })), $_.Exception.Message)
if ($attempt -ge $MaxAttempts) {
throw
}
Start-Sleep -Seconds $delay
$delay = [math]::Min($delay * 2, 30)
}
}
}
function Get-CloudToken {
[CmdletBinding()]
param(
[Parameter(Mandatory)][uri]$BaseUrl,
[Parameter(Mandatory)][string]$ApiKey
)
$uri = [uri]::new($BaseUrl, '/token')
$body = @{
grant_type = 'apikey'
key = $ApiKey
}
$requestParams = @{
Method = 'Post'
ContentType = 'application/x-www-form-urlencoded'
Uri = $uri
Body = $body
ErrorAction = 'Stop'
}
Write-Verbose "Requesting token from $($uri.AbsoluteUri)"
$response = Invoke-WithRetry -ScriptBlock { Invoke-RestMethod @requestParams }
if (-not $response.access_token) { throw "Token response missing 'access_token'." }
return [string]$response.access_token
}
function New-AuthHeader {
[CmdletBinding()]
param([Parameter(Mandatory)][string]$Token)
return @{
Authorization = "Bearer $Token"
Accept = 'application/json'
}
}
function Get-SiteLibraryId {
[CmdletBinding()]
param(
[Parameter(Mandatory)][uri]$BaseUrl,
[Parameter(Mandatory)][hashtable]$Headers,
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$SiteUrl,
[Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$ListId
)
$eSite = [System.Net.WebUtility]::UrlEncode($SiteUrl)
$eList = [System.Net.WebUtility]::UrlEncode($ListId)
$relative = "/api/sitelibrary?listId=$eList&siteUrl=$eSite"
$uri = [uri]::new($BaseUrl, $relative)
$requestParams = @{
Method = 'Get'
Uri = $uri
Headers = $Headers
ErrorAction = 'Stop'
}
Write-Verbose "Resolving Site Library ID for listId=$ListId siteUrl=$SiteUrl"
$resp = Invoke-WithRetry -ScriptBlock { Invoke-RestMethod @requestParams }
if (-not $resp.id) { throw "Response missing 'id' for listId=$ListId." }
return [string]$resp.id
}
# --- Load and validate settings JSON ---
$settingsJson = Get-Content -Path $SettingsFile -Raw
try {
$null = $settingsJson | ConvertFrom-Json -Depth 10
}
catch {
throw "Settings file '$SettingsFile' is not valid JSON: $($_.Exception.Message)"
}
# --- Resolve base endpoint from parameter set ---
switch ($PSCmdlet.ParameterSetName) {
'ByList' { $baseEndpoint = '/api/sim/list' }
'ByContentType' { $baseEndpoint = '/api/sim/contenttype' }
default { throw "Invalid parameter set: $($PSCmdlet.ParameterSetName)" }
}
# --- Auth ---
try {
$token = Get-CloudToken -BaseUrl $CloudUrl -ApiKey $ApiKey
$header = New-AuthHeader -Token $token
}
catch {
Write-Error "Authentication failed: $($_.Exception.Message)"
exit 1
}
# --- Execute ---
if ($PSCmdlet.ParameterSetName -eq 'ByList') {
try {
$siteLibraryId = Get-SiteLibraryId -BaseUrl $CloudUrl -Headers $header `
-SiteUrl $SiteUrl.AbsoluteUri -ListId $ListId
$relative = "$baseEndpoint/$siteLibraryId/field"
$uri = [uri]::new($CloudUrl, $relative)
$req = @{
Method = 'Post'
Uri = $uri
Headers = $header
ContentType = 'application/json'
Body = $settingsJson
ErrorAction = 'Stop'
}
if ($PSCmdlet.ShouldProcess("SiteLibraryId=$siteLibraryId", 'Configure SIM settings')) {
Write-Verbose "Configuring SIM settings for site library $siteLibraryId"
Invoke-WithRetry -ScriptBlock { Invoke-RestMethod @req } | Out-Null
}
Write-Information "Configured SIM settings for SiteLibraryId=$siteLibraryId"
}
catch {
Write-Warning "Failed for ListId=$ListId at site $($SiteUrl.AbsoluteUri): $($_.Exception.Message)"
}
}
else {
try {
$ctId = [System.Net.WebUtility]::UrlEncode($ContentTypeId)
$relative = "$baseEndpoint/$ctId/field?siteUrl=$($SiteUrl.AbsoluteUri)"
$uri = [uri]::new($CloudUrl, $relative)
$req = @{
Method = 'Post'
Uri = $uri
Headers = $header
ContentType = 'application/json'
Body = $settingsJson
ErrorAction = 'Stop'
}
if ($PSCmdlet.ShouldProcess("ContentTypeId=$ContentTypeId", 'Configure SIM settings')) {
Write-Verbose "Configuring SIM settings for content type $ContentTypeId"
Invoke-WithRetry -ScriptBlock { Invoke-RestMethod @req } | Out-Null
}
Write-Information "Configured SIM settings for ContentTypeId=$ContentTypeId"
}
catch {
Write-Warning "Failed for ContentTypeId=$ContentTypeId at site $($SiteUrl.AbsoluteUri): $($_.Exception.Message)"
}
}