functions/update-d365aadguestuser.ps1
|
<# .SYNOPSIS Updates the guest user details in the database .DESCRIPTION Is capable of updating the identity provider, network domain and object id inside the UserInfo table for AAD guest users .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be updated. The parameter supports wildcards. E.g. -Email "*@contoso.com*" .PARAMETER AzureAdCredential Use a PSCredential object for connecting with AzureAd .PARAMETER TenantId The TenantId to use when connecting to Azure Active Directory Uses the tenant id of the current environment if not specified. .EXAMPLE PS C:\> Update-D365AadGuestUser -Email "claire@contoso.com" This will search for the user with the e-mail address claire@contoso.com and update it with the identity provider, network domain and object id needed for an AAD guest user .EXAMPLE PS C:\> Update-D365AadGuestUser -Email "*contoso.com" This will search for all users with an e-mail address containing 'contoso.com' and update them with the identity provider, network domain and object id needed for an AAD guest user .EXAMPLE PS C:\> Update-D365AadGuestUser -Email "claire@contoso.com" -TenantId "99999999-aaaa-bbbb-cccc-9999999999" This will search for the user with the e-mail address claire@contoso.com and update it with the identity provider, network domain and object id needed for an AAD guest user. Uses tenant id "99999999-aaaa-bbbb-cccc-9999999999" when connecting to Azure Active Directory(AAD). .NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Guest Author: Mötz Jensen (@Splaxi) At no circumstances can this cmdlet be used to update users in a PROD environment. #> function Update-D365AadGuestUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string]$DatabaseServer = $Script:DatabaseServer, [string]$DatabaseName = $Script:DatabaseName, [string]$SqlUser = $Script:DatabaseUserName, [string]$SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$Email, [PSCredential] $AzureAdCredential, [string] $TenantId = $Script:TenantId ) begin { Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $canonicalProvider = Get-CanonicalIdentityProvider try { Write-PSFMessage -Level Verbose -Message "Trying to connect to the Azure Active Directory with tenant id '$TenantId'" if ($PSBoundParameters.ContainsKey("AzureAdCredential") -eq $true) { Connect-AzAccount -Credential $AzureAdCredential -ErrorAction Stop -TenantId $TenantId } else { Connect-AzAccount -ErrorAction Stop -TenantId $TenantId } $sqlCommand.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against Azure Active Directory or the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } process { if (Test-PSFFunctionInterrupt) { return } $users = Get-D365User -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName -SqlUser $SqlUser -SqlPwd $SqlPwd -Email $Email if (Test-PSFFunctionInterrupt) { return } try { foreach ($user in $users) { $aadUser = $null $guestUpnPrefix = [uri]::EscapeDataString(($user.Email -replace '@', '_') + '#EXT#') $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/users?`$filter=mail eq '$($user.Email)' or startswith(userPrincipalName,'$guestUpnPrefix')" if ($resObj.StatusCode -like "2**") { $aadUser = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value | Select-Object -First 1 } if ($null -eq $aadUser) { Write-PSFMessage -Level Critical "Could not find user $($user.Email) in AzureAAd" continue } $provider = $canonicalProvider $networkDomain = $canonicalProvider $resolvedObjectId = $aadUser.id Write-PSFMessage -Level Verbose -Message "Updating $($user.Email) - Provider $provider - ObjectId $resolvedObjectId" Update-AadGuestUserInD365FO -SqlCommand $SqlCommand -Id $user.UserId -IdentityProvider $provider -NetworkDomain $networkDomain -ObjectId $resolvedObjectId if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Host -Message "User $($user.Email) Updated" } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against Azure Active Directory or the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } end { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() Invoke-TimeSignal -End } } |