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 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"}
    .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 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 BrightBooking process it directly
    .LINK
        Get-AzureADUser
    #>


    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    Param(
      [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
       [System.Object[]]$pipelineAzureADUsers,
       
      [Parameter(Mandatory=$False)]
       [string]$ADUserNamePropertyName = "DisplayName",
       
      [Parameter(Mandatory=$False)]
       [string]$ADUserPincodePropertyName,
       
      [Parameter(Mandatory=$False)]
       [string]$ADUserMobilePropertyName = "Mobile",
       
      [Parameter(Mandatory=$False)]
       [string]$ADUserNFCIdPropertyName,
       
      [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
    )
    
    Begin {
        If (-not $PSBoundParameters.ContainsKey('Confirm')) {
            $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
        }
        If (-not $PSBoundParameters.ContainsKey('WhatIf')) {
            $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
        }
        
        If ($GroupUserRoleMapping)
        {
            Write-Output "Loading groups for configured 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)
            {
                $foundGroup = $null

                # try to find the related group by name
                $foundGroups = Get-AzureADGroup -SearchString $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 groups"
        }

        $convertedUsers = @()
    }

    Process {
        Foreach ($ADUser in $pipelineAzureADUsers)
        {
            $userName = ""
            If ($ADUserNamePropertyName)
            {
                $userName = $ADUser.$ADUserNamePropertyName
            }
            Else
            {
                $userName = $ADUser.DisplayName
            }
                        
            $userMobile = ""
            If ($ADUserMobilePropertyName)
            {
                $userMobile = $ADUser.$ADUserMobilePropertyName
            }
                        
            $userNFCId = ""
            If ($ADUserNFCIdPropertyName)
            {
                $userNFCId = $ADUser.$ADUserNFCIdPropertyName
            }

            $userEmailAddress = $ADUser.UserPrincipalName
            
            $userEnabled = $false
            If ($ADUser.AccountEnabled -And $ADUser.AssignedLicenses -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)
                {
                    If ($groupUserRoleMappingItem.MemberUserObjectIds -contains $ADUser.ObjectID) {
                        $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
            }
            
            If ($ADUser.AssignedPlans) {
                $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                   
        }
    }
}