Public/Configuration/ExchangeOnline/BitTitan/New-BitTitanAppRegistration.ps1
function New-BitTitanAppRegistration() { param( [Parameter(Mandatory)] [string]$TenantId ) Connect-CustomerGraph -CustomerTenantId $TenantId Connect-CustomerExchange -CustomerTenantId $TenantId try { $Resource = Get-MgServicePrincipal -Filter "appId eq '00000002-0000-0ff1-ce00-000000000000'" -ErrorAction Stop if(!$Resource) { Write-ModuleLog -Message "Failed to find Exchange Online service principal. The customer does not have Exchange Online - and therefore app registration is impossible. Assign a license to the customer, and wait 10 minutes before trying again." -Level Error -Component 'BitTitanAppRegistration' } } catch { Write-ModuleLog -Message "Failed to find Exchange Online service principal. The customer does not have Exchange Online - and therefore app registration is impossible. Assign a license to the customer, and wait 10 minutes before trying again." -Level Error -Component 'BitTitanAppRegistration' -ThrowError } try { $AppRegistrationParams = @{ displayName = "BitTitan MigrationWiz" description = "App registration for BitTitan MigrationWiz usage." isFallbackPublicClient = "True" signInAudience = "AzureADMultipleOrgs" publicClient = @{ redirectUris = @( "urn:ietf:wg:oauth:2.0:oob" ) } requiredResourceAccess = @( @{ resourceAppId = "00000002-0000-0ff1-ce00-000000000000" resourceAccess = @( @{ id = "3b5f3d61-589b-4a3c-a359-5dd4b5ee5bd5" type = "Scope" } @{ id = "dc50a0fb-09a3-484d-be87-e023b12c6440" type = "Role" } @{ id = "dc890d15-9560-4a4c-9b7f-a736ec74ec40" type = "Role" } ) } ) } $Application = New-MgApplication -BodyParameter $AppRegistrationParams -ErrorAction Stop Write-ModuleLog -Message "Created BitTitan app registration: $($Application.DisplayName)" -Level Info -Component 'BitTitanAppRegistration' } catch { Write-ModuleLog -Message "Failed to create BitTitan app registration" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { $ServicePrincipal = Get-MgServicePrincipal -Filter "appId eq '$($Application.AppId)'" -ErrorAction Stop if (!$ServicePrincipal) { $ServicePrincipal = New-MgServicePrincipal -AppId $Application.AppId Write-ModuleLog -Message "Created BitTitan app registration service principal" -Level Info -Component 'BitTitanAppRegistration' } } catch { Write-ModuleLog -Message "Failed to find/create app registration service principal" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { Write-ModuleLog -Message "Waiting 30 seconds to ensure Entra ID Service Principal is synced to Exchange Online" -Level Info -Component 'BitTitanAppRegistration' Start-Sleep 30 $EXOSP = New-ServicePrincipal -AppId $ServicePrincipal.AppId -ObjectId $ServicePrincipal.Id -DisplayName "BitTitan MigrationWiz" -ErrorAction Stop Write-ModuleLog -Message "Created Exchange Online service principal" -Level Info -Component 'BitTitanAppRegistration' } catch { Write-ModuleLog -Message "Failed to create Exchange Online service principal" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { $OrgConfig = Get-OrganizationConfig -ErrorAction Stop if($OrgConfig.isDehydrated) { Enable-OrganizationCustomization Write-ModuleLog -Message "Succesfully organization customization" -Level Info -Component 'BitTitanAppRegistration' } else { Write-ModuleLog -Message "Organization customization is already enabled." -Level Info -Component 'BitTitanAppRegistration' } } catch { Write-ModuleLog -Message "Failed to enable organization customization" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { $ManagementRoleAssignment = New-ManagementRoleAssignment -App $EXOSP.Id -Role "Application EWS.AccessAsApp" -ErrorAction Stop Write-ModuleLog -Message "Succesfully assigned Application EWS.AccessAsApp role" -Level Info -Component 'BitTitanAppRegistration' } catch { Write-ModuleLog -Message "Failed to assign Application EWS.AccessAsApp role" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } # Create a client secret try { $PasswordCredential = @{ displayName = "MigrationWiz" endDateTime = (Get-Date).AddMonths(6) } $ClientSecret = (Add-MgApplicationPassword -ApplicationId $Application.Id -PasswordCredential $PasswordCredential).SecretText Write-ModuleLog -Message "Successfully created client secret." -Level Info -Component 'BitTitanAppRegistration' } catch { Write-ModuleLog -Message "Failed to create client secret" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { $AppRoleAssignment1 = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ServicePrincipal.Id -PrincipalId $ServicePrincipal.Id -PrincipalDisplayName "BitTitan MigrationWiz" -ResourceDisplayName "Office 365 Exchange Online" -ResourceId $Resource.Id -AppRoleId "dc50a0fb-09a3-484d-be87-e023b12c6440" -ErrorAction Stop $AppRoleAssignment2 = New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ServicePrincipal.Id -PrincipalId $ServicePrincipal.Id -PrincipalDisplayName "BitTitan MigrationWiz" -ResourceDisplayName "Office 365 Exchange Online" -ResourceId $Resource.Id -AppRoleId "dc890d15-9560-4a4c-9b7f-a736ec74ec40" -ErrorAction Stop } catch { Write-ModuleLog -Message "Failed to create app role assignments" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } try { $Grant = New-MgOauth2PermissionGrant -ClientId $ServicePrincipal.Id -ConsentType "AllPrincipals" -Scope "EWS.AccessAsUser.All Exchange.ManageAsApp full_access_as_app" -ResourceId $Resource.Id -ErrorAction Stop Write-ModuleLog -Message "Successfully granted admin consent." -Level Info -Component 'BitTitanAppRegistration' } catch { Write-ModuleLog -Message "Failed to grant admin consent for EWS.AccessAsUser.All" -Level Error -Component 'BitTitanAppRegistration' -ErrorRecord $_ -ThrowError } Write-ModuleLog -Message "Client ID:" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "$($Application.AppId)" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "Tenant ID:" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "$($TenantId)" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "Client Secret:" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "$($ClientSecret)" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "For troubleshooting, view this:" -Level Info -Component 'BitTitanAppRegistration' Write-ModuleLog -Message "https://help.bittitan.com/hc/en-us/articles/25111263275035-Replacement-to-the-Retirement-of-Role-Based-Access-Control-for-Applications-in-Exchange-Online" -Level Info -Component 'BitTitanAppRegistration' } |