Public/Push-AzureADUsersToBB.ps1
Function Push-AzureADUsersToBB { <# .SYNOPSIS Takes users via the pipeline from Get-AzureADUser, converts the information needed and process it directly in GoBright BrightBooking .DESCRIPTION Takes users via the pipeline from Get-AzureADUser, converts the information needed and process it directly in GoBright BrightBooking .PARAMETER ADUserNamePropertyName Optional AzureAd User Property which contains the name of the user, in case you do not want to use the default property .PARAMETER ADUserPincodePropertyName Optional AzureAd User Property which contains the pincode .PARAMETER ADUserMobilePropertyName Optional AzureAd User Property which contains the mobile phone number .PARAMETER ADUserNFCIdPropertyName Optional AzureAd User Property which contains the NFC Identifier, note that this must be in hex format, example: XX:XX:XX .PARAMETER ADUserDefaultCostCenterIdOrNamePropertyName Optional AzureAd User Property which contains the Default Cost Center for the user, which can be the Name or the Id, both the name or id can be found in the GoBright portal .PARAMETER BrightBookingApiUrl Address of the GoBright BrightBooking API, e.g.: https://t1b.gobright.cloud/ .PARAMETER BrightBookingApiKey API key of the user to use to process the import .PARAMETER BrightBookingIntegrationName Name of the GoBright integration to link the users to .PARAMETER UserRoleNameForNewUsers Name of the GoBright userrole to link new users to .PARAMETER UserDefaultRoleName Optional default name of role the role the user should get (will be assigned to every user, except for the matches found in 'GroupUserRoleMapping') .PARAMETER GroupUserRoleMapping Optional map of AzureADRoleName and the corresponding role name that should be assigned. First match will be taken, and will override a potential given 'UserDefaultRoleName' Examplestructure to supply in this parameter: $groupToRoleMapping = @() $groupToRoleMapping += @{AzureADRoleName = "Group name A"; RoleName = "Bookingmanagers"} $groupToRoleMapping += @{AzureADRoleName = ""; RoleName = "Standard user role"; MatchType = "AddForEveryUser"} # NOTE: Here a special case, by setting MatchType = "AddForEveryUser", every user will be assigned to this "Standard user role" .PARAMETER DeactivateExistingUsersInSameIntegrationThatAreNotLoaded Deactivate users that exist in the platform in the same integration but are not loaded anymore from AD (e.g. because they are not anymore in the group you filter on) .PARAMETER IncludeUsersWithoutAzureADAssignedLicensesOrAssignedPlans Include users that do not have AzureAD licenses assigned (would otherwise be included as inactive) or AzureAD 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. .PARAMETER WhatIf Use the WhatIf switch to print out the retreived users, without processing them to the API. This is usefull for testing purposes .EXAMPLE Get-AzureADUser | Push-AzureADUsersToBB -BrightBookingApiUrl "https://t1b.gobright.cloud/" -BrightBookingApiKey "[your api key]" -BrightBookingIntegrationName "Office 365" # Get all users in the Active Directory and let GoBright process it directly .LINK Get-AzureADUser #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] Param( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Object[]]$pipelineAzureADUsers, [Parameter(Mandatory = $False)] [string]$ADUserEmailAddressPropertyName = "Mail", [Parameter(Mandatory = $False)] [string]$ADUserNamePropertyName = "DisplayName", [Parameter(Mandatory = $False)] [string]$ADUserPincodePropertyName, [Parameter(Mandatory = $False)] [string]$ADUserMobilePropertyName = "Mobile", [Parameter(Mandatory = $False)] [string]$ADUserNFCIdPropertyName, [Parameter(Mandatory = $False)] [string]$ADUserDefaultCostCenterIdOrNamePropertyName, [Parameter(Mandatory = $True)] [string]$BrightBookingApiUrl, [Parameter(Mandatory = $True)] [string]$BrightBookingApiKey, [Parameter(Mandatory = $True)] [string]$BrightBookingIntegrationName, [Parameter(Mandatory = $False)] [string]$UserRoleNameForNewUsers, [Parameter(Mandatory = $False)] [string]$UserDefaultRoleName, [Parameter(Mandatory = $False)] [System.Object[]]$GroupUserRoleMapping, [switch]$DeactivateExistingUsersInSameIntegrationThatAreNotLoaded, [switch]$IncludeUsersWithoutAzureADAssignedLicensesOrAssignedPlans ) Begin { If (-not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') } If (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } # make the list unique, so we don't have duplicates $pipelineAzureADUsers = $pipelineAzureADUsers | Sort-Object -Property * -Unique If ($GroupUserRoleMapping) { Write-Output "Loading AzureAD groups for configured groups in the group to role mapping" # lookup a groupname, we do this in the order of the supplied key/values, and the first hit is taken. Foreach ($groupUserRoleMappingItem in $GroupUserRoleMapping) { If ($groupUserRoleMappingItem.MatchType -eq "AddForEveryUser") { # for this special match type we should not load the users of the group, because it is designed to matche always (and probably does not even have an AzureADRoleName set) Write-Output " - Special MatchType 'AddForEveryUser' found, every user will be added to the role '$($groupUserRoleMappingItem.RoleName)'" } Else { $foundGroup = $null # try to find the related group by name $foundGroups = Get-AzureADGroup -Filter "DisplayName eq '$($groupUserRoleMappingItem.AzureADRoleName)'" If ($foundGroups.Count -ge 1) { # add the object id of the group to the mapping, so we can use it later on $foundGroup = $foundGroups[0] } $memberUserObjectIds = @() If ($foundGroup) { $azureADGroupMembers = Get-AzureADGroupMember -All $true -ObjectId $foundGroup.ObjectId Foreach ($azureADGroupMember in $azureADGroupMembers) { $memberUserObjectIds += $azureADGroupMember.ObjectId } Write-Output " - Group '$($foundGroup.DisplayName)' found, contains $($memberUserObjectIds.Count) users" } Else { Write-Error " - Group '$($groupUserRoleMappingItem.AzureADRoleName)' not found, so users cannot be mapped to this group" } $groupUserRoleMappingItem | Add-Member MemberUserObjectIds $memberUserObjectIds -Force } } Write-Output "Finished loading AzureAD group info" } $convertedUsers = @() } Process { Foreach ($ADUser in $pipelineAzureADUsers) { # load the basic information fields from the user object $userEmailAddress = "" If ($ADUserEmailAddressPropertyName) { $userEmailAddress = $ADUser.$ADUserEmailAddressPropertyName } Else { $userEmailAddress = $ADUser.Mail } $userName = "" If ($ADUserNamePropertyName) { $userName = $ADUser.$ADUserNamePropertyName } Else { $userName = $ADUser.DisplayName } $userMobile = "" If ($ADUserMobilePropertyName) { $userMobile = $ADUser.$ADUserMobilePropertyName } $userNFCId = "" If ($ADUserNFCIdPropertyName) { $userNFCId = $ADUser.$ADUserNFCIdPropertyName } $userDefaultCostCenterIdOrName = "" If ($ADUserDefaultCostCenterIdOrNamePropertyName) { $userDefaultCostCenterIdOrName = $ADUser.$ADUserDefaultCostCenterIdOrNamePropertyName } $userEnabled = $false If ($ADUser.AccountEnabled -And ($ADUser.AssignedLicenses -Or $IncludeUsersWithoutAzureADAssignedLicensesOrAssignedPlans) -And $userEmailAddress) { $userEnabled = $true } $userPincode = "" If ($ADUserPincodePropertyName) { $userPincode = $ADUser.$ADUserPincodePropertyName } $userMappedRoles = @() If ($GroupUserRoleMapping) { # lookup which roles are valid for this user Foreach ($groupUserRoleMappingItem in $GroupUserRoleMapping) { $userMatches = $false # check if there is a 'special' matchtype, and otherwise match the default way If ($groupUserRoleMappingItem.MatchType -eq "AddForEveryUser") { $userMatches = $true } Else { If ($groupUserRoleMappingItem.MemberUserObjectIds -contains $ADUser.ObjectID) { $userMatches = $true } } If ($userMatches) { $propertiesHash = [ordered]@{ RoleName = $groupUserRoleMappingItem.RoleName } $userMappedRoles += New-Object PSObject -Property $propertiesHash } } } # if nothing matched, then add the default rolename If ($UserDefaultRoleName) { If ($userMappedRoles.Count -eq 0) { $propertiesHash = [ordered]@{ RoleName = $UserDefaultRoleName } $userMappedRoles += New-Object PSObject -Property $propertiesHash } } $outputUserPropertiesHash = [ordered]@{ EmailAddress = $userEmailAddress Name = $userName TelephoneMobile = $userMobile Pincode = $userPincode Active = $userEnabled UniqueImportID = $ADUser.ObjectId UserMappedRoles = $userMappedRoles NFCId = $userNFCId DefaultCostCenterIdOrName = $userDefaultCostCenterIdOrName } If ($ADUser.AssignedPlans -Or $IncludeUsersWithoutAzureADAssignedLicensesOrAssignedPlans) { $outputUser = New-Object PSObject -Property $outputUserPropertiesHash $convertedUsers += $outputUser } } } End { $syncIncludesUserPincode = $false If ($ADUserPincodePropertyName) { $syncIncludesUserPincode = $true } $syncIncludesUserNFCId = $false If ($ADUserNFCIdPropertyName) { $syncIncludesUserNFCId = $true } # ShouldProcess intercepts WhatIf* --> no need to pass it on If ($PSCmdlet.ShouldProcess("ShouldProcess?")) { If ($DeactivateExistingUsersInSameIntegrationThatAreNotLoaded) { Send-ADUsersToBB -pipelineConvertedADUsers $convertedUsers -BrightBookingApiUrl $BrightBookingApiUrl -BrightBookingApiKey $BrightBookingApiKey -BrightBookingIntegrationName $BrightBookingIntegrationName -UserRoleNameForNewUsers $UserRoleNameForNewUsers -SyncIncludesUserPincode $syncIncludesUserPincode -SyncIncludesUserNFCId $syncIncludesUserNFCId -DeactivateExistingUsersInSameIntegrationThatAreNotLoaded } Else { Send-ADUsersToBB -pipelineConvertedADUsers $convertedUsers -BrightBookingApiUrl $BrightBookingApiUrl -BrightBookingApiKey $BrightBookingApiKey -BrightBookingIntegrationName $BrightBookingIntegrationName -UserRoleNameForNewUsers $UserRoleNameForNewUsers -SyncIncludesUserPincode $syncIncludesUserPincode -SyncIncludesUserNFCId $syncIncludesUserNFCId } } Else { $countConvertedUsers = $convertedUsers | Measure-Object | Select-Object -ExpandProperty Count; Write-Output "============ Test mode (AzureAD) ============" Write-Output "When run in normal mode, it would now process the following $countConvertedUsers users to the API." Write-Output "If you want to run it for real, you should run without the WhatIf parameter." If ($syncIncludesUserPincode) { Write-Output "Sync will process user property '$ADUserPincodePropertyName' as 'PIN code'" } If ($syncIncludesUserNFCId) { Write-Output "Sync will process user property '$ADUserNFCIdPropertyName' as NFC ids" } Return $convertedUsers } } } |