Public/Configuration/ExchangeOnline/Enable-CustomerDKIM.ps1

function Get-MainDomain {
    param (
        [string]$domain
    )

    # Split the domain into its components
    $domainParts = $domain -split '\.'

    # If the domain has more than two parts, return the last two parts
    if ($domainParts.Length -gt 2) {
        return ($domainParts[-2..-1] -join '.')
    } else {
        return $domain
    }
}

# Function to get the subdomain part of the domain
function Get-Subdomain {
    param (
        [string]$domain
    )

    # Split the domain into its components
    $domainParts = $domain -split '\.'

    # If the domain has more than two parts, return all but the last two parts
    if ($domainParts.Length -gt 2) {
        return ($domainParts[0..($domainParts.Length - 3)] -join '.')
    } else {
        return ""
    }
}

function Is-Subdomain {
    param (
        [string]$domain
    )

    # Split the domain into its components
    $domainParts = $domain -split '\.'

    # If the domain has more than two parts, return all but the last two parts
    if ($domainParts.Length -gt 2) {
        return $true
    } else {
        return $false
    }
}

function Enable-CustomerDKIM() {
    param(
        [Parameter(Mandatory)]
        [string]$TenantId
    )

    Write-ModuleLog -Message "Starting DKIM configuration..." -Level Info -Component 'EnableCustomerDKIM'

    try {
        Write-ModuleLog -Message "Connecting to Customer environment.." -Level Info -Component 'EnableCustomerDKIM'
        Connect-CustomerExchange -CustomerTenantId $TenantId
        Connect-CustomerGraph -CustomerTenantId $TenantId

        $DomainsWithoutDKIM = @()

        Get-MgDomain | Where-Object { $_.Id -NotLike '*.onmicrosoft.com' } | ForEach-Object {
            Write-ModuleLog -Message "Checking domain $($_.Id).." -Level Info -Component 'EnableCustomerDKIM'

            $DKIMStatus = Get-DkimSigningConfig -Identity $_.Id -ErrorAction SilentlyContinue

            if( -not $DKIMStatus  -or $DKIMStatus.Enabled -eq $false) {
                $DomainsWithoutDKIM += [pscustomobject]@{
                    Domain = $_.Id
                }
            }
        }
    
        if ( $DomainsWithoutDKIM.Count -eq 0 ) {
            Write-ModuleLog -Message "No domains without DKIM found." -Level Info -Component 'EnableCustomerDKIM'
            return
        }
    
        $SelectedDomains = $DomainsWithoutDKIM | Out-ConsoleGridView -Title "Select domains to enable DKIM for.." -OutputMode Multiple
    
        $SelectedDomains | ForEach-Object {
            $Domain = $_
            $DomainName = $Domain.Domain
        
            Write-ModuleLog -Message "Getting DKIM configuration for $DomainName" -Level Info -Component 'EnableCustomerDKIM'
        
            $DKIMConfig = Get-DkimSigningConfig -Identity $DomainName -ErrorAction SilentlyContinue
        
            if ( -not $DKIMConfig ) {
                Write-ModuleLog -Message "[$($DomainName)] DKIM signing config not found. Trying to enable." -Level Info -Component 'EnableCustomerDKIM'
                New-DkimSigningConfig -DomainName $DomainName -Enabled $false -ErrorAction SilentlyContinue | Out-Null
                $DKIMConfig = Get-DkimSigningConfig -Identity $DomainName -ErrorAction SilentlyContinue
            }
        
            if ( $DKIMConfig ) {
                if ( $DKIMConfig.Enabled ) {
                    Write-ModuleLog -Message "[$($DomainName)] DKIM signing config is enabled. Skipping..." -Level Info -Component 'EnableCustomerDKIM' 
                }
                else {
                    $cname1 = "selector1._domainkey.$($DomainName)"
                    $cname2 = "selector2._domainkey.$($DomainName)"
                
                    $CreateManual = $false

                    # Used if the domain is a subdomain
                    $MainDomain = Get-MainDomain -Domain $DomainName
                    
                    $cname1Dns = Resolve-DnsName -Name $cname1 -Type CNAME -ErrorAction SilentlyContinue
                    $cname2Dns = Resolve-DnsName -Name $cname2 -Type CNAME -ErrorAction SilentlyContinue
                    $NameServer = Resolve-DnsName -Name $MainDomain -Type NS -ErrorAction SilentlyContinue
                
                    Write-ModuleLog -Message "[$($DomainName)] Checking DNS records..." -Level Info -Component 'EnableCustomerDKIM'
                
                    if ( !$cname1Dns.NameHost -and !$cname2Dns.NameHost ) {
                        Write-ModuleLog -Message "[$($DomainName)] CNAME records not found." -Level Warning -Component 'EnableCustomerDKIM'
                        Write-ModuleLog -Message "[$($DomainName)] Checking nameservers..." -Level Info -Component 'EnableCustomerDKIM'
                    
                        if( $NameServer.NameHost -notlike '*.curanet.dk' ) {
                            Write-ModuleLog -Message "[$($DomainName)] Nameservers are not curanet.dk." -Level Warning -Component 'EnableCustomerDKIM'
                            $CreateManual = $true
                        }
                        else {
                            $DNSRecords = Get-CuranetDNSRecords -DomainName $MainDomain
                        
                            if ( $DNSRecords.status -ne 404 ) {
                                Write-ModuleLog -Message "[$($DomainName)] Domain found on curanet." -Level Info -Component 'EnableCustomerDKIM'
                                Write-ModuleLog -Message "[$($DomainName)] Trying to create first cname record..." -Level Info -Component 'EnableCustomerDKIM'

                                if(Is-Subdomain -domain $DomainName) {
                                    $Subdomain = Get-Subdomain -domain $DomainName
                                    $Selector1 = "selector1._domainkey.$($Subdomain)"
                                    $Selector2 = "selector2._domainkey.$($Subdomain)"
                                } else {
                                    $Selector1 = "selector1._domainkey"
                                    $Selector2 = "selector2._domainkey"
                                }
                            
                                $Cname1Result = New-CuranetDNSRecord -DomainName $MainDomain -Hostname $Selector1 -Type 'CNAME' -Value $($DKIMConfig.Selector1CNAME.Trim())
                            
                                if ( -not $Cname1Result.status ) {
                                    Write-ModuleLog -Message "Selector1 - SUCCESS!" -Level Info -Component 'EnableCustomerDKIM'
                                }
                            
                                else {
                                    Write-ModuleLog -Message "Selector1 - FAILED!" -Level Error -Component 'EnableCustomerDKIM'
                                    $CreateManual = $true
                                }
                            
                                Write-ModuleLog -Message "[$($DomainName)] Trying to create second cname record..." -Level Info -Component 'EnableCustomerDKIM'
                            
                                $Cname2Result = New-CuranetDNSRecord -DomainName $MainDomain -Hostname $Selector2 -Type 'CNAME' -Value $($DKIMConfig.Selector2CNAME.Trim())
                            
                                if( -not $Cname2Result.status ) {
                                    Write-ModuleLog -Message "Selector2 - SUCCESS!" -Level Info -Component 'EnableCustomerDKIM'
                                }
                            
                                else {
                                    Write-ModuleLog -Message "Selector2 - FAILED!" -Level Error -Component 'EnableCustomerDKIM'
                                    $CreateManual = $true
                                }
                            }
                        
                            else {
                                Write-ModuleLog -Message "[$($DomainName)] Domain not found on curanet." -Level Warning -Component 'EnableCustomerDKIM'
                                $CreateManual = $true
                            }
                        }
                        if ( $CreateManual ) {
                            Write-ModuleLog -Message "[$($DomainName)] Please create the following CNAME records manually:" -Level Warning -Component 'EnableCustomerDKIM'
                            Write-ModuleLog -Message "[$($DomainName)] selector1._domainkey.$($DomainName) -> $($DKIMConfig.Selector1CNAME.Trim())" -Level Warning -Component 'EnableCustomerDKIM'
                            Write-ModuleLog -Message "[$($DomainName)] selector2._domainkey.$($DomainName) -> $($DKIMConfig.Selector2CNAME.Trim())" -Level Warning -Component 'EnableCustomerDKIM'
                            Write-ModuleLog -Message "[$($DomainName)] Press any key to continue..." -Level Warning -Component 'EnableCustomerDKIM'
                            Read-Host
                        }
                    }
                    else {
                        Write-ModuleLog -Message "[$($DomainName)] CNAME records found." -Level Info -Component 'EnableCustomerDKIM'
                    }
                
                    Write-ModuleLog -Message "[$($DomainName)] Enabling DKIM" -Level Info -Component 'EnableCustomerDKIM'

                    Set-DkimSigningConfig -Identity $DomainName -Enabled $true -ErrorAction SilentlyContinue | Out-Null

                    While(1) {
                        Write-ModuleLog -Message "[$($DomainName)] Waiting for DKIM to be enabled..." -Level Info -Component 'EnableCustomerDKIM'
                        $result = Get-DkimSigningConfig -Identity $DomainName -ErrorAction SilentlyContinue
                    
                        if($result.Enabled -eq $true) {
                            Write-ModuleLog -Message "[$($DomainName)] DKIM enabled!" -Level Info -Component 'EnableCustomerDKIM'
                            break
                        }
                    
                        Set-DkimSigningConfig -Identity $DomainName -Enabled $true -ErrorAction SilentlyContinue | Out-Null
                        Start-Sleep -Seconds 5
                   }
                }
            }
            else {
                Write-ModuleLog -Message "[$($DomainName)] Could not enable DKIM Signing config. -Maybe exchange has not propagated yet on the tenant!" -Level Error -Component 'EnableCustomerDKIM'
            }
        }
    }
    catch {
        Write-ModuleLog -Message "Failed to enable DKIM: $_" -Level Error -Component 'EnableCustomerDKIM'
    }
}