Created
December 8, 2021 00:54
-
-
Save DanClowry/68bccd3680b84aa96316bda2a568f951 to your computer and use it in GitHub Desktop.
Script to rollout DKIM to all O365 tenants with Azure DNS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://www.cyberdrain.com/connect-to-exchange-online-automated-when-mfa-is-enabled-using-the-secureapp-model/ | |
$ApplicationId = 'xxxx-xxxx-xxx-xxxx-xxxx' | |
$ApplicationSecret = 'TheSecretTheSecrey' | Convertto-SecureString -AsPlainText -Force | |
$TenantID = 'YourTenantID' | |
$RefreshToken = 'RefreshToken' | |
$ExchangeRefreshToken = 'ExchangeRefreshToken' | |
$upn = 'UPN-Used-To-Generate-Tokens' | |
$credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $ApplicationSecret) | |
$azureResourceGroup = "YourAzureResourceGroupName" | |
$aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID | |
$graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID | |
Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken | |
$customers = Get-MsolPartnerContract -All | |
Connect-AzAccount | |
# Get a list of all domains in Azure DNS so we can skip setting up DKIM for domains we don't manage | |
$azureDomains = @{} | |
Get-AzDnsZone -ResourceGroupName $azureResourceGroup | ForEach-Object { $azureDomains[$_.Name] = $_.Name } | |
Write-Output "Got $($azureDomains.Count) domains from Azure DNS" | |
foreach ($customer in $customers) { | |
$token = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716'-RefreshToken $ExchangeRefreshToken -Scopes 'https://outlook.office365.com/.default' -Tenant $customer.TenantId | |
$tokenValue = ConvertTo-SecureString "Bearer $($token.AccessToken)" -AsPlainText -Force | |
$credential = New-Object System.Management.Automation.PSCredential($upn, $tokenValue) | |
$customerId = $customer.DefaultDomainName | |
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell-liveid?DelegatedOrg=$($customerId)&BasicAuthToOAuthConversion=true" -Credential $credential -Authentication Basic -AllowRedirection | |
Import-PSSession $session | |
Write-Output "Connected to $($customerId) $($customer.TenantId)" | |
$domains = Get-AcceptedDomain | |
foreach ($domain in $domains) { | |
# Skip domains in the tenant that aren't in Azure DNS | |
if (!$azureDomains.ContainsKey($domain.Name)) { | |
Write-Output "Skipping $($domain.Name) - domain not in Azure DNS" | |
continue | |
} | |
$dkimConfig = Get-DkimSigningConfig -Identity $domain.Name | |
# Skip domains where DKIM is already enabled | |
if ($dkimConfig.Enabled) { | |
Write-Output "Skipping $($domain.Name) - DKIM already enabled" | |
continue | |
} | |
# Create DKIM keys if Get-DkimSigningConfig fails | |
if ($? -eq $false) { | |
New-DkimSigningConfig -DomainName $domain.Name -Enabled $false | |
Write-Output "DKIM keys created for $($domain.Name)" | |
} | |
else { | |
Write-Output "DKIM keys already created for $($domain.Name)" | |
} | |
$dkimConfig = Get-DkimSigningConfig -Identity $domain.Name | |
New-AzDnsRecordSet -Name selector1._domainkey -RecordType CNAME -ZoneName $domain.Name -ResourceGroupName $azureResourceGroup -Ttl 3600 -DnsRecords (New-AzDnsRecordConfig -Cname $dkimConfig.Selector1CNAME) | |
New-AzDnsRecordSet -Name selector2._domainkey -RecordType CNAME -ZoneName $domain.Name -ResourceGroupName $azureResourceGroup -Ttl 3600 -DnsRecords (New-AzDnsRecordConfig -Cname $dkimConfig.Selector2CNAME) | |
Write-Output "Domainkey selectors added to $($domain.Name) zone" | |
Start-Sleep 10 | |
Write-Host "Sleeping for 10 seconds before checking DKIM" | |
for ($i = 0; $i -lt 10; $i++) { | |
Set-DkimSigningConfig -Identity $domain.Name -Enabled $true -ErrorVariable ErrorEnableDKIM | |
# This doesnt actually work... | |
if ($ErrorEnableDKIM) { | |
Write-Output "Error when enabling DKIM. Likely need to wait for DNS to take effect. Waiting 10 seconds... (attempt $($i+1)/10)" | |
Start-Sleep 10 | |
} | |
else { | |
Write-Host "DKIM enabled for $($domain.Name)" | |
break | |
} | |
} | |
} | |
Remove-PSSession $session | |
Write-Output "Disconnected from $($customerId) $($customer.TenantId)" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment