Public/Connect/CreateSecureConnetions/New-ExoCBAConnection.ps1
function New-ExoCBAConnection { <# .SYNOPSIS Creates a connection to Exchange Online authenticated by certificate .DESCRIPTION Creates a connection to Exchange Online authenticated by a certificate 1. Creates Azure AD App 2. Adds needed API Permissions to App ( Exchange.ManageAsApp ) 3. Opens browser to grant admin consent 4. Creates a self-signed certificate 5. Adds certificate to Current User's personal store 6. Uploads certificate to Azure AD App 7. Encrypts and saves AppID, thumbprint, and tenant domain with Export-Clixml 8. Connecting to Exchange Online is as easy as running this command: Connect-Cloud -Tenant Contoso -EXOCBA .PARAMETER Tenant if the tenant is contoso.onmicrosoft.com use contoso .PARAMETER Duration By default, 1 year. Specify longer duration if desired. .PARAMETER GCCHigh Use this switch for GCCHigh tenants .EXAMPLE New-ExoCBAConnection -Tenant contoso .NOTES Once you run this function, you will be given the exact syntax to connect to Exchange Online using CBA. For example: Connect-Cloud -Tenant Contoso -EXOCBA Note: It will also output an alternate method to connect: Connect-ExchangeOnline -AppId e527b732-95f9-abcd-aa66-1d8a07870898 -CertificateThumbprint 9427165D630XXXXXXXE7F5F85005D4A77BE0B -Organization contoso.onmicrosoft.com #> Param( [Parameter(Mandatory)] [string] $Tenant, [Parameter()] [int] $Duration = 1, [Parameter()] [switch] $GCCHigh ) if ($Tenant -notlike "*.onmicrosoft.*") { if ($GCCHigh) { $Tenant = "$Tenant.onmicrosoft.us" } else { $Tenant = "$Tenant.onmicrosoft.com" } } $SelfSignedSplat = @{ ExchangeCBA = $True Duration = $Duration Tenant = $Tenant } $CertInfo = New-PoshSelfSignedCert @SelfSignedSplat # Register Azure AD Application $RegisterAppSplat = @{ Tenant = $Tenant App = 'EXO' ReturnAppObject = $true AlsoCreateGraphConnection = $AlsoCreateGraphConnection GCCHIGH = $GCCHIGH } $AppObject = Register-GraphApplication @RegisterAppSplat do { $YorN = Read-Host "`r`n`r`nHas the Azure App been created and permissions granted consent by admin [Y/N] ?" } until ($YorN = 'Y') # Upload certificate to application by ApplicationId $cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cer.Import($CertInfo.CerPath) $binCert = $cer.GetRawCertData() $Base64Value = [System.Convert]::ToBase64String($binCert) $bin = $cer.GetCertHash() $base64Thumbprint = [System.Convert]::ToBase64String($bin) $UploadSplat = @{ ObjectId = $AppObject.TenantObjectID CustomKeyIdentifier = $base64Thumbprint Type = 'AsymmetricX509Cert' Usage = 'Verify' Value = $Base64Value StartDate = $cer.NotBefore EndDate = $cer.NotAfter } $null = New-AzureADApplicationKeyCredential @UploadSplat Write-Host "`r`n`r`n" Write-Host "Waiting for Application ID $($AppObject.TenantClientID)." -ForegroundColor Yellow Write-Host "If this takes longer than 2 minutes, paste the green link above into a browser to grant admin consent" -ForegroundColor Green do { Write-Host "Waiting for Application ID $($AppObject.TenantClientID)." -ForegroundColor Yellow Start-Sleep -Seconds 10 $ServicePrincipal = Get-AzureADServicePrincipal -Filter "AppId eq '$($AppObject.TenantClientID)'" } until ($ServicePrincipal) if ($GCCHigh) { $role = Get-AzureADDirectoryRole -Filter "DisplayName eq 'Exchange Service Administrator'" } else { $role = Get-AzureADDirectoryRole -Filter "DisplayName eq 'Exchange Administrator'" } Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $ServicePrincipal.ObjectId $RootPath = $env:USERPROFILE + "\ps\" $KeyPath = $Rootpath + "creds\" if (-not (Test-Path $KeyPath)) { $null = New-Item -ItemType Directory -Path $KeyPath -ErrorAction STOP } $EXOCBAPath = (Join-Path $KeyPath "$($Tenant.split('.')[0]).EXOCBA.xml") if (Test-Path $EXOCBAPath) { $YorN = Read-Host "Connect-Cloud already has a connection. Overwrite [Y/N] ?" if ($YorN -eq 'N') { return } } $InitialDomain = ((Get-AzureADDomain).where{ $_.IsInitial }).Name @{ AppId = $AppObject.TenantClientID CertificateThumbprint = $Cer.Thumbprint Organization = $InitialDomain } | Export-Clixml $EXOCBAPath Write-Host "`r`n`r`nTo connect to Exchange Online with a certificate use:`r`n" -ForegroundColor Cyan Write-Host "Connect-Cloud " -ForegroundColor Yellow -NoNewline Write-Host "-Tenant " -ForegroundColor White -NoNewline Write-Host "$($Tenant.split('.')[0]) " -ForegroundColor Green -NoNewline if ($GCCHigh) { Write-Host "-EXOCBA " -ForegroundColor White -NoNewline Write-Host "-GCCHIGH" } else { Write-Host "-EXOCBA " -ForegroundColor White } Write-Host "`r`n`r`nor:`r`n" -ForegroundColor Cyan Write-Host "Connect-ExchangeOnline " -ForegroundColor Yellow -NoNewline Write-Host "-AppId " -ForegroundColor White -NoNewline Write-Host "$($AppObject.TenantClientID) " -ForegroundColor Green -NoNewline Write-Host "-CertificateThumbprint " -ForegroundColor White -NoNewline Write-Host "$($Cer.Thumbprint) " -ForegroundColor Green -NoNewline Write-Host "-Organization " -ForegroundColor White -NoNewline if ($GCCHigh) { Write-Host "$Tenant" -ForegroundColor Green -NoNewline Write-Host " -ExchangeEnvironmentName " -ForegroundColor White -NoNewline Write-Host "O365USGovGCCHigh `r`n`r`n`r`n`r`n" -ForegroundColor Green } else { Write-Host "$Tenant`r`n`r`n`r`n`r`n" -ForegroundColor Green } } |