User synchronization with Azure AD/Active Directory
This article is available in video format as well as a written article containing more details.
Note: due to changes in the PowerShell module, parts of the video are outdated. The video can still be used for reference. The code in this article is up to date.
The Azure AD / Active Directory synchronization is capable of automatically creating, updating, and disabling users from Azure AD or Active Directory.
We have created the ‘BrightBookingUserAdminTools’ PowerShell module, which handles this logic. By creating a (planned) task with the right PowerShell commands, you can push this information regularly to GoBright from your server.
Note: GoBright only receives data through this BrightBookingUserAdminTools. GoBright does not have permissions to send data back to your Azure AD / Active Directory.
GoBright as an Enterprise Application in Azure AD
Before continuing the section below we’d like to address that you can setup GoBright as an enterprise application within Azure AD. This will allow you to create/update users to the platform automatically and enable SSO easily. We highly recommend following the steps in the article below before continuing: GoBright as an Enterprise Application (Azure AD)
Introduction
The integration-logic is available as a PowerShell module, via PowerShellGallery, as ‘BrightBookingUserAdminTools‘.
The ‘BrightBookingUserAdminTools’ PowerShell module should be installed on a machine (server) in your domain.
When configured it follows the following steps, each time it runs:
- Get the users from Azure AD or Active Directory, filtered by your preferences, for example, filtered by group membership
- These users are sent to GoBright and immediately created or updated
- If the user is deactivated in Azure AD or Active Directory, it will also be deactivated in GoBright
- Users that are not read from the Azure AD or Active Directory are also no updated in GoBright
Follow the steps below to install and configure the integration!
Step 1
Install prerequisites
The BrightBookingUserAdminTools module has the following dependencies:
- PowerShell version 5 or higher
- The following PowerShell modules:
- PowerShellGallery
- ActiveDirectory
- Azure AD
- The machine (server) should be linked in your Windows domain
Please follow the next steps to install the dependencies:
- Log in to the machine (server) where you want to install the task. (this machine should be linked in the Windows domain).
- Start PowerShell on that machine, as ‘administator’:
- Check if PowerShell 5 is installed:
- Execute the following command:
$PSVersionTable.PSVersion
- In the result you get, the ‘Major‘ should be ‘5‘ or higher.
- If the ‘Major‘ is lower than ‘5‘, follow these steps:
- Install Windows Management Framework 5 (this includes PowerShell 5):
Download Windows Management Framework 5 - Note 1: if you get the error ‘The update is not applicable to your computer’ you probably selected the wrong download, please refer to this article.
- Note 2: Windows Management Framework 5 depends on .NET Framework 4.5.
- Note 3: Reboot is probably required.
- After installation please check if the ‘Major‘ is ‘5‘ or higher:
$PSVersionTable.PSVersion
- Install Windows Management Framework 5 (this includes PowerShell 5):
- Execute the following command:
- PowerShell ExecutionPolicy(optional)
- Set PowerShell ExecutionPolicy to Unrestricted
-
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
-
- Set PowerShell ExecutionPolicy to Unrestricted
- Install the PowerShellGallery PowerShell module:
- Execute the following commands in PowerShell (running as administrator)
- Install the NuGet PackageProvider:
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
- Configure PowerShellGallery as a trusted source:
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
- Install the PowerShellGet module:
Import-Module -Name PowerShellGet
- If you want to synchronize with Active Directory: Install the ActiveDirectory PowerShell module:
- The ActiveDirectory PowerShell module is a part of the Remote Server Administration Tools (RSAT).
- Please follow these steps to install the Remote Server Administration Tools (RSAT)
- If you want to synchronize with Azure AD: Install the Microsoft.Graph PowerShell module:
- Execute the following commands in PowerShell (running as administrator)
- Note: .Net Framework 4.7.2 or higher is required, for more documentation see: https://learn.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0
- Install the applicable Microsoft.Graph modules:
Install-Module Microsoft.Graph.Applications -Force Install-Module Microsoft.Graph.Users -Force Install-Module Microsoft.Graph.Groups -Force Install-Module Microsoft.Graph.Identity.DirectoryManagement -Force
Step 2
Installation/Update of the synchronization module
Install or update the BrightBookingUserAdminTools PowerShell module:
Install-Module -Name BrightBookingUserAdminTools -Force
The ‘-Force‘ command makes sure that the latest version of the module is installed even when a previous installation exists. When the module was already installed, the PowerShell session will need to be restarted.
Step 3
Configuration: get the API URL and API key
To be able to synchronize the users, you need to get the following information in the GoBright Portal:
- The API URL and API key
- The name of the integration which should be linked to the users
Follow these steps to find the API URL and API key:
- Log in with a manager account in the GoBright portal
- Go to Admin center > Integrations > API access
- Generate an API key via the ‘Add’-button. Choose as type ‘manager’ and enter a description for later reference
- Note: please make sure you save the API key, as there is no way to recover it
- The ‘API URL’ is your GoBright environment URL which can be found in the URL bar of your browser and under Admin center > Integrations > API access: API url https://[tenant-id].gobright.cloud/
Follow these steps to find the name of the integration:
- Log in with a manager account in the GoBright portal
- Go to Admin center > Integrations
- Copy the name of the integration (Exchange/Office 365) which should be used to link the users to
The name of the integration, the API URL and API key are needed in the next steps.
Step 4
Configure the synchronization PowerShell script
In the last step you will build the actual script to tell the GoBright PowerShell module which users you want to get and push to your GoBright environment. This can be done with Azure AD or Active Directory.
The GoBright platform enforces communication using TLS 1.2. Depending on the system you use this might nog happen automatically. See the code below and implement this in every PowerShell script that communicates with GoBright.
Also add the $ErrorActionPreference to make sure it stops the script whenever an error occurs. Please don’t forget to add the lines below in each of your scripts.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ErrorActionPreference = "Stop"
Choose one of the explanations for the script which applies to your situation below.
Script for Azure AD synchronization using the Microsoft.Graph module
Step 4.1: Connect to your Azure AD
Start PowerShell, and connect to your Azure AD via the command:
Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All','GroupMember.Read.All'
Step 4.2: Test the selection of users
Below you can find several example commands, you can adjust them to fit your situation.
These commands will not yet actually update users in GoBright, because they include the ‘-WhatIf’ parameter.
Example synchronization commands:
Process users and add the user roles within GoBright based on their group membership in Azure AD:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $ErrorActionPreference = "Stop" Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All','GroupMember.Read.All' $includedGroups = @()
$includedGroups += '[your AzureAD groupname_1 here]' $includedGroups += '[your AzureAD groupname_2 here]'
# get the list of userid's in the group $groups = Get-MgGroup -All | Where-Object { $includedGroups -contains $_.DisplayName } $users_in_groups_userids = @(); Foreach ($group in $groups) { $groupMembers = Get-MgGroupMember -All -GroupID $group.id Foreach ($groupMember in $groupMembers) { $users_in_groups_userids += $groupMember.Id } } # get the required details of those users $users_full_list = Get-MgUser -All -Select Id,DisplayName,Mail,UserPrincipalName,AccountEnabled,MobilePhone,AssignedLicenses $users = $users_full_list | Where-Object { $users_in_groups_userids -contains $_.Id } Write-Output "Loaded from AzureAD: $(($users | Measure-Object).Count) users" # define the mapping of groups to roles $groupToRoleMapping = @()
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for View
$groupToRoleMapping += @ # **special case** this line matches for every user, because of the 'MatchType', and is needed when you want to have a generic role for every user
$roleNameDefaultIfNoGroupMatched = "Regular user"
$users | Push-AzureADUsersToBB -DeactivateExistingUsersInSameIntegrationThatAreNotLoaded -UserDefaultRoleName $roleNameDefaultIfNoGroupMatched -GroupUserRoleMapping $groupToRoleMapping -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Available parameters for Push-AzureADUsersToBB
You can use the following parameters in the ‘Push-AzureADUsersToBB’ command:
–ADUserSpecificUsername UserPrincipalName |
By default the user will authenticate with the primary e-mailaddress of the user to the Microsoft Exchange Server or Office365. Provide this value to use a different way of authenticating of the user to the Microsoft Exchange Server or Office365: |
-ADUserPincodePropertyName (optional) |
Specify an fieldname of a field in Active Directory which you want to use as a ‘pincode’ (has to be numeric, minimum of 4 digits, and has to be unique). |
-ADUserMobilePropertyName (optional) |
Specify an fieldname of a field in Active Directory which you want to use to get the mobile phonenumber of the users (e.g. for notification of the digital reception) |
-ADUserNFCIdPropertyName (optional) |
Specify a fieldname of a field in Active Directory which you want to use to get the NFC Identifier for that user. |
-ADUserDefaultCostCenterId OrNamePropertyName (optional) |
Specify a fieldname of a field in Active Directory which you want to use to set the default cost center for that user. You can specify the name or id (‘guid’) of the costcenter, where the name is most commonly used. |
-GroupUserRoleMapping |
This parameter gives you the possibility to assign a role to a user in the platform, based on a group membership in the Azure AD. See the example below. |
-UserRoleNameForNewUsers (optional) |
Optional name of an existing role in the portal to use when new users are created through this synchronization. |
-DeactivateExistingUsersIn SameIntegrationThatAreNotLoaded (optional) |
Optional switch to automatically deactivate users that are not in the selected users from ActiveDirectory anymore, but still existing in the portal. |
-IncludeUsersWithoutAzureAD AssignedLicensesOrAssignedPlans |
Include users that do not have Azure AD licenses assigned (would otherwise be included as inactive) or Azure AD plans assigned (would otherwise be fully excluded). Note that including these users might result in having unintended ‘users’ like serviceacounts, roommailbox users, etc. That can be mitigated by filtering the users before feeding them into this command. |
-BrightBookingApiUrl (required) |
The API url, as found in step 3 |
-BrightBookingApiKey (required) |
The API url, as found in step 3 |
-BrightBookingIntegrationName (required) |
The API url, as found in step 3 |
-WhatIf (optional) |
Use the ‘-WhatIf’ parameter to only test and see, but not actually send data to your GoBright environment |
Step 4.2: Run the actual synchronization
Once the list of users is correctly filtered, you can execute the real synchronization by removing the ‘-WhatIf’ parameter.
So now execute the same command, but without ‘-WhatIf’ and it will process the users to your GoBright environment.
Step 4.3: Schedule the integration to run periodically via Windows task scheduler
To be able to run the script unattended you should somehow login automatically.
The advised way to do use unattended login, this can be done via certificates, via app registration in Azure AD:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $ErrorActionPreference = "Stop"
#This script will create een enterprise app with a local certificate for unattended authorisation.
#Set the enterprise app name $AppName = "GoBright_UserSync_UnattendedLogin" $ErrorActionPreference = "Stop" #Connect with the graph to be able to create or update the application Connect-MgGraph -Scopes "Application.Read.All","Application.ReadWrite.All" #Get the tenantid $organization = Get-MgOrganization $APPTenantID = $organization.Id #Create or update the enterprise app $foundApps = Get-MgApplication | Where-Object {$_.DisplayName -eq $AppName} $foundAppsCount = $foundApps | Measure-Object if ($foundAppsCount.Count -eq 0) { # create the app $App = New-MgApplication -DisplayName $AppName $APPObjectID = $App.Id $APPClientID = $App.AppId } Else { $APPObjectID = $foundApps.Id $APPClientID = $foundApps.AppId } #Create a local self-signed certificate to use it as credential for the enterprise app $foundCerts = Get-ChildItem -Path cert:CurrentUsermy | Where-Object { $_.Subject -eq "CN=$($AppName)" } $foundCertsCount = $foundCerts | Measure-Object If ($foundCertsCount.Count -eq 0) { # create self-signed cert $thumb = (New-SelfSignedCertificate -CertStoreLocation Cert:CurrentUserMy -subject $AppName -KeyExportPolicy Exportable -NotAfter (Get-Date).AddYears(20) -Type CodeSigningCert -KeySpec Signature).Thumbprint $foundCerts = Get-ChildItem -Path cert:CurrentUsermy$thumb $cert = $foundCerts[0] } Else { $cert = $foundCerts[0] } #Create a keyCredential from the certificate for the enterprise app $keyCreds = @{ Type = "AsymmetricX509Cert"; Usage = "Verify"; key = $cert.RawData } try { #Set credentials Update-MgApplication -ApplicationId $APPObjectID -KeyCredentials $keyCreds #Set permission scopes, needs to go via id, see: https://learn.microsoft.com/en-us/graph/permissions-reference #'User.Read.All' = df021288-bdef-4463-88db-98f22de89214 #'Group.Read.All' = 5b567255-7703-4780-807c-7be8301ae99b #'GroupMember.Read.All' = 98830695-27a2-44f7-8c18-0c3ebc9698f6 $params = @{ RequiredResourceAccess = @( @{ ResourceAppId = "00000003-0000-0000-c000-000000000000" ResourceAccess = @( @{ Id = "df021288-bdef-4463-88db-98f22de89214" Type = "Role" }, @{ Id = "5b567255-7703-4780-807c-7be8301ae99b" Type = "Role" }, @{ Id = "98830695-27a2-44f7-8c18-0c3ebc9698f6" Type = "Role" } ) } )} Update-MgApplication -ApplicationId $APPObjectID -BodyParameter $params } catch { Write-Error $Error[0] } #Output details and request the admin to check the consent
Write-Output "App registration '$($AppName)' is now available, please use following details in the user sync script:"
Write-Output " - ClientId: $($APPClientID)"
Write-Output " - TenantId: $($APPTenantID)"
Write-Output " - CertificateThumbprint: $($cert.Thumbprint)"
Write-Output "NOTE: Please give admin consent in the AzureAD portal to this app!"
Admin Consent in AzureAD
Please go to Azure portal and open the created enterprise application for unattendedlogin and select API permission > Grant admin consent for “Your Domain”
Now you can use the following way to automatically login to your Azure AD with the unattended login method and test your script via ‘-WhatIf’ before running the actual user sync script:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ErrorActionPreference = "Stop"
$clientid = "[fill in your client from the output of the first script]" $tenantid = "[fill in your tenant id from the output of the first script]" $thumb = "[fill in your thumb id from the output of the first script]" Connect-MgGraph -ClientId $clientid -TenantId $tenantid -CertificateThumbprint $thumb
$includedGroups = @()
$includedGroups += '[your AzureAD groupname_1 here]' $includedGroups += '[your AzureAD groupname_2 here]'
# get the list of userid's in the group $groups = Get-MgGroup -All | Where-Object { $includedGroups -contains $_.DisplayName } $users_in_groups_userids = @(); Foreach ($group in $groups) { $groupMembers = Get-MgGroupMember -All -GroupID $group.id Foreach ($groupMember in $groupMembers) { $users_in_groups_userids += $groupMember.Id } } # get the required details of those users $users_full_list = Get-MgUser -All -Select Id,DisplayName,Mail,UserPrincipalName,AccountEnabled,MobilePhone,AssignedLicenses $users = $users_full_list | Where-Object { $users_in_groups_userids -contains $_.Id } Write-Output "Loaded from AzureAD: $(($users | Measure-Object).Count) users" # define the mapping of groups to roles $groupToRoleMapping = @()
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for View
$groupToRoleMapping += @ # **special case** this line matches for every user, because of the 'MatchType', and is needed when you want to have a generic role for every user
$roleNameDefaultIfNoGroupMatched = "Regular user"
$users | Push-AzureADUsersToBB -DeactivateExistingUsersInSameIntegrationThatAreNotLoaded -UserDefaultRoleName $roleNameDefaultIfNoGroupMatched -GroupUserRoleMapping $groupToRoleMapping -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Next, follow these steps to synchronize the users from Active Directory on a schedule:
- Take the command you’ve composed (see previous steps), and save it in a .ps1 file:
- Create a .ps1 file (e.g. UsersToBrightBooking.ps1) in a folder you prefer
- Open the file with an editor, for example ‘notepad’
- Paste the login script to automatically login to your Azure AD
- Paste the full command into the file
- Save the file
- Execute the file to see if it is successful
- Create a task in the Windows task scheduler:
- Open Windows task scheduler
- Create a task
- Set a schedule, for example once a day, or every 4 hours
- Add an action ‘Start a program’:
- Program/script:
Powershell.exe - Parameters:
-windowstyle minimized -c “powershell -c .[Name of the created .ps1 file] -verbose >> ExportToGoBright_Output.txt 2>&1″ - Start in:
Fill the ‘start in’ with the location of the script, e.g.: C:scripts
- Program/script:
”Script
“]
Step 4.1: Connect to your Azure AD
Start PowerShell, and connect to your Azure AD via the standard ‘Connect-AzureAD’ command.
AzureAD powershell module is deprecated
Please note that the AzureAD powershell module is deprecated, please migrate to the Microsoft.Graph powershell module (see above in this article)
Step 4.2: Test the selection of users
The command to get the information from Active Directory and process it in BrightBooking is:
Get-AzureADUser -All $true [optional: filter] | Push-AzureADUsersToBB [optional: specific username/pincode field] -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]'
You can use the following parameters in the ‘Push-AzureADUsersToBB’ command:
–ADUserSpecificUsername UserPrincipalName |
By default the user will authenticate with the primary e-mailaddress of the user to the Microsoft Exchange Server or Office365. Provide this value to use a different way of authenticating of the user to the Microsoft Exchange Server or Office365: |
-ADUserPincodePropertyName (optional) |
Specify an fieldname of a field in Active Directory which you want to use as a ‘pincode’ (has to be numeric, minimum of 4 digits, and has to be unique). |
-ADUserMobilePropertyName (optional) |
Specify an fieldname of a field in Active Directory which you want to use to get the mobile phonenumber of the users (e.g. for notification of the digital reception) |
-ADUserNFCIdPropertyName (optional) |
Specify a fieldname of a field in Active Directory which you want to use to get the NFC Identifier for that user. |
-ADUserDefaultCostCenterId OrNamePropertyName (optional) |
Specify a fieldname of a field in Active Directory which you want to use to set the default cost center for that user. You can specify the name or id (‘guid’) of the costcenter, where the name is most commonly used. |
-GroupUserRoleMapping |
This parameter gives you the possibility to assign a role to a user in the platform, based on a group membership in the Azure AD. See the example below. |
-UserRoleNameForNewUsers (optional) |
Optional name of an existing role in the portal to use when new users are created through this synchronization. |
-DeactivateExistingUsersIn SameIntegrationThatAreNotLoaded (optional) |
Optional switch to automatically deactivate users that are not in the selected users from ActiveDirectory anymore, but still existing in the portal. |
-IncludeUsersWithoutAzureAD AssignedLicensesOrAssignedPlans |
Include users that do not have Azure AD licenses assigned (would otherwise be included as inactive) or Azure AD plans assigned (would otherwise be fully excluded). Note that including these users might result in having unintended ‘users’ like serviceacounts, roommailbox users, etc. That can be mitigated by filtering the users before feeding them into this command. |
-BrightBookingApiUrl (required) |
The API url, as found in step 3 |
-BrightBookingApiKey (required) |
The API url, as found in step 3 |
-BrightBookingIntegrationName (required) |
The API url, as found in step 3 |
-WhatIf (optional) |
Use the ‘-WhatIf’ parameter to only test and see, but not actually send data to your GoBright environment |
Below you can find several example commands, you can adjust them the way you need to fit your situation.
These commands will not yet actually update users in the system, so these are test commands, because they include the ‘-WhatIf’ parameter.
Example test commands:
Process all users in the Azure AD to GoBright:
Get-AzureADUser -All $true | Push-AzureADUsersToBB -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users with UPN’s ending with ‘yourdomain.com’ to GoBright:
Get-AzureADUser -All $true | where {$_.userprincipalname -like "*yourdomain.com"} | Push-AzureADUsersToBB -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users with an NFC ID and Pincode in a custom attribute, note that the extension attribute name must be identical to the one in Azure AD:
$users_all_import = Get-AzureADUser -All $true [optional: filter]
$users_all = @()
$pincodeField = '[Extension attribute here]'
$NFCField = '[Extension attribute here]'
Foreach ($user in $users_all_import) {
$getExtensionProperty = $user | Select-Object -ExpandProperty ExtensionProperty
If ($getExtensionProperty.$pincodeField) {
$pin = (Get-AzureADUserExtension -ObjectId $user.ObjectId).get_item($pincodeField)
} Else {
$pin = ''
}
If ($getExtensionProperty.$NFCField) {
$nfc = (Get-AzureADUserExtension -ObjectId $user.ObjectId).get_item($NFCField)
} Else {
$nfc = ''
}
$user | Add-Member UserPincode $pin -Force
$user | Add-Member UserNFC $nfc -Force
$users_all += $user
}
$users_all | Push-AzureADUsersToBB -ADUserPincodePropertyName UserPincode -ADUserNFCIdPropertyName UserNFC -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users and add the user roles within GoBright based on their group membership in Azure AD:
$groupToRoleMapping = @()
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for Meet-Work-Visit
$groupToRoleMapping += @ # match specific users that belong to a group for View
$groupToRoleMapping += @ # **special case** this line matches for every user, because of the 'MatchType', and is needed when you want to have a generic role for every user
$roleNameDefaultIfNoGroupMatched = "Regular user"
$users_all = Get-AzureADUser -All $true
$users_all | Push-AzureADUsersToBB -UserDefaultRoleName $roleNameDefaultIfNoGroupMatched -GroupUserRoleMapping $groupToRoleMapping -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process all users except those who are a member of a specific group in Azure AD:
$excludedGroups = @()
$excludedGroups += '[GroupName1]'
$excludedGroups += '[GroupName2]'
$excludedGroups += '[GroupName3]'
$ADGroups = Get-AzureADGroup -All $true | Where-Object { $excludedGroups -notcontains $_.DisplayName }
$users_all = $ADGroups | Get-AzureADGroupMember -All $true
$users_all | Push-AzureADUsersToBB -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Step 4.2: Run the actual synchronization
Once the list of users is correctly filtered, you can execute the real synchronization by removing the ‘-WhatIf’ parameter.
So now execute the same command, but without ‘-WhatIf’ and it will process the users to your GoBright environment.
Step 4.3: Schedule the integration to run periodically via Windows task scheduler
To be able to run the script unattended you should somehow login automatically.
Advised unattended login method:
The advised way to do unattended login, is by creating an registered app in Azure AD, and connect to that app:
#script for creating user, cert, and get tenantid #getting data for daily script
Connect-AzureAD $pwd = "Password to encrypt the cert" $subject = "GoBright_unattendedlogin" # may not be longer than 15 characters = the name certificate and app $tmppath = "C:tmp" $certname= "unattendedlogin_azuread.pfx" $fullcertpath = "C:tmpunattendedlogin.pfx" $IdentifierUris = "https://www.fillInYourOwnDomain.com" # Here you need to fill in your own domain name
$thumb = (New-SelfSignedCertificate -CertStoreLocation Cert:CurrentUserMy -subject $subject -KeyExportPolicy Exportable -NotAfter (Get-Date).AddYears(10) -Type CodeSigningCert -KeySpec Signature).Thumbprint $pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText if ($tmppath -eq $false) Export-PfxCertificate -cert "cert:CurrentUsermy$thumb" -FilePath $fullcertpath -Password $pwd
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($fullcertpath, $pwd) $keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
$application = New-AzureADApplication -DisplayName $subject -IdentifierUris $IdentifierUris New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier $subject -Type AsymmetricX509Cert -Usage Verify -Value $keyValue $sp=New-AzureADServicePrincipal -AppId $application.AppId Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Directory Readers"}).Objectid -RefObjectId $sp.ObjectId
$tenantid = Get-AzureADTenantDetail | Select ObjectId -ExpandProperty ObjectId $appid = $application.AppId $thumb $tenantid $appid
#copy data from thumb, tenantid, appid to daily user sync script
For more information please click on this link.
For testing purposes you could use the following way to automatically login to your Azure AD with the unattended login method and test your script before running the actual user sync script:
$tenantid = "[fill in your tenant id from the output of the first script]" $thumb = "[fill in your thumb id from the output of the first script]" $appid = "[fill in your appid from the output of the first script]"
Connect-AzureAD -TenantId $tenantid -ApplicationId $appid -CertificateThumbprint $thumb
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $ErrorActionPreference = "Stop"
$users_all = Get-AzureADUser -All $true | Where-Object {$_.userprincipalname -like "*someDomainname.com"} $users_all | Push-AzureADUsersToBB -UserDefaultRoleName $roleNameDefaultIfNoGroupMatched -GroupUserRoleMapping $groupToRoleMapping -DeactivateExistingUsersInSameIntegrationThatAreNotLoaded -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Note: when you get an error within PowerShell that there are insufficient rights to run the script, then you need to check the rights to add to the app. For more information please read the following Microsoft article ‘Step 5: Assign Azure AD roles to the application’: https://docs.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps
Next, follow these steps to synchronize the users from Active Directory on a schedule:
- Take the command you’ve composed (see previous steps), and save it in a .ps1 file:
- Create a .ps1 file (e.g. UsersToBrightBooking.ps1) in a folder you prefer
- Open the file with an editor, for example ‘notepad’
- Paste the login script to automatically login to your Azure AD
- Paste the full command into the file
- Save the file
- Execute the file to see if it is successful
- Create a task in the Windows task scheduler:
- Open Windows task scheduler
- Create a task
- Set a schedule, for example once a day, or every 4 hours
- Add an action ‘Start a program’:
- Program/script:
Powershell.exe - Parameters:
-windowstyle minimized -c “powershell -c .[Name of the created .ps1 file] -verbose >> ExportToGoBright_Output.txt 2>&1″ - Start in:
Fill the ‘start in’ with the location of the script, e.g.: C:scripts
- Program/script:
Script for Active Directory synchronization
Step 4.1: Test the selection of users
The command to get the information from Active Directory and process it in GoBright is:
Push-ADUsersToBB [filter] [optional: specific username/pincode field] -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]'
You can use the following parameters in the ‘Push-ADUsersToBB’ command:
-Filter (required) |
The filter condition to filter the users you want to synchronize (more documentation available) |
-SearchBase (optional) |
Specifies the Active Directory path the search under (more documentation available) |
-ADSpecificUsername |
By default, the user will authenticate with the primary e-mail address of the user to the Microsoft Exchange Server or Office365. Provide these values to use a different way of authenticating the user to the Microsoft Exchange Server or Office365: |
-ADUserPincodePropertyName (optional) |
Specify a field name of a field in Active Directory which you want to use as a ‘pincode’ (has to be numeric, minimum of 4 digits, and has to be unique) |
-ADUserMobilePropertyName (optional) |
Specify a field name of a field in Active Directory which you want to use to get the mobile phone number of the users (e.g. for notification of the digital reception) |
-ADUserNFCIdPropertyName (optional) |
Specify a field name of a field in Active Directory which you want to use to get the NFC Identifier for that user. Please note that it should be in HEX format, eg: XX:XX:XX:XX:XX:XX. |
-ADUserDefaultCostCenterId OrNamePropertyName (optional) |
Specify a fieldname of a field in Active Directory which you want to use to set the default cost center for that user. You can specify the name or id (‘guid’) of the costcenter, where the name is most commonly used. |
-UserRoleNameForNewUsers (optional) |
Optional name of an existing role in the platform to use when new users are created through this synchronization. |
-UserDefaultRoleName (optional) |
Set the default rolename for all users that don’t have a match in the ‘GroupUserRoleMapping’ (see below) |
-GroupUserRoleMapping (optional) |
This parameter gives you the possibility to assign a role to a user in the platform, based on a group membership in the ActiveDirectory. See the example below. |
-DeactivateExistingUsersIn SameIntegrationThatAreNotLoaded (optional) |
Optional switch to automatically deactivate users that are not in the selected users from ActiveDirectory anymore, but still existing in the portal. |
-BrightBookingApiUrl (required) |
The API url, as found in step 3 |
-BrightBookingApiKey (required) |
The API url, as found in step 3 |
-BrightBookingIntegrationName (required) |
The API url, as found in step 3 |
-WhatIf (optional) |
Use the ‘-WhatIf’ parameter to only test and see, but not actually send data to your GoBright environment |
Below you can find several example commands, you can adjust them the way you need to fit your situation.
There commands will not yet actually update users in the system, so these are test commands, because the include the ‘-WhatIf’ parameter.
Example test commands:
Process users with UPN’s ending with ‘yourdomain.com’:
Push-ADUsersToBB -Filter 'UserPrincipalName -like "*yourdomain.com"' -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users with UPN’s ending with ‘yourdomain.com’, and using the ‘PersonnelNumber’ field in ActiveDirectory as pincode for the users:
Push-ADUsersToBB -Filter 'UserPrincipalName -like "*yourdomain.com"' -ADUserPincodePropertyName PersonnelNumber -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users which are members of a specific group in an OU (Organizational Unit):
Push-ADUsersToBB -Filter { memberOf -RecursiveMatch "CN=Administrators,DC=Company,DC=com" } -SearchBase "OU=Office,DC=Company,DC=com" -ADUserPincodePropertyName PersonnelNumber -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users which are members of a specific group in an OU (Organizational Unit) and set a specific role based on their group membership:
$groupToRoleMapping = @()
$groupToRoleMapping += @ # match specific users that belong to a group
$groupToRoleMapping += @ # match specific users that belong to a group
$groupToRoleMapping += @ # match specific users that belong to a group to a role of View
$groupToRoleMapping += @ # **special case** this line matches for every user, because of the 'MatchType', and is needed when you want to have a generic role for every user
$roleNameDefaultIfNoGroupMatched = "Regular user"
Push-ADUsersToBB -Filter { memberOf -RecursiveMatch "CN=OfficeUsers,DC=Company,DC=com" } -SearchBase "OU=Office,DC=Company,DC=com" -ADUserPincodePropertyName PersonnelNumber -UserDefaultRoleName $roleNameDefaultIfNoGroupMatched -GroupUserRoleMapping $groupToRoleMapping -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Process users which are members of a specific group in an OU (Organizational Unit), with [domain][username] as authentication username:
Push-ADUsersToBB -Filter { memberOf -RecursiveMatch "CN=Administrators,DC=Company,DC=com" } -SearchBase "OU=Office,DC=Company,DC=com" -ADSpecificUsername DomainPlusUsername -BrightBookingApiUrl '[API url]' -BrightBookingApiKey '[API key]' -BrightBookingIntegrationName '[name of integration as created in Admin center > Integrations]' -WhatIf
Step 4.2: Run the actual synchronization
Once the list of users is correctly filtered, you can execute the real synchronization by removing the ‘-WhatIf’ parameter.
So now execute the same command, but without ‘-WhatIf’ and it will process the users to your GoBright environment.
Step 4.3: Schedule the integration to run periodically via Windows task scheduler
Follow these steps to synchronize the users from Active Directory on a schedule:
- Take the command you’ve composed (see previous steps), and save it in a .ps1 file:
- Create a .ps1 file (e.g. UsersToBrightBooking.ps1) in a folder you prefer
- Open the file with an editor, for example ‘notepad’
- Paste the full command into the file
- Save the file
- Execute the file to see if it is successfull
- Create a task in the Windows task scheduler:
- Open Windows task scheduler
- Create a task
- Set a schedule, for example once a day, or every 4 hours
- Add an action ‘Start a program’:
- Program/script:
Powershell.exe - Parameters:
-windowstyle minimized -c “powershell -c .[Name of the created .ps1 file] -verbose >> ExportToGoBright_Output.txt 2>&1″ - Start in:
Fill the ‘start in’ with the location of the script, e.g.: C:scripts
- Program/script:
Sync interval for testing
The advice for the sync interval is a scope of the following amounts below:
- 0 to 2000 users: the sync can be run 4 times a day
- Over 2000 users: the sync can be run 2 times a day
For testing approximately 3-4 times in an hour we strongly advise to run the script with small batches of 10 users per run.