Admin API
The Admin API provides interfaces for user, profile, group, organisation, and permission management. In addition, templates and snippets (text modules) can be queried and managed. The endpoints are exposed as a versioned REST API under /api/v3/{datasourceId}/Admin/....
Authentication
In order to call the Admin APIs, such a client must be registered in the primedocs.config, see primedocs.config.
After registration, an AccessToken can be requested from the IdS.
This PowerShell example shows how to obtain the AccessToken:
# Configuration
$datasourceId = "b78c3707-d7c7-4fc7-b97f-87d70f63c1ac"
$tokenUrl = "https://{instanz}/ids/connect/token"
$clientID = "CustomApiClient"
$clientSecret = "CustomClient_Secret_123"
$scope = "pd_AdminWebApi"
$tokenRequestHeaders = @{
"Content-Type" = "application/x-www-form-urlencoded"
}
$tokenRequestBody = @{
client_id = $clientID
client_secret = $clientSecret
grant_type = "client_credentials"
scope = $scope
}
# Request the access token
try {
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method POST -Headers $tokenRequestHeaders -Body $tokenRequestBody
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
if (-not $tokenResponse.access_token) {
Write-Error "Failed to obtain an access token!"
exit 1
}
# Access token information
Write-Host "Access Token: $($tokenResponse.access_token)"
$accessToken = $tokenResponse.access_token
Query-Syntax
The Admin API offers typical "CRUD" (Create / Read / Update / Delete) endpoints as an HTTP API.
To search for specific data, the following GET endpoints offer a "query" parameter:
| HTTP GET-Endpoint | Description |
|---|---|
/api/v3/{datasourceId}/Admin/AppUserGroups | Returns a list of "AppUserGroups". |
/api/v3/{datasourceId}/Admin/Groups | Returns a list of "UserGroups". |
/api/v3/{datasourceId}/Admin/Users | Returns a list of "Users". |
/api/v3/{datasourceId}/Admin/Templates | Returns a list of "Templates". |
All of these APIs return paginated lists of data. Filtering/searching can be triggered using the "Query" parameter.
The syntax consists of [Property]:"[filter]" [AdditionalProperty]:"[additional filter]"...
" can be optionally placed around the filter, especially if spaces are part of the filter criteria.
Some properties support the * wildcard operator at the beginning and end.
The individual filters are linked with AND.
Example:
https://{instanz}/webapi/api/v3/{datasourceId}/Admin/Templates?query=localizedName:*brief%20active:true
Searches for all active templates whose name ends with "brief".
AppUserGroups
Possible "Query" options:
title: Search by title- Supports the
*wildcard operator at the beginning and end.
- Supports the
primarySid: Search by primarySid- Supports the
*wildcard operator at the beginning and end.
- Supports the
Example:
title:Admin primarySid:123* = Find all AppUserGroups that have the title "Admin" and start with the primarySid 123.
UserGroups
Possible "Query" options:
title: Search by title- Supports the
*wildcard operator at the beginning and end.
- Supports the
primarySid: Search by primarySid- Supports the
*wildcard operator at the beginning and end.
- Supports the
Example:
title:Admin primarySid:123* = Find all UserGroups that have the title "Admin" and start with the primarySid 123.
Users
Possible "Query" options:
title: Search by title- Supports the
*wildcard operator at the beginning and end.
- Supports the
primarySid: Search by primarySid- Supports the
*wildcard operator at the beginning and end.
- Supports the
field[<User.FieldId>]: Search for a configurable user field (e.g.field[User.FirstName])- Supports the
*wildcard operator at the beginning and end.
- Supports the
Example:
title:"John*" Field[User.EmailField]:"*foobar.com" = Search for all Users whose title begins with "John" and whose email address in the User.EmailField field ends with foobar.com.
Templates
Possible "Query" options:
templateId: Search by TemplateId- Must be a GUID.
metaTemplateId: Search by MetaTemplateId- Must be a GUID.
active: Search for active/inactive (deleted) templates- Must be a Bool (
True,False).
- Must be a Bool (
templatestate: Search for the template status- Supported: 0 (=
InProgress), 1 (=InTest), 2 (=Released)
- Supported: 0 (=
templateGroupId: Search for the parent template group- Must be a GUID.
localizedName: Search by name.- Supports the
*wildcard operator at the beginning and end.
- Supports the
localizedDescription: Search by description.- Supports the
*wildcard operator at the beginning and end.
- Supports the
tags: Search by tags- AND link via
;and OR link via|. (ExampleTAG1;TAG2;TAG3|TAG4)
- AND link via
Example:
active:true tags:ProjectX;Finance|Controlling = Search for all active Templates that are either tagged with ProjectX and Finance or that have the tag Controlling.
Examples
This AccessToken must be included in the Authorization header for all calls. The API allows, among other things, listing, creating, and editing users, profiles, groups, organizational units, and snippet groups, as well as querying templates and AppUserGroups. Examples can be found below:
List users
This lists existing users:
# Prepare headers for request
$apiRequestHeaders = @{
"Authorization" = "Bearer $accessToken"
}
Write-Host "Getting users..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
try {
$apiUrl = "https://{instanz}/webapi/api/v3/$($datasourceId)/Admin/Users?pageSize=$($pageSize)&page=$($page)"
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($user in $response.data) {
Write-Output "$($user.id): '$($user.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
User onboarding
This call can be used to add a new user using the SID. The User Onboarding & Offboarding process is then run automatically.
# Prepare headers for request
$apiRequestHeaders = @{
"Authorization" = "Bearer $accessToken"
}
$sid = Read-Host "Enter SID"
Write-Host "Creating and onboarding user with SID: $sid"
try {
$apiUrl = "https://{instanz}/webapi/api/v3/$($datasourceId)/Admin/Users?sid=" + $sid;
$user = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $apiRequestHeaders
Write-Output "Onboarded '$($user.title)' with id '$($user.id)'";
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
PowerShell Script
Below you will find a complete example PowerShell script that covers various use cases: users, profiles and profile shares, groups, organizational units, snippet groups (incl. permissions and localizations), AppUserGroups, and templates.
The Configuration section (datasourceId, tokenUrl, baseApiUrl, clientId and clientSecret) must be changed to the settings of your environment.
# Configuration
$datasourceId = "b78c3707-d7c7-4fc7-b97f-87d70f63c1ac"
$tokenUrl = "https://{instanz}/ids/connect/token"
$baseApiUrl = "https://{instanz}/webapi/api"
$clientID = "CustomApiClient"
$clientSecret = "CustomClient_Secret_123"
$scope = "pd_AdminWebApi"
$tokenRequestHeaders = @{
"Content-Type" = "application/x-www-form-urlencoded"
}
$tokenRequestBody = @{
client_id = $clientID
client_secret = $clientSecret
grant_type = "client_credentials"
scope = $scope
}
# Request the access token
try {
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method POST -Headers $tokenRequestHeaders -Body $tokenRequestBody
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
if (-not $tokenResponse.access_token) {
Write-Error "Failed to obtain an access token!"
exit 1
}
# Access token information
Write-Host "Access Token: $($tokenResponse.access_token)"
$accessToken = $tokenResponse.access_token
# Prepare headers for request
$apiRequestHeaders = @{
"Authorization" = "Bearer $accessToken"
}
$putBodyRequestHeaders = @{
"Content-Type" = "application/json"
"Authorization" = "Bearer $accessToken"
}
function Show-Menu {
Write-Host "================ Main Menu ================"
Write-Host "1: Get Users"
Write-Host "2: Get User Details"
Write-Host "3: Update User"
Write-Host "4: Create and Onboard User"
Write-Host "5: Get Profile"
Write-Host "6: Profile Update"
Write-Host "7: Add Profile Share"
Write-Host "8: Delete Profile Share"
Write-Host "9: Create and Onboard Group"
Write-Host "10: Get Groups"
Write-Host "11: Get Organization Units"
Write-Host "12: Get Organization Unit Details"
Write-Host "13: Get Organization Unit Children"
Write-Host "14: Update Organization Unit"
Write-Host "15: Create Organization Unit"
Write-Host "16: Delete Organization Unit"
Write-Host "29: Get Organization Unit Tree"
Write-Host "17: Get Snippet Groups"
Write-Host "18: Get Snippet Group Details"
Write-Host "19: Create Snippet Group"
Write-Host "20: Delete Snippet Group"
Write-Host "21: Get Snippet Group Children"
Write-Host "22: Update Snippet Group ParentId or Sort"
Write-Host "23: Delete Snippet Group Permission"
Write-Host "24: Add Snippet Group Permission"
Write-Host "25: Delete Snippet Group Localization"
Write-Host "26: Add Snippet Group Localization"
Write-Host "27: Get AppUserGroups"
Write-Host "28: Get Templates"
Write-Host "Q: Exit"
}
function GetUsers {
Write-Host "Getting users..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$query = Read-Host "Enter query"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users?pageSize=$($pageSize)&page=$($page)"
# Append query only if it's not null or whitespace
if (![string]::IsNullOrWhiteSpace($query)) {
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($user in $response.data) {
Write-Output "$($user.id): '$($user.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetUserDetails {
$userId = Read-Host "Enter UserId"
Write-Host "Getting details for user: $userId"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/" + $userId;
$user = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
Write-Output "Id: '$($user.id)'"
Write-Output "Title: '$($user.title)'";
Write-Output "Profiles: "
foreach ($profile in $user.profiles) {
Write-Output "'$($profile.id)': '$($profile.title) (Profile OU: '$($profile.organizationUnitId)')"
}
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function CreateAndOnBoardUser {
$sid = Read-Host "Enter SID"
Write-Host "Creating and onboarding user with SID: $sid"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users?sid=" + $sid;
$user = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $apiRequestHeaders
Write-Output "Onboarded '$($user.title)' with id '$($user.id)'";
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function CreateAndOnBoardGroup {
$sid = Read-Host "Enter SID"
Write-Host "Creating and onboarding Group with SID: $sid"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Groups?sid=" + $sid;
$group = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $apiRequestHeaders
Write-Output "Onboarded '$($group.title)' with id '$($group.id)'";
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetGroups {
Write-Host "Getting Groups..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$query = Read-Host "Enter query"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Groups?pageSize=$($pageSize)&page=$($page)"
# Append query only if it's not null or whitespace
if (![string]::IsNullOrWhiteSpace($query)) {
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($group in $response.data) {
Write-Output "$($group.id): '$($group.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetAppUserGroups {
Write-Host "Getting AppUserGroups..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$query = Read-Host "Enter query"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/AppUserGroups?pageSize=$($pageSize)&page=$($page)"
# Append query only if it's not null or whitespace
if (![string]::IsNullOrWhiteSpace($query)) {
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($group in $response.data) {
Write-Output "$($group.id): '$($group.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetTemplates {
Write-Host "Getting Templates..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$query = Read-Host "Enter query"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Templates?pageSize=$($pageSize)&page=$($page)"
# Append query only if it's not null or whitespace
if (![string]::IsNullOrWhiteSpace($query)) {
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($template in $response.data) {
Write-Output "$($template.templateId): MetaTemplateId: '$($template.metaTemplateId)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function ProfileUpdate {
$userId = Read-Host "Enter User ID"
$profileId = Read-Host "Enter Profile ID"
$title = Read-Host "Enter Title"
$organizationUnitId = Read-Host "Enter New Organization Unit ID"
$lcid = 1031 #Read-Host "Enter lcid"
$field = "Org.Title" # Read-Host "Enter Field"
$field2 = "User.FirstName" # Read-Host "Enter Field"
$text = Read-Host "Enter New Org.Title Value (Empty = delete)"
$text2 = Read-Host "Enter New User.FirstName Value (Empty = delete)"
Write-Host "Updating profile for User ID: $userId, Profile ID: $profileId, Title: $title, Organization Unit ID: $organizationUnitId"
$targetOrganizationUnitId = if ($null -ne $organizationUnitId) {
[System.Guid]::Parse($organizationUnitId)
} else {
$null
}
try {
$body = @{
Title = $title;
OrganizationUnitId = $targetOrganizationUnitId;
FieldChanges = @(
@{
Lcid = $lcid
Field = $field
Text = $text
Purge = ($text -eq "")
},
@{
Lcid = $lcid
Field = $field2
Text = $text2
Purge = ($text2 -eq "")
}
)
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/$($userId)/Profiles/$($profileId)";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method PUT -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetProfile {
$userId = Read-Host "Enter User ID"
$profileId = Read-Host "Enter Profile ID"
Write-Host "Getting profile for User ID: $userId, Profile ID: $profileId"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/" + $userId + "/Profiles/" + $profileId;
$userProfile = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
Write-Output "Id: '$($userProfile.id)'"
Write-Output "Title: '$($userProfile.title)'";
Write-Output "ProfileShares: "
foreach ($share in $userProfile.profileShares) {
if ($null -ne $share.userId) {
Write-Output "'$($share.id)': UserId:'$($share.userId)', ProfilePermissionLevel:'$($share.profilePermissionLevel)', SignaturePermissionLevel:'$($share.signaturePermissionLevel)'"
}
if ($null -ne $share.groupId) {
Write-Output "'$($share.id)': GroupId:'$($share.groupId)', ProfilePermissionLevel:'$($share.profilePermissionLevel)', SignaturePermissionLevel:'$($share.signaturePermissionLevel)'"
}
if ($null -ne $share.appUserGroupId) {
Write-Output "'$($share.id)': AppUserGroupId:'$($share.appUserGroupId)', ProfilePermissionLevel:'$($share.profilePermissionLevel)', SignaturePermissionLevel:'$($share.signaturePermissionLevel)'"
}
}
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function AddProfileShare {
$userId = Read-Host "Enter User ID"
$profileId = Read-Host "Enter Profile ID"
Write-Host "Enter either User ID or Group ID or AppUserGroup ID to access the profile. Leave two of them empty."
$shareUserId = Read-Host "Enter User ID (or empty)"
$shareGroupId = Read-Host "Enter Group ID (or empty)"
$shareAppUserGroupId = Read-Host "Enter AppUserGroup ID (or empty)"
Write-Host " "
Write-Host "0: Profile share cannot be used as 'regular' profile"
Write-Host "1: Profile share can be used as 'regular' profile, but will be marked 'on behalf'"
Write-Host "2: Profile share can be used as 'regular' profile and impersonation is allowed"
$profilePermissionLevel = Read-Host "Enter Profile Permission Level"
Write-Host " "
Write-Host "0: Signature share cannot be used for document signing"
Write-Host "1: Signature share can be used for document signing, but without real signature image"
Write-Host "2: Signature share can be used for document signing with real signature image"
$signaturePermissionLevel = Read-Host "Enter Signature Permission Level"
$targetShareUserId = if ($shareUserId -eq "") {
$null
} else {
$shareUserId
}
$targetShareGroupId = if ($shareGroupId -eq "") {
$null
} else {
$shareGroupId
}
$targetShareAppUserGroupId = if ($shareAppUserGroupId -eq "") {
$null
} else {
$shareAppUserGroupId
}
try {
$body = @{
UserId = $targetShareUserId
GroupId = $targetShareGroupId
AppUserGroupId = $targetShareAppUserGroupId
profilePermissionLevel = $profilePermissionLevel
signaturePermissionLevel = $signaturePermissionLevel
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/$($userId)/Profiles/$($profileId)/ProfileShares";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function DeleteProfileShare {
$userId = Read-Host "Enter User ID"
$profileId = Read-Host "Enter Profile ID"
$profileShareId = Read-Host "Enter Profile Share ID"
Write-Host "Deleting profile share for User ID: $userId, Profile ID: $profileId, Profile Share ID: $profileShareId"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/$($userId)/Profiles/$($profileId)/ProfileShares/$($profileShareId)";
Invoke-RestMethod -Uri $apiUrl -Method DELETE -Headers $putBodyRequestHeaders
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetOrganizationUnits {
Write-Host "Getting organization units..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$query = Read-Host "Enter query (optional, e.g. title:*Sales* or sid:OU-123)"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits?pageSize=$($pageSize)&page=$($page)";
# Append query only if it's not null or whitespace
if (![string]::IsNullOrWhiteSpace($query)) {
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($organizationUnit in $response.data) {
Write-Output "$($organizationUnit.id): '$($organizationUnit.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetOrganizationUnitDetails {
$organizationUnitId = Read-Host "Enter Organization Unit ID"
Write-Host "Getting details for organization unit: $organizationUnitId"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits/" + $organizationUnitId;
$organizationUnit = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
Write-Output "Id: '$($organizationUnit.id)'"
Write-Output "Title: '$($organizationUnit.title)'";
Write-Output "ParentId: '$($organizationUnit.parentId)'";
Write-Output "Fields:";
foreach ($field in $organizationUnit.fields) {
$inherited = if ($field.isInherited) { " (inherited)" } else { "" }
Write-Output " [$($field.lcid)] $($field.fieldId): '$($field.text)'$inherited"
}
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetOrganizationUnitChildren {
$organizationUnitId = Read-Host "Enter Organization Unit ID"
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
$searchTerm = Read-Host "Enter title search term (optional)"
Write-Host "Getting children for organization unit: $organizationUnitId"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits/" + $organizationUnitId + "/Children?pageSize=$($pageSize)&page=$($page)";
if (![string]::IsNullOrWhiteSpace($searchTerm)) {
$query = [System.Uri]::EscapeDataString("title:*$searchTerm*")
$apiUrl += "&query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($organizationUnit in $response.data) {
Write-Output "$($organizationUnit.id): '$($organizationUnit.title)'"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetOrganizationUnitTree {
$searchTerm = Read-Host "Enter title search term (optional)"
Write-Host "Getting organization unit tree..."
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnitTree"
if (![string]::IsNullOrWhiteSpace($searchTerm)) {
$query = [System.Uri]::EscapeDataString("title:*$searchTerm*")
$apiUrl += "?query=$query"
}
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
$response | ConvertTo-Json -Depth 10
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function UpdateOrganizationUnit {
Write-Host "Updating organization unit"
$organizationUnitId = Read-Host "Enter Organization Unit ID"
$title = Read-Host "Enter New Title"
$parentId = Read-Host "Enter New Parent Organization Unit ID"
$sid = Read-Host "Enter New SID"
$lcid = 1031 #Read-Host "Enter lcid"
$field = "Org.Title" # Read-Host "Enter Field"
$field2 = "Org.Claim" # Read-Host "Enter Field"
$text = Read-Host "Enter New Org.Title Value (Empty = delete)"
$text2 = Read-Host "Enter New Org.Claim Value (Empty = delete)"
Write-Host "Updating organization unit, Title: $title, Organization Unit ID: $organizationUnitId"
$targetParentId = if ($null -ne $parentId) {
[System.Guid]::Parse($parentId)
} else {
$null
}
try {
$body = @{
Title = $title
ParentId = $targetParentId
Sid = $sid
FieldChanges = @(
@{
Lcid = $lcid
Field = $field
Text = $text
Purge = ($text -eq "")
},
@{
Lcid = $lcid
Field = $field2
Text = $text2
Purge = ($text2 -eq "")
}
)
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits/$($organizationUnitId)";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method PUT -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function CreateOrganizationUnit {
Write-Host "Creating organization unit"
$title = Read-Host "Enter Title"
$parentId = Read-Host "Enter Parent Organization Unit ID (leave empty for root)"
$sid = Read-Host "Enter SID (optional, leave empty to create without SID)"
$lcid = 1031 #Read-Host "Enter lcid"
$field = "Org.Title" # Read-Host "Enter Field"
$text = Read-Host "Enter Org.Title Value (leave empty to skip)"
$targetParentId = if (![string]::IsNullOrWhiteSpace($parentId)) {
[System.Guid]::Parse($parentId)
} else {
$null
}
$targetSid = if (![string]::IsNullOrWhiteSpace($sid)) { $sid } else { $null }
$fields = @()
if (![string]::IsNullOrWhiteSpace($text)) {
$fields += @{
Lcid = $lcid
Field = $field
Text = $text
}
}
try {
$body = @{
Title = $title
ParentId = $targetParentId
Sid = $targetSid
Fields = $fields
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
$newId = Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
Write-Output "Created OrganizationUnit with ID: $newId"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function DeleteOrganizationUnit {
Write-Host "Deleting organization unit"
$organizationUnitId = Read-Host "Enter Organization Unit ID"
$deleteChildrenInput = Read-Host "Delete children as well? (y/n, default: n)"
$deleteChildren = ($deleteChildrenInput -eq "y")
Write-Host "Deleting organization unit: $organizationUnitId (deleteChildren: $deleteChildren)"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/OrganizationUnits/$($organizationUnitId)?deleteChildren=$($deleteChildren)";
Invoke-RestMethod -Uri $apiUrl -Method DELETE -Headers $apiRequestHeaders
Write-Output "Deleted OrganizationUnit: $organizationUnitId"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function UpdateUser {
$userId = Read-Host "Enter User ID"
$title = Read-Host "Enter New Title"
$lcid = 1031 #Read-Host "Enter lcid"
$field = "User.FirstName" # Read-Host "Enter Field"
$field2 = "User.LastName" # Read-Host "Enter Field"
$text = Read-Host "Enter New User.FirstName Value (Empty = delete)"
$text2 = Read-Host "Enter New User.LastName Value (Empty = delete)"
Write-Host "Updating user, Title: $title, User ID: $userId"
try {
$body = @{
Title = $title
FieldChanges = @(
@{
Lcid = $lcid
Field = $field
Text = $text
Purge = ($text -eq "")
},
@{
Lcid = $lcid
Field = $field2
Text = $text2
Purge = ($text2 -eq "")
}
)
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/Users/$($userId)";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method PUT -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetSnippetGroups {
Write-Host "Getting snippet groups (public)..."
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/?pageSize=$($pageSize)&page=$($page)";
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($snippetGroup in $response.data) {
Write-Output "$($snippetGroup.id)"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetSnippetGroupsChildren {
Write-Host "Getting snippet groups (public)..."
$parentSnippetGroup = Read-Host "Enter Parent Snippet Group"
$pageSize = Read-Host "Enter pagesize"
$page = Read-Host "Enter page"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($parentSnippetGroup)/SnippetGroups?pageSize=$($pageSize)&page=$($page)";
$response = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
foreach ($snippetGroup in $response.data) {
Write-Output "$($snippetGroup.id)"
}
Write-Output "Page: $($response.pagingDetails.page) / $($response.pagingDetails.totalPages)"
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function GetSnippetGroupDetails {
Write-Host "Getting snippet groups (public) for id..."
$snippetGroup = Read-Host "Enter Snippet Group ID"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($snippetGroup)";
$snippetGroup = Invoke-RestMethod -Uri $apiUrl -Method GET -Headers $apiRequestHeaders
Write-Output "Id: '$($snippetGroup.id)'"
Write-Output "ParentId: '$($snippetGroup.parentId)'"
Write-Output "Sort: '$($snippetGroup.sort)'"
Write-Output "Localized Data:"
foreach ($localized in $snippetGroup.localized) {
Write-Output "Localized '$($localized.lcid)': Name '$($localized.name)' | Description '$($localized.description)' | SearchKeywords '$($localized.searchkeywords)'"
}
Write-Output "Permissions:"
foreach ($permission in $snippetGroup.permissions) {
Write-Output "Permission '$($permission.id)': UserId '$($permission.userId)' | GroupId '$($permission.groupid)' | AppUserGroupId '$($permission.appUserGroupId)' | HasModifyPermission: '$($permission.HasModifyPermission)' | HasUsingPermission: '$($permission.HasUsingPermission)'"
}
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function CreateSnippetGroup {
$parentId = Read-Host "Enter Snippet Parent Id (or empty)"
Write-Host "Enter either User ID or Group ID or AppUserGroup ID to give use and modify permission on the snippetgroup. Leave two of them empty."
$shareUserId = Read-Host "Enter User ID (or empty)"
$shareGroupId = Read-Host "Enter Group ID (or empty)"
$shareAppUserGroupId = Read-Host "Enter AppUserGroup ID (or empty)"
$targetShareUserId = if ($shareUserId -eq "") {
$null
} else {
$shareUserId
}
$targetShareGroupId = if ($shareGroupId -eq "") {
$null
} else {
$shareGroupId
}
$targetShareAppUserGroupId = if ($shareAppUserGroupId -eq "") {
$null
} else {
$shareAppUserGroupId
}
$targetParentSnippetGroupId = if ($parentId -eq "") {
$null
} else {
[System.Guid]::Parse($parentId)
}
$lcid = Read-Host "Enter lcid"
$name = Read-Host "Enter Sample Name"
# Sort can also be applied
try {
$body = @{
ParentId = $targetParentSnippetGroupId
Localized = @(
@{
Lcid = $lcid
Name = $name
}
)
Permissions = @(
@{
UserId = $targetShareUserId
GroupId = $targetShareGroupId
AppUserGroupId = $targetShareAppUserGroupId
HasModifyPermission = $true
HasUsingPermission = $true
}
)
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function DeleteSnippetGroup {
$snippetGroup = Read-Host "Enter SnippetGroup ID"
Write-Host "Deleting public snippet group (and everything below) for Snippet Group ID: $snippetGroup"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($snippetGroup)";
Invoke-RestMethod -Uri $apiUrl -Method DELETE -Headers $putBodyRequestHeaders
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function UpdateSnippetGroup {
$targetSnippetGroup = Read-Host "Enter Snippet Group Id which needs to be updated"
$parentId = Read-Host "Enter new Snippet Group Parent Id"
$sort = Read-Host "Enter Sort"
$targetParentSnippetGroupId = if ($parentId -eq "") {
$null
} else {
[System.Guid]::Parse($parentId)
}
try {
$body = @{
ParentId = $targetParentSnippetGroupId
Sort = $sort
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($targetSnippetGroup)";
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method PUT -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function DeleteSnippetGroupPermission {
$targetSnippetGroup = Read-Host "Enter Snippet Group Id which needs to be updated"
$targetSnippetGroupPermissionId = Read-Host "Enter Permission Id"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($targetSnippetGroup)/Permissions/$($targetSnippetGroupPermissionId)";
Invoke-RestMethod -Uri $apiUrl -Method DELETE -Headers $putBodyRequestHeaders
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function AddSnippetGroupPermission {
$targetSnippetGroupId = Read-Host "Enter Snippet Group Id"
Write-Host "Enter either User ID or Group ID or AppUserGroup ID to give use and modify permission on the snippetgroup. Leave two of them empty."
$shareUserId = Read-Host "Enter User ID (or empty)"
$shareGroupId = Read-Host "Enter Group ID (or empty)"
$shareAppUserGroupId = Read-Host "Enter AppUserGroup ID (or empty)"
$targetShareUserId = if ($shareUserId -eq "") {
$null
} else {
$shareUserId
}
$targetShareGroupId = if ($shareGroupId -eq "") {
$null
} else {
$shareGroupId
}
$targetShareAppUserGroupId = if ($shareAppUserGroupId -eq "") {
$null
} else {
$shareAppUserGroupId
}
try {
$body = @{
UserId = $targetShareUserId
GroupId = $targetShareGroupId
AppUserGroupId = $targetShareAppUserGroupId
HasModifyPermission = $true
HasUsingPermission = $true
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($targetSnippetGroupId)/Permissions"
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function DeleteSnippetGroupLocalization {
$targetSnippetGroup = Read-Host "Enter Snippet Group Id which needs to be updated"
$targetSnippetGroupLcid = Read-Host "Enter Localization LCID"
try {
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($targetSnippetGroup)/Localized/$($targetSnippetGroupLcid)";
Invoke-RestMethod -Uri $apiUrl -Method DELETE -Headers $putBodyRequestHeaders
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
function AddSnippetGroupLocalization {
$targetSnippetGroupId = Read-Host "Enter Snippet Group Id"
$lcid = Read-Host "Enter lcid"
$name = Read-Host "Enter Name"
$description = Read-Host "Enter Description"
$searchKeyWord = Read-Host "Enter SearchKeywords"
try {
$body = @{
Lcid = $lcid
Name = $name
Description = $description
SearchKeywords = $searchKeyWord
}
$apiUrl = "$($baseApiUrl)/v3/$($datasourceId)/Admin/SnippetGroups/Public/$($targetSnippetGroupId)/Localized"
# Ensure UTF-8 Encoding
$utf8body = ([System.Text.Encoding]::UTF8.GetBytes(($body | ConvertTo-Json)))
Invoke-RestMethod -Uri $apiUrl -Method POST -Headers $putBodyRequestHeaders -Body $utf8body
}
catch {
Write-Error "Error making the request: $_"
exit 1;
}
}
do {
Show-Menu
$selection = Read-Host "Please select an option"
switch ($selection) {
'1' { GetUsers }
'2' { GetUserDetails }
'3' { UpdateUser }
'4' { CreateAndOnBoardUser }
'5' { GetProfile }
'6' { ProfileUpdate }
'7' { AddProfileShare }
'8' { DeleteProfileShare }
'9' { CreateAndOnBoardGroup }
'10' { GetGroups }
'11' { GetOrganizationUnits }
'12' { GetOrganizationUnitDetails }
'13' { GetOrganizationUnitChildren }
'14' { UpdateOrganizationUnit }
'15' { CreateOrganizationUnit }
'16' { DeleteOrganizationUnit }
'29' { GetOrganizationUnitTree }
'17' { GetSnippetGroups }
'18' { GetSnippetGroupDetails }
'19' { CreateSnippetGroup }
'20' { DeleteSnippetGroup }
'21' { GetSnippetGroupsChildren }
'22' { UpdateSnippetGroup }
'23' { DeleteSnippetGroupPermission }
'24' { AddSnippetGroupPermission }
'25' { DeleteSnippetGroupLocalization }
'26' { AddSnippetGroupLocalization }
'27' { GetAppUserGroups }
'28' { GetTemplates }
'Q' { break; }
Default {
Write-Host "Invalid option selected"
}
}
} while ($selection -ne 'Q')
Swagger / Open API
The current Admin API Open API can be used as a reference, for example from the PrimeSoft instance:
https://primesoft.primedocs.io/webapi/swagger/index.html
You can visualise this description using the Swagger Editor, for example.