Git Product home page Git Product logo

helloid-conn-prov-target-topdesk's Introduction

HelloID-Conn-Prov-Target-Topdesk

⚠️ Warning
This script is for the new powershell connector. Make sure to use the mapping and correlation keys like mentionded in this readme. For more information, please read our documentation
ℹ️ Information
This repository contains the connector and configuration code only. The implementer is responsible to acquire the connection details such as username, password, certificate, etc. You might even need to sign a contract or agreement with the supplier before implementing this connector. Please contact the client's application manager to coordinate the connector requirements.

Table of contents

Introduction

HelloID-Conn-Prov-Target-Topdesk is a target connector. Topdesk provides a set of REST APIs that allow you to programmatically interact with its data. The Topdesk API documentation provides details of API commands that are used.

Getting started

Prerequisites

⚠️ Warning
When changes or incidents are in scope, a helloID agent on-premise is required. For cloud only changes or incidents use the HelloID Topdesk notification system
  • Archiving reason that is configured in Topdesk
  • Credentials with the rights as described in permissions

Connection settings

The following settings are required to connect to the API.

Setting Description Mandatory
BaseUrl The URL to the API Yes
UserName The UserName to connect to the API Yes
Password The Password to connect to the API Yes
Notification file path Location of the JSON file needed for changes or incidents No
Archiving reason Fill in an archiving reason that is configured in Topdesk Yes
Fallback email When a manager is set as the requester (in the JSON file) but the manager account reference is empty No
Toggle debug logging Creates extra logging for debug purposes Yes
Do not create changes or incidents If enabled no changes or incidents will be created in Topdesk Yes
When no item is found in Topdesk Stop processing and generate an error or keep the current value and continue. For example, when no budgetholder or department is found in Topdesk. Yes
When no department in source data Stop processing and generate an error or clear the department field in Topdesk Yes
When no budgetholder in source data Stop processing and generate an error or clear the budgetholder field in Topdesk Yes

Permissions

The following permissions are required to use this connector. This should be configured on a specific Permission Group for the Operator HelloID uses.

Permission Read Write Create Archive
Call Management
First line calls x x x
Second line calls x x x
Escalate calls x
Link object to call x
Link room to call x
Change Management
Requests for Simple Change x x x
Requests for Extensive Change x x x
Simple Changes x x
Extensive Changes x x
New Asset Management
Templates x
Supporting Files
Persons x x x x
Operators x x x x
Operator groups x
Suppliers x
Rooms x
Login data x
Supporting Files Settings x x
Reporting API
REST API x
Use application passwords x

Filters

ℹ️ Information
It is possible to set filters in Topdesk. If you don't get a result from Topdesk when expecting one it is probably because filters are used. For example, searching for a branch that can't be found by the API user but is visible in Topdesk.

Setup the connector

Mapping

The mandatory and recommended field mapping is listed below.

ℹ️ Information
Only mapped values to the actions create, update, and delete are being used in the script. The Enable and Disable will only Unarchive and Archive the person.
Name Create Enable Update Disable Delete Store in account data Default mapping Mandatory Comment
branch.lookupValue X X Field: PrimaryContract.Location.Name Lookupvalue
budgetHolder.lookupValue X X Field: PrimaryContract.CostCenter.Name Lookupvalue
department.lookupValue X X Field: PrimaryContract.Department.DisplayName Lookupvalue
email X X X Create/Update: Complex email.js Delete Fixed empty
employeeNumber X X Field: ExternalId Yes Used for correlation
firstInitials X X Complex: firstInitials.js
firstName X X Field: Name.NickName
gender X X Complex: gender.js
id X X Yes None Yes Writes back the account Refference to account data
isManager X Fixed: false Oprtionaly boolean: $p.Custom.isManager when provided by the source
jobTitle X X Field: PrimaryContract.Title.Name
manager.id X X None Yes Used in PowerShell script for ManagerAccountRefference and fallback
networkLoginName X X X Create/Update: Complex networkLoginName.js Delete Fixed empty
prefixes X X Complex: prefixes.js
showAllBranches X X Fixed: true
surName X X Complex: surName.js
tasLoginName X X X Create/Update: Complex tasLoginName.js Delete Fixed empty

Extra fields

You can add extra fields by adding them to the field mapping. For all possible options please check the Topdesk API documentation.

Name Create Enable Update Disable Delete Store in account data Default mapping Mandatory Comment
mobileNumber X X Field: Contact.Business.Phone.Mobile

Correlation

It is mandatory to enable the correlation in the correlation tab. The default value for "person correlation field" is " ExternalId". The default value for "Account Correlation field" is "employeeNumber".

Remove attributes when updating a Topdesk person

There is an example of only set certain attributes when correlate-update a person, but skipping them when updating the person. For example, if you don't want to update the tasLoginName.

    if (-not($actionContext.AccountCorrelated -eq $true)) {
        # Example to only set certain attributes when create-correlate. If you don't want to update certain values, you need to remove them here.    
        # $account.PSObject.Properties.Remove('email')
        # $account.PSObject.Properties.Remove('networkLoginName')
        # $account.PSObject.Properties.Remove('tasLoginName')
    }

Disable department or budgetholder

The fields department and budgetholder are both non-required lookup fields in Topdesk. This means you first need to look up the field and then use the returned GUID (ID) to set the Topdesk person.

For example:

"id": "90ee5493-027d-4cda-8b41-8325130040c3",
"name": "EnYoi Holding B.V.",
"externalLinks": []

If you don't need the mapping of the department field or the budgetholder field in Topdesk, it's necessary to comment out the function in the script.

Example for the department field:

# Resolve department id
# $splatParamsDepartment = @{
#     Account                 = [ref]$account
#     Headers                 = $authHeaders
#     BaseUrl                 = $actionContext.Configuration.baseUrl
#     LookupErrorHrDepartment = $actionContext.Configuration.lookupErrorHrDepartment
#     LookupErrorTopdesk      = $actionContext.Configuration.lookupErrorTopdesk
# }
# Get-TopdeskDepartment @splatParamsDepartment  

Changes

It is possible to create changes in Topdesk when granting or revoking an entitlement in HelloID. The content of the changes is managed in a JSON file. The local HelloID agent needs to read this file.

Please map the correct account mapping in change_permissions_grant.ps1 and change_permissions_revoke.ps1. If used in the JSON file.

# Map the account variables used in the JSON
$account = @{
    userPrincipalName = $personContext.Person.Accounts.MicrosoftActiveDirectory.userPrincipalName
    sAMAccountName    = $personContext.Person.Accounts.MicrosoftActiveDirectory.sAMAccountName
    mail              = $personContext.Person.Accounts.MicrosoftActiveDirectory.mail
}

Please use the change_example.json as a template to build you're own.

The change JSON file has the following structure:

{
	"Identification": {
		"Id": "C001"
	},
	"DisplayName": "Aanvraag/Inname laptop",
	"Grant": {
		"Requester": "[email protected]",
		"Request": "Graag een laptop gereed maken voor onderstaande medewerker.\n\nNaam: $($p.Name.NickName)\nAchternaam: $($p.Name.FamilyName)\nuserPrincipalName: $($account.userPrincipalName)\nsAMAccountName: $($account.sAMAccountName)\nPersoneelsnummer: $($p.ExternalId)\n\nFunctie: $($p.PrimaryContract.Title.Name)\nAfdeling: $($p.PrimaryContract.Department.DisplayName)",
		"Action": null,
		"BriefDescription": "Aanvraag Laptop ($($p.displayName))",
		"Template": "Ws 006",
		"Category": "Middelen",
		"SubCategory": "Inventaris & apparatuur",
		"ChangeType": "Simple",
		"Impact": "Persoon",
		"Benefit": null,
		"Priority": "P1"
	},
	"Revoke": {
		"Requester": "Employee",
		"Request": "Volgens onze informatie is onderstaande medewerker in het bezit van een laptop, deze dient op de laatste werkdag ingeleverd te worden bij zijn/haar direct leidinggevende.\n\nNaam: $($p.Name.NickName)\nAchternaam: $($p.Name.FamilyName)\nPersoneelsnummer: $($p.ExternalId)\n\nFunctie: $($p.PrimaryContract.Title.Name)\nAfdeling: $($p.PrimaryContract.Department.DisplayName)\n\nManager: $($p.PrimaryContract.Manager.DisplayName)",
		"Action": null,
		"BriefDescription": "Inname Laptop ($($p.displayName))",
		"Template": "Ws 015",
		"Category": "Middelen",
		"SubCategory": "Inventaris & apparatuur",
		"ChangeType": "Simple",
		"Impact": "Persoon",
		"Benefit": null,
		"Priority": "P1"
	}
}
JSON field Description
Id: Unique identifier in the JSON for HelloID. This cannot change!
DisplayName: The value is shown when selecting the entitlement in HelloID.
Grant / Revoke: It is possible to create a change when granting and revoking an entitlement. It is also possible to create a change when only granting or revoking an entitlement. Please look at the change_example.JSON to see how this works.
Requester: It is possible to edit who is the requester of the change. You can fill in the E-mail of the Topdesk person or fill in 'Employee' or 'Manager'. Please note if the requester is an 'Employee' or 'Manager' the script will check if the person is archived. If the person is archived the script will activate the person, create the change and archive the person again.
Request: Fill in the request text. It is possible to use variables like $($p.Name.FamilyName) for the family name of the employee. Use \n for "enter".
Action: Commonly filled in the Topdesk change template. If so use null.
BriefDescription: Fill in the desired title of the change.
Template: Fill in the Topdesk template code of the change. This is mandatory.
Category: Commonly filled in the Topdesk change template. If so use null.
SubCategory: Commonly filled in the Topdesk change template. If so use null.
ChangeType: Fill in the change type Simple or Extensive.
Impact: Commonly filled in the Topdesk change template. If so use null.
Benefit: Commonly filled in the Topdesk change template. If so use null.
Priority: Commonly filled in the Topdesk change template. If so use null.

Incidents

It is possible to create incidents in Topdesk when granting or revoking an entitlement in HelloID. The content of the incidents is managed in a JSON file. The local HelloID agent needs to read this file.

Please map the correct account mapping in incident_permissions_grant.ps1 and incident_permissions_revoke.ps1. If used in the JSON file.

# Map the account variables used in the JSON
$account = @{
    userPrincipalName = $personContext.Person.Accounts.MicrosoftActiveDirectory.userPrincipalName
    sAMAccountName    = $personContext.Person.Accounts.MicrosoftActiveDirectory.sAMAccountName
    mail              = $personContext.Person.Accounts.MicrosoftActiveDirectory.mail
}

Please use the incident_example.json as a template to build you're own.

ℹ️ Information
If you want to look up for example operator with 'employeeNumber'. Then you should change the SearchAttribute field like in the example below. Make sure you name the SearchAttribute the same as Topdesk uses. You can verifier this in the Topdesk API documentation
     # Resolve operator id 
    if (-not [string]::IsNullOrEmpty($template.Operator)) {
        $splatParamsOperator = @{
            BaseUrl         = $actionContext.Configuration.baseUrl
            Headers         = $authHeaders
            Class           = 'Operator'
            Value           = $template.Operator
            Endpoint        = '/tas/api/operators'
            SearchAttribute = 'email'
        }
    
        #Add Impact to request object
        $requestObject += @{
            operator = @{
                id = Get-TopdeskIdentifier @splatParamsOperator
            }
        }
    }

The incident JSON file has the following structure:

{
	"Identification": {
		"Id": "I001"
	},
	"DisplayName": "Aanvraag/Inname laptop",
	"Grant": {
		"Caller": "[email protected]",
		"RequestShort": "Aanvraag Laptop ($($p.displayName))",
		"RequestDescription": "<b>Graag een laptop gereed maken voor onderstaande medewerker.</b><br><br><em>Naam: $($p.Name.NickName)</em><br><strong>Achternaam: $($p.Name.FamilyName)</strong><br>userPrincipalName: $($account.userPrincipalName)<br>sAMAccountName: $($account.sAMAccountName)<br><u>Personeelsnummer: $($p.ExternalId)</u><br><br>Functie: $($p.PrimaryContract.Title.Name)<br><i>Afdeling: $($p.PrimaryContract.Department.DisplayName)</i><br><br><a href='https://www.tools4ever.nl/'>Visit Tools4ever.nl!</a>",
		"Action": "<b>Medewerker ($($p.displayName)) heeft een laptop nodig</b><br><br>Graag gereed maken voor $($p.PrimaryContract.StartDate).",
		"Branch": "Baarn",
		"OperatorGroup": "Applicatiebeheerders",
		"Operator": null,
		"Category": "Middelen",
		"SubCategory": "Inventaris & apparatuur",
		"CallType": "Aanvraag",
		"Impact": null,
		"Priority": null,
		"Duration": null,
		"EntryType": null,
		"Urgency": null,
		"ProcessingStatus": null
	},
	"Revoke": {
		"Caller": "[email protected]",
		"RequestShort": "Inname Laptop ($($p.displayName))",
		"RequestDescription": "Volgens onze informatie is onderstaande medewerker in het bezit van een laptop, deze dient op de laatste werkdag ingeleverd te worden bij zijn/haar direct leidinggevende.<br><br>Naam: $($p.Name.NickName)<br>Achternaam: $($p.Name.FamilyName)<br>Personeelsnummer: $($p.ExternalId)<br><br>Functie: $($p.PrimaryContract.Title.Name)<br>Afdeling: $($p.PrimaryContract.Department.DisplayName)<br><br>Manager: $($p.PrimaryContract.Manager.DisplayName)",
		"Action": "<b>Medewerker ($($p.displayName)) is in het bezit van een laptop</b>.",
		"Branch": "Baarn",
		"OperatorGroup": "Applicatiebeheerders",
		"Operator": null,
		"Category": "Middelen",
		"SubCategory": "Inventaris & apparatuur",
		"CallType": "Aanvraag",
		"Impact": null,
		"Priority": null,
		"Duration": null,
		"EntryType": null,
		"Urgency": null,
		"ProcessingStatus": null
	}
}
JSON field Description
Id: Unique identifier in the JSON for HelloID.
DisplayName: The value is shown when selecting the entitlement in HelloID.
Grant / Revoke: It is possible to create an incident when granting and revoking an entitlement. It is also possible to create an incident when only granting or revoking an entitlement. Please look at the incident_example.json to see how this works.
Caller: It is possible to edit who is the caller of the change. You can fill in the E-mail of the Topdesk person or fill in 'Employee' or 'Manager'. Please note if the requester is an 'Employee' or 'Manager' the script will check if the person is archived. If the person is archived the script will activate the person, create the change and archive the person again.
RequestShort: Fill in the desired title of the incident. Size range: maximum 80 characters. It is possible to use variables like $($p.Name.FamilyName) for the family name of the employee.
RequestDescription: Fill in the request text. It is possible to use variables like $($p.Name.FamilyName) for the family name of the employee. Use <'br'> to enter. For more HTML tags: Topdesk incident API documentation
Action: Fill in the action field if needed. If not used fill in null. It is possible to use variables like $($p.Name.FamilyName) for the family name of the employee. Use <'br'> to enter. For more HTML tags: Topdesk incident API documentation
Branch: Fill in the branch name that is used in Topdesk. This is a mandatory lookup field.
OperatorGroup: Fill in the operator group name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Operator: Fill in the operator email that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Category: Fill in the category name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
SubCategory: Fill in the subcategory name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
CallType: Fill in the branch call type that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Impact: Fill in the impact name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Priority: Fill in the priority name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Duration: Fill in the duration name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
EntryType: Fill in the entry type name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
Urgency: Fill in the urgency name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident.
ProcessingStatus: Fill in the processing status name that is used in Topdesk. It is possible to disable this lookup field by using the value null. If marked mandatory in Topdesk this will be shown when opening the incident. With the correct processing status, it is possible to create a closed incident.

Getting help

For more information on how to configure a HelloID PowerShell connector, please refer to our documentation pages

If you need help, feel free to ask questions on our forum

HelloID docs

The official HelloID documentation can be found at: https://docs.helloid.com/

helloid-conn-prov-target-topdesk's People

Contributors

ajh3 avatar bvandervoorn avatar evanderiet avatar gradykoopman avatar gsichtman avatar jbreek avatar maikel-b avatar michiel85 avatar mouki9 avatar mspreeuwenberg avatar rhouthuijzen avatar rick-jongbloed avatar rscholtelubberink avatar rschouten97 avatar rvddijssel avatar sjoerdvandijkt4e avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

helloid-conn-prov-target-topdesk's Issues

OFS not supported in PowerShell core 7

'ofs' in the The Get-RandomCharacters function is not supported in PowerShell core 7 (cloud agent). Please adjust this function.

Remove the ofs-part from the function.

Make assets configurable per template

Not in all cases is the account lifecycle of the Topdesk person in scope.
There are a lot of customers that want to keep the sync between Entra ID and Topdesk. If we enable the query of Topdesk assets, then a Topdesk person should already be present.
If we make the retrieval of Topdesk assets configurable in the template itself instead of in the configuration of the system, then the process could be integrated much more flexible.
Whenever we provision the AD / Entra ID account, usually we also want to make an Topdesk incident and/or change. For arranging hardware, access card, etc. If the account lifecycle of Topdesk is not in scope, then we cannot also query the assets of the Topdesk person. This Topdesk person is only available after the sync has been executed. If we can configure the assets per template, then we can make the above use case work again.

Correlation only is missing

is it possible to add a "correlation only" option?

There is often already a synchronization with the AD.
Therefore it is not necessary to take over the provisioning of the persons, but it is necessary to create changes or incidents.

Budgetholder is queried when none is provided in account object

When we don't use a field, we don't provide it in the mapping (account) object.
However, if I outcomment (or remove) the field budgetHolder, like so:

# Account mapping. See for all possible options the Topdesk 'supporting files' API documentation at
# https://developers.topdesk.com/explorer/?page=supporting-files#/Persons/createPerson
$account = [PSCustomObject]@{
    surName             = (New-TopdeskName -Person $p).surname      # Generate surname according to the naming convention code.
    prefixes            = (New-TopdeskName -Person $p).prefixes
    firstName           = $p.Name.NickName
    firstInitials       = (New-TopdeskName -Person $p).initials     # Generate initials max 10 char
    gender              = New-TopdeskGender -Person $p
    email               = $p.Accounts.MicrosoftActiveDirectory.mail
    employeeNumber      = $p.ExternalId
    networkLoginName    = $p.Accounts.MicrosoftActiveDirectory.UserPrincipalName
    tasLoginName        = $p.Accounts.MicrosoftActiveDirectory.UserPrincipalName    # When setting a username, a (dummy) password could be mandatory
    #password            = (Get-RandomCharacters -length 10 -characters 'ABCDEFGHKLMNOPRSTUVWXYZ1234567890')
    jobTitle            = $p.PrimaryContract.Title.Name
    branch              = @{ lookupValue = $p.PrimaryContract.Location.Name }
    department          = @{ lookupValue = $p.PrimaryContract.Department.DisplayName }
    # budgetHolder        = @{ lookupValue = $p.PrimaryContract.CostCenter.Name }
    isManager           = $false # When the HelloID source provides an isManager boolean: $p.Custom.isManager
    manager             = @{ id = $mRef }
    #showDepartment      = $true
    showAllBranches     = $true
}

The function Get-TopdeskBudgetHolder to query the Topdesk budgetholder ID is still performed and returns the following error:
Requested to lookup budgetholder, but budgetholder.lookupValue is missing. This is a scripting issue.

IMO this should not be the case. We should only query and use the provided fields of the mapping (account) object.

This can be easily solved by changing this:

    # Resolve budgetholder id
    $splatParamsBudgetHolder = @{
        Account                   = [ref]$account
        AuditLogs                 = [ref]$auditLogs
        Headers                   = $authHeaders
        BaseUrl                   = $config.baseUrl
        lookupErrorHrBudgetHolder = $config.lookupErrorHrBudgetHolder
        lookupErrorTopdesk        = $config.lookupErrorTopdesk
    }
    Get-TopdeskBudgetholder @splatParamsBudgetHolder

To this:

    if($null -ne $Account.budgetHolder){
        # Resolve budgetholder id
        $splatParamsBudgetHolder = @{
            Account                   = [ref]$account
            AuditLogs                 = [ref]$auditLogs
            Headers                   = $authHeaders
            BaseUrl                   = $config.baseUrl
            lookupErrorHrBudgetHolder = $config.lookupErrorHrBudgetHolder
            lookupErrorTopdesk        = $config.lookupErrorTopdesk
        }
        Get-TopdeskBudgetholder @splatParamsBudgetHolder
    }

The example given is for budgetholder, but this should be for every field (that isn't required).

Person incorrectly archived on update

The person is archived when the manager doesn't have an active contract. How exactly I don't know yet, but I have been able to reproduce this. Probably the manager and the person are mixed up in the archiving actions.
Related to TOPdesk ticket 20230620-054.

missing mapping

missing the fieldmapping. With the functionality to import/export mapping, this should be the default by now. Please add the missing mapping file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.