Migrate-EOPSettings.ps1

<#PSScriptInfo
 
.VERSION 4.0
 
.GUID 3811626d-c583-4d52-a4a5-649f1c55d70d
 
.AUTHOR Aaron Guilmette
 
.COMPANYNAME Microsoft
 
.COPYRIGHT 2020
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI https://www.undocumented-features.com/2017/01/23/migrating-eop-settings-between-tenants/
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
.DESCRIPTION
Migrate EOP settings from one tenant to another.
 
.PRIVATEDATA
 
#>


<#
.SYNOPSIS
Migrate EOP settings from one tenant to another.
 
.PARAMETER AADRM
Enable Azure AD Rights Management for tenant. Valid parameters:
- GCC - US Government Community Cloud
- NA - North America
- EU - European Union
- AP - Asia / Pacific
- SA - South America
 
.PARAMETER EOP
Identifies source environment as EOP (different target endpoint)
 
.PARAMETER SourceTenantCredential
Standard PSCredential object for connecting to source environment.
 
.PARAMETER TargetTenantCredential
Standard PSCredential object for connecting to target environment.
 
.PARAMETER Mode
Modes available:
- Export (Exports all settings and domains)
- ExportDomains (Exports only domains from source tenant)
- ImportDomains (Imports only domains from source tenant)
- ConfirmDomains (confirms domains in target tenant)
- Import (Imports all settings except domains)
- ImportTransportRulesOnly (Imports transport rules; useful for re-running if initial import failed)
 
.NOTES
When migrating EOP and transport settings between domains, perform these activities in order:
- Export (source tenant)
- ImportDomains (target tenant)
- Add DNS verification records to external DNS
- Delete objects from source tenant
- Remove domains from source tenant
- ConfirmDomains (target tenant)
- Import (target tenant)
 
.EXAMPLE
.\Migrate-EOPSettings.ps1 -Mode Export -SourceTenantCredential (Get-Credential) -EOP
Export all settings from standalone EOP tenant using souce credentials specified on command-line.
 
.EXAMPLE
.\Migrate-EOPSettings.ps1 -Mode ExportDomains
Export domains from source tenant.
 
.LINK
https://www.undocumented-features.com/2017/01/23/migrating-eop-settings-between-tenants/
 
.NOTES
Based on TN functions and process from https://technet.microsoft.com/en-us/library/dn801047%28v=exchg.150%29.aspx
2020-04-21 - Updated for PowerShell Gallery.
2019-03-11 - Updated install mechanism for AADRM module, updated output statements to console
2018-12-03 - Added export for ATP tenant, SafeLinks, and Safe Attachments
2018-04-24 - Update to Malware filter policy
           - Added switch parameter UseExistingSession
           - Added ImportMalwareSettingsOnly mode
           - Corrected import problem with domains
2017-01-23 - Initial relase
#>


Param(
        [ValidateSet('GCC', 'NA', 'EU', 'AP', 'SA')]
        [string]$AADRM,
    [switch]$EOP,
    [Parameter()]
        [ValidateSet('Export','ExportDomains','Import','ImportDomains','ConfirmDomains','ImportTransportRulesOnly','ImportMalwareSettingsOnly')]
        [string]$Mode,
    [System.Management.Automation.PSCredential]$SourceTenantCredential,
    [System.Management.Automation.PSCredential]$TargetTenantCredential,
    [switch]$UseExistingSession
    )

function Write-Log([string[]]$Message, [string]$LogFile = $Script:LogFile, [switch]$ConsoleOutput, [ValidateSet("SUCCESS", "INFO", "WARN", "ERROR", "DEBUG")][string]$LogLevel)
{
    $Message = $Message + $Input
    If (!$LogLevel) { $LogLevel = "INFO" }
    switch ($LogLevel)
    {
        SUCCESS { $Color = "Green" }
        INFO { $Color = "White" }
        WARN { $Color = "Yellow" }
        ERROR { $Color = "Red" }
        DEBUG { $Color = "Gray" }
    }
    if ($Message -ne $null -and $Message.Length -gt 0)
    {
        $TimeStamp = [System.DateTime]::Now.ToString("yyyy-MM-dd HH:mm:ss")
        if ($LogFile -ne $null -and $LogFile -ne [System.String]::Empty)
        {
            Out-File -Append -FilePath $LogFile -InputObject "[$TimeStamp] $Message"
        }
        if ($ConsoleOutput -eq $true)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "[$TimeStamp] [$LogLevel] :: $Message" -ForegroundColor $Color
        }
    }
}

function InstallSupportingModules
{
    If (!(Get-Command Install-Module))
    {
        wget https://download.microsoft.com/download/C/4/1/C41378D4-7F41-4BBE-9D0D-0E4F98585C61/PackageManagement_x64.msi -OutFile $env:TEMP\PackageManagement_x64.msi
        Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Installing PowerShell-Get Supporting Libraries."
        msiexec /i $env:TEMP\PackageManagement_x64.msi /qn
        Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Installing PowerShell Get Supporting Libraries (NuGet)."
        Install-PackageProvider -Name Nuget -MinimumVersion 2.8.5.201 -Force -Confirm:$false
    }
}

If (!(Get-Module -ListAvailable DnsClient))
{
    Write-Log -ConsoleOutput -LogLevel Warn -Message "Please install the Dns Client module."
}
Else
{
    Import-Module DnsClient
}

If (!(Get-Module -ListAvailable MSOnline))
{
    if ($InstallModules)
    {
        InstallSupportingModules
        
        Write-Log -LogFile $Logfile -LogLevel DEBUG -Message "Installing Microsoft Online Services Module."
        Install-Module MSOnline -Confirm:$false -Force
        
        else
        {
            Write-Log -ConsoleOutput -LogLevel Error -Message "Please install the Windows Azure AD Module, close, and re-run this script. The Azure AD Module can be"
            Write-Log -ConsoleOutput -LogLevel Error -Message "downloaded from http://connect.microsoft.com/site1164/Downloads/DownloadDetails.aspx?DownloadID=59185"
            Write-Log -ConsoleOutput -LogLevel ERROR -Message "or by using the InstallModules switch."
            Break
        }
    }
    
    
}
Else
{
    Import-Module MSOnline
}

If ($EOP)
    {
    $ConnectionUri = "https://ps.protection.outlook.com/powershell-liveid/"
    }
Else
    {
    $ConnectionUri = "https://outlook.office365.com/powershell-liveid/"
    }

Function SourceTenantLogon
    {
    If (!($SourceTenantCredential))
    {
        $SourceTenantCredential = Get-Credential
    }
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Credential $SourceTenantCredential -Authentication Basic -AllowRedirection
    Import-PSSession $Session
    Connect-MsolService -Credential $SourceTenantCredential
    }

function TargetTenantLogon
{
    If (!($TargetTenantCredential))
    {
        $TargetTenantCredential = Get-Credential
    }
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionUri -Credential $TargetTenantCredential -Authentication Basic -AllowRedirection
    Import-PSSession $Session
    Connect-MsolService -Credential $TargetTenantCredential
}

function makeparam ([string]$ParamName, [string[]]$ParamValue)
{
    $FormattedParam = ""
    If ($ParamValue.Count -gt 0)
    {
        $FormattedParam = " -$ParamName "
        Foreach ($value in $ParamValue)
        {
            If ($value -eq "True")
            {
                $FormattedParam = " -$ParamName" + ":`$True,"
            }
            else
            {
                If ($value -eq "False")
                {
                    $FormattedParam = " -$ParamName" + ":`$False,"
                }
                else
                {
                    $FormattedParam += "`"$value`","
                }
            }
        }
        $FormattedParam = $FormattedParam.TrimEnd(",")
    }
    Return $FormattedParam
}

Switch ($Mode)
{
    Export
    {
        If (!$UseExistingSession) { SourceTenantLogon }
        
        Write-Log -ConsoleOutput -LogLevel Info -Message "Exporting..."
        
        # Connection Filter Policy
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...HostedConnectionFilterPolicy"
        Get-HostedConnectionFilterPolicy | Export-Clixml HostedConnectionFilterPolicy.xml
        
        # Content Filter Policy
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...HostedContentFilterPolicy"
        Get-HostedContentFilterPolicy | Export-Clixml HostedContentFilterPolicy.xml
        
        # Content Filter Rules
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...HostedContentFilterRule"
        Get-HostedContentFilterRule | Export-Clixml HostedContentFilterRule.xml
        
        # Outbound Spam Filter
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...HostedOutboundSpamFilterPolicy"
        Get-HostedOutboundSpamFilterPolicy | Export-Clixml HostedOutboundSpamFilterPolicy.xml
        
        # Anti-malware Content Filter Policy
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...MalwareFilterPolicy"
        Get-MalwareFilterPolicy | Export-Clixml MalwareFilterPolicy.xml
        
        # Anti-malware Filter Rules
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...MalwareFilterRule"
        Get-MalwareFilterRule | Export-Clixml MalwareFilterRule.xml
        
        # Inbound Connectors
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...InboundConnector"
        Get-InboundConnector | Export-Clixml InboundConnector.xml
        
        # Outbound Connectors
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...OutboundConnector"
        Get-OutboundConnector | Export-Clixml OutboundConnector.xml
        
        # Transport rules
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...TransportRuleCollection"
        $file = Export-TransportRuleCollection
        Set-Content -Path ".\TransportRules.xml" -Value $file.FileData -Encoding Byte
        
        # Domains
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...AcceptedDomains"
        Get-MsolDomain | Where-Object { $_.DomainName -notlike "*onmicrosoft.com" } | Export-Clixml Domains.xml
        
        # ATP
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...ATP tenant policy settings"
        Get-AtpPolicyForO365 | Export-Clixml AtpPolicyForO365.xml
        
        # ATP Safe Attachments
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...ATP Safe Attachments"
        Get-SafeAttachmentPolicy | Export-Clixml SafeAttachmentPolicy.xml
        Get-SafeAttachmentRule | Export-Clixml SafeAttachmentRule.xml
        
        # ATP Safe Links
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...ATP Safe Links"
        Get-SafeLinksPolicy | Export-Clixml SafeLinksPolicy.xml
        Get-SafeLinksRule | Export-Clixml SafeLinksRule.xml
        
        Get-PSSession | Remove-PSSession
        Write-Log -ConsoleOutput -LogLevel Success -Message "Export task completed."
    }
    
    ExportDomains
    {
        If (!$UseExistingSession) { SourceTenantLogon }
        
        # Domains
        Write-Log -ConsoleOutput -LogLevel Info -Message " ...AcceptedDomains"
        Get-MsolDomain | Where-Object {
            $_.DomainName -notlike "*onmicrosoft.com"
        } | Export-Clixml Domains.xml
        Write-Log -ConsoleOutput -LogLevel Info -Message "Export Domains task completed."
    }
    
    ImportMalwareSettingsOnly
    {
        If (!$UseExistingSession) { TargetTenantLogon }
        
        # MalwareFitlerPolicy
        $MalwareFilterPolicies = Import-Clixml ".\MalwareFilterPolicy.xml"
        $MalwareFilterPolicyCount = $MalwareFilterPolicies.Name.Count
        
        If ($MalwareFilterPolicyCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing MalwareFilterPoliciesCount Malware Filter Policies"
            foreach ($MalwareFilterPolicy in $MalwareFilterPolicies)
            {
                If (Get-MalwareFilterPolicy $MalwareFilterPolicy.Name -ea silentlycontinue) { $MalwareFilterPolicyCmdlet = "Set-MalwareFilterPolicy -Identity `"$($MalwareFilterPolicy.Name)`"" }
                Else { $MalwareFilterPolicyCmdlet = "New-MalwareFilterPolicy -Name `"$($MalwareFilterPolicy.Name)`"" }
                #$MalwareFilterPolicyCmdlet += makeparam "Name" $MalwareFilterPolicy.Name
                If (!($MalwareFilterPolicy.CustomAlertText -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomAlertText" $MalwareFilterPolicy.CustomAlertText }
                If (!($MalwareFilterPolicy.AdminDisplayName -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "AdminDisplayName" $MalwareFilterPolicy.AdminDisplayName }
                If (!($MalwareFilterPolicy.CustomInternalSubject -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomInternalSubject" $MalwareFilterPolicy.CustomInternalSubject }
                If (!($MalwareFilterPolicy.CustomInternalBody -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomInternalBody" $MalwareFilterPolicy.CustomInternalBody }
                If (!($MalwareFilterPolicy.CustomExternalSubject -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomExternalSubject" $MalwareFilterPolicy.CustomInternalSubject }
                If (!($MalwareFilterPolicy.CustomExternalBody -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomExternalBody" $MalwareFilterPolicy.CustomExternalBody }
                If (!($MalwareFilterPolicy.CustomFromName -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomFromName" $MalwareFilterPolicy.CustomFromName }
                If (!($MalwareFilterPolicy.CustomFromAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomFromAddress" $MalwareFilterPolicy.CustomFromAddress }
                If (!($MalwareFilterPolicy.InternalSenderAdminAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "InternalSenderAdminAddress" $MalwareFilterPolicy.InternalSenderAdminAddress }
                If (!($MalwareFilterPolicy.ExternalSenderAdminAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "ExternalSenderAdminAddress" $MalwareFilterPolicy.ExternalSenderAdminAddress }
                If (!($MalwareFilterPolicy.BypassInboundMessages -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "BypassInboundMessages" $MalwareFilterPolicy.BypassInboundMessages }
                If (!($MalwareFilterPolicy.BypassOutboundMessages -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "BypassOutboundMessages" $MalwareFilterPolicy.BypassOutboundMessages }
                If (!($MalwareFilterPolicy.Action -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "Action" $MalwareFilterPolicy.Action }
                If (!($MalwareFilterPolicy.CustomNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomNotifications" $MalwareFilterPolicy.CustomNotifications }
                If (!($MalwareFilterPolicy.EnableInternalSenderNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableInternalSenderNotifications" $MalwareFilterPolicy.EnableInternalSenderNotifications }
                If (!($MalwareFilterPolicy.EnableExternalSenderNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableExternalSenderNotifications" $MalwareFilterPolicy.EnableExternalSenderNotifications }
                If (!($MalwareFilterPolicy.EnableInternalSenderAdminNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableInternalSenderAdminNotifications" $MalwareFilterPolicy.EnableInternalSenderAdminNotifications }
                If (!($MalwareFilterPolicy.EnableFileFilter -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableFileFilter" $MalwareFilterPolicy.EnableFileFilter }
                If (!($MalwareFilterPolicy.FileTypes -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "FileTypes" $MalwareFilterPolicy.FileTypes }
                If (!($MalwareFilterPolicy.ZapEnabled -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "ZapEnabled" $MalwareFilterPolicy.ZapEnabled }
                
                # Executing Cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing malware policy $($MalwareFilterPolicy.Name)"
                # Write-Log -ConsoleOutput -LogLevel Info -Message "Will execute $($MalwareFilterPolicyCmdlet)"
                Invoke-Expression $MalwareFilterPolicyCmdlet
            }
        }
        
        # MalwareFilterRule
        $MalwareFilterRules = Import-Clixml ".\MalwareFilterRule.xml"
        $MalwareFilterRuleCount = $MalwareFilterRules.Name.Count
        
        if ($MalwareFilterRuleCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $MalwareFilterRuleCount Malware Filter Rules"
            ForEach ($MalwareFilterRule in $MalwareFilterRules)
            {
                If ((Get-MalwareFilterRule $MalwareFilterRule.Name -ea silentlycontinue)) { $MalwareFilterRuleCmdlet = "Set-MalwareFilterRule -Identity `"$($MalwareFilterRule.Name)`"" }
                Else { $MalwareFilterRuleCmdlet = "New-MalwareFilterRule -Name `"$($MalwareFilterRule.Name)`"" }
                $MalwareFilterRuleCmdlet += makeparam "MalwareFilterPolicy" $MalwareFilterRule.MalwareFilterPolicy
                $MalwareFilterRuleCmdlet += makeparam "Comments" $MalwareFilterRule.Comments
                $MalwareFilterRuleCmdlet += " -Confirm:`$False"
                $MalwareFilterRuleCmdlet += makeparam "Enabled" $MalwareFilterRule.Enabled
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfRecipientDomainIs" $MalwareFilterRule.ExceptIfRecipientDomainIs
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfSentTo" $MalwareFilterRule.ExceptIfSentTo
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfSentToMemberOf" $MalwareFilterRule.ExceptIfSentToMemberOf
                $MalwareFilterRuleCmdlet += makeparam "RecipientDomainIs" $MalwareFilterRule.RecipientDomainIs
                $MalwareFilterRuleCmdlet += makeparam "SentTo" $MalwareFilterRule.SentTo
                $MalwareFilterRuleCmdlet += makeparam "SentToMemberOf" $MalwareFilterRule.SentToMemberOf
                $MalwareFilterRuleCmdlet += " -erroraction silentlycontinue"
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing malware rule $($MalwareFilterRule.Name)."
                Invoke-Expression $MalwareFilterRuleCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Malware Filter Rules to add."
        }
    }
    
    ImportTransportRulesOnly
    {
        If (!$UseExistingSession) { TargetTenantLogon }
        
        # Check existing Transport Rules for Encryption Settings
        [XML]$CheckTransportRules = Get-Content .\TransportRules.xml
        [array]$RulesWithEncryption = $CheckTransportRules.rules.rule | Where-Object {
            $_.InnerXML -like "*ApplyOME*"
        } | Select-Object -ExpandProperty Name
        If ($RulesWithEncryption.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Warn -Message "The following rules require AADRM to be configured to work properly."
            Write-Log -ConsoleOutput -LogLevel Warn -Message $RulesWithEncryption
        }
        else {
            Write-Log -ConsoleOutput -LogLevel Success -Message "No transport rules with encryption identified."
        }
        
        # Enable Azure Rights Management
        If ($AADRM)
        {
            Switch ($AADRM)
            {
                GCC
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.govus.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                
                NA
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.na.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                EU
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.eu.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                AP
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.ap.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                SA
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.sa.aadrm.com/TenantManagement/ServicePartner.svc"
                }
            }
            
            If (!(Get-Module -ListAvailable AADRM))
            {
                If ($InstallModules)
                {
                    Write-Log -ConsoleOutput -LogLevel Error -Message "AADRM Module not present. Attempting to download and install."
                    InstallSupportingModules
                    Install-Module AADRM -Force
                }
            }
            
            If (!(Get-Module -ListAvailable AADRM))
            {
                If ($RulesWithEncryption.Count -gt 0)
                {
                    Write-Log -ConsoleOutput -LogLevel Error -Message "The following transport rules may not import due to Encryption Settings."
                    Write-Log -ConsoleOutput -LogLevel Error -Message $RulesWithEncryption
                }
            }
            Else
            {
                Import-Module AADRM
                If (!($TargetTenantCredential))
                {
                    $TargetTenantCredential = Get-Credential -Message "Target Office 365 Credential"
                    Connect-AADRMService -Credential $TargetTenantCredential
                    Enable-AADRM
                    Set-IRMConfiguration -RMSOnlineKeySharingLocation $RMSOnlineKeySharingLocation
                    Import-RMSTrustedPublishingDomain -RMSOnline -name "RMS Online"
                    Set-IRMConfiguration -InternalLicensingEnabled $true
                }
            }
        }
        # TransportRules
        Write-Log -ConsoleOutput -LogLevel Info -Message "Processing Transport Rules."
        [Byte[]]$Data = Get-Content -Path ".\TransportRules.xml" -Encoding Byte -ReadCount 0
        Import-TransportRuleCollection -FileData $Data -Confirm:$false -Force
        Get-PSSession | Remove-PSSession
        Write-Log -ConsoleOutput -LogLevel Success -Message "Import Transport Rules Only task completed."
    }
    
    ImportDomains
    {
        
        If (!$UseExistingSession) { TargetTenantLogon }
        
        # Domains
        Write-Log -ConsoleOutput -LogLevel Info -Message "Registering domains."
        
        $Domains = Import-Clixml .\Domains.xml
        $VerificationDns = New-Object PSCustomObject
        foreach ($domain in $domains)
        {
            New-MsolDomain -Name $domain.Name
            
            $VerificationDnsValue = (Get-MsolDomainVerificationDns -DomainName $domain.Name).Label
            $VerificationDnsValue = "MS=" + $VerificationDnsValue.Split(".")[0]
            $VerificationDns | Add-Member -MemberType NoteProperty -Name Domain -Value $domain.Name
            $VerificationDns | Add-Member -MemberType NoteProperty -Name RecordType -Value TXT
            $VerificationDns | Add-Member -MemberType NoteProperty -Name Value -Value $VerificationDnsValue
        }
        $VerificationDns | Export-Csv -NoTypeInformation DnsVerificationValues.csv -Append
        Write-Log -ConsoleOutput -LogLevel Info -Message "File DnsVerificationValues.csv has been created. Please add the DNS TXT verifications records to external DNS."
        Get-PSSession | Remove-PSSession
        Write-Log -ConsoleOutput -LogLevel Success -Message "Import domains task completed."
    }
    
    Import
    {
        If (!$UseExistingSession) { TargetTenantLogon }
        
        # Enable Organization Customization of tenant
        Enable-OrganizationCustomization -ea SilentlyContinue -wa SilentlyContinue
        
        # Hosted Content Filter Policies
        $HostedContentFilterPolicies = Import-Clixml ".\HostedContentFilterPolicy.xml"
        $HostedContentFilterPolicyCount = $HostedContentFilterPolicies.Name.Count
        
        If ($HostedContentFilterPolicyCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($HostedContentFilterPolicyCount) Hosted Content Filter Policies."
            ForEach ($HostedContentFilterPolicy in $HostedContentFilterPolicies)
            {
                # Building Cmdlet
                $HostedContentFilterPolicyCmdlet = "New-HostedContentFilterPolicy"
                If ($HostedContentFilterPolicy.Name -eq "Default")
                {
                    $HostedContentFilterPolicyCmdlet = "Set-HostedContentFilterPolicy -Identity Default"
                }
                Else
                {
                    $HostedContentFilterPolicyCmdlet += makeparam "Name" $HostedContentFilterPolicy.Name
                }
                $HostedContentFilterPolicyCmdlet += makeparam "AddXHeaderValue" $HostedContentFilterPolicy.AddXHeaderValue
                $HostedContentFilterPolicyCmdlet += makeparam "AdminDisplayName" $HostedContentFilterPolicy.AdminDisplayName.Replace("""", "")
                $HostedContentFilterPolicyCmdlet += " -Confirm:`$False"
                $HostedContentFilterPolicyCmdlet += makeparam "DownloadLink" $HostedContentFilterPolicy.DownloadLink
                $HostedContentFilterPolicyCmdlet += makeparam "EnableEndUserSpamNotifications" $HostedContentFilterPolicy.EnableEndUserSpamNotifications
                $HostedContentFilterPolicyCmdlet += makeparam "EnableLanguageBlockList" $HostedContentFilterPolicy.EnableLanguageBlockList
                $HostedContentFilterPolicyCmdlet += makeparam "EnableRegionBlockList" $HostedContentFilterPolicy.EnableRegionBlockList
                
                If ($HostedContentFilterPolicy.EndUserSpamNotificationCustomFromAddress.Length -gt 0)
                {
                    $HostedContentFilterPolicyCmdlet += makeparam "EndUserSpamNotificationCustomFromAddress" $HostedContentFilterPolicy.EndUserSpamNotificationCustomFromAddress
                }
                $HostedContentFilterPolicyCmdlet += makeparam "EndUserSpamNotificationCustomFromName" $HostedContentFilterPolicy.EndUserSpamNotificationCustomFromName
                $HostedContentFilterPolicyCmdlet += makeparam "EndUserSpamNotificationCustomSubject" $HostedContentFilterPolicy.EndUserSpamNotificationCustomSubject
                $HostedContentFilterPolicyCmdlet += makeparam "EndUserSpamNotificationFrequency" $HostedContentFilterPolicy.EndUserSpamNotificationFrequency
                $HostedContentFilterPolicyCmdlet += makeparam "EndUserSpamNotificationLanguage" $HostedContentFilterPolicy.EndUserSpamNotificationLanguage
                $HostedContentFilterPolicyCmdlet += makeparam "LanguageBlockList" $HostedContentFilterPolicy.LanguageBlockList
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamBulkMail" $HostedContentFilterPolicy.MarkAsSpamBulkMail
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamEmbedTagsInHtml" $HostedContentFilterPolicy.MarkAsSpamEmbedTagsInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamEmptyMessages" $HostedContentFilterPolicy.MarkAsSpamEmptyMessages
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamFormTagsInHtml" $HostedContentFilterPolicy.MarkAsSpamFormTagsInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamFramesInHtml" $HostedContentFilterPolicy.MarkAsSpamFramesInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamFromAddressAuthFail" $HostedContentFilterPolicy.MarkAsSpamFromAddressAuthFail
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamJavaScriptInHtml" $HostedContentFilterPolicy.MarkAsSpamJavaScriptInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamNdrBackscatter" $HostedContentFilterPolicy.MarkAsSpamNdrBackscatter
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamObjectTagsInHtml" $HostedContentFilterPolicy.MarkAsSpamObjectTagsInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamSensitiveWordList" $HostedContentFilterPolicy.MarkAsSpamSensitiveWordList
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamSpfRecordHardFail" $HostedContentFilterPolicy.MarkAsSpamSpfRecordHardFail
                $HostedContentFilterPolicyCmdlet += makeparam "MarkAsSpamWebBugsInHtml" $HostedContentFilterPolicy.MarkAsSpamWebBugsInHtml
                $HostedContentFilterPolicyCmdlet += makeparam "ModifySubjectValue" $HostedContentFilterPolicy.ModifySubjectValue
                $HostedContentFilterPolicyCmdlet += makeparam "Organization" $HostedContentFilterPolicy.Organization
                $HostedContentFilterPolicyCmdlet += makeparam "QuarantineRetentionPeriod" $HostedContentFilterPolicy.QuarantineRetentionPeriod
                $HostedContentFilterPolicyCmdlet += makeparam "RedirectToRecipients" $HostedContentFilterPolicy.RedirectToRecipients
                $HostedContentFilterPolicyCmdlet += makeparam "RegionBlockList" $HostedContentFilterPolicy.RegionBlockList
                $HostedContentFilterPolicyCmdlet += makeparam "SpamAction" $HostedContentFilterPolicy.SpamAction
                $HostedContentFilterPolicyCmdlet += makeparam "TestModeBccToRecipients" $HostedContentFilterPolicy.TestModeBccToRecipients
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing policy $($HostedContentFilterPolicy.Name)."
                Invoke-Expression $HostedContentFilterPolicyCmdlet
            }
        }
        Else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Hosted Content Policy Filters to add."
        }
        
        # HostedContentFilterRule
        $HostedContentFilterRules = Import-Clixml ".\HostedContentFilterRule.xml"
        $HostedContentFilterRuleCount = $HostedContentFilterRules.Name.Count
        
        if ($HostedContentFilterRuleCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($HostedContentFilterRuleCount) Hosted Content Filter Rules."
            ForEach ($HostedContentFilterRule in $HostedContentFilterRules)
            {
                $HostedContentFilterRuleCmdlet = "New-HostedContentFilterRule"
                if ($HostedContentFilterRule.Name -eq "Default")
                {
                    $HostedContentFilterRuleCmdlet = "Set-HostedContentFilterRule Default"
                }
                $HostedContentFilterRuleCmdlet += makeparam "Name" $HostedContentFilterRule.Name
                $HostedContentFilterRuleCmdlet += makeparam "HostedContentFilterPolicy" $HostedContentFilterRule.HostedContentFilterPolicy
                $HostedContentFilterRuleCmdlet += makeparam "Comments" $HostedContentFilterRule.Comments
                $HostedContentFilterRuleCmdlet += " -Confirm:`$False"
                $HostedContentFilterRuleCmdlet += makeparam "Enabled" $HostedContentFilterRule.Enabled
                $HostedContentFilterRuleCmdlet += makeparam "ExceptIfRecipientDomainIs" $HostedContentFilterRule.ExceptIfRecipientDomainIs
                $HostedContentFilterRuleCmdlet += makeparam "ExceptIfSentTo" $HostedContentFilterRule.ExceptIfSentTo
                $HostedContentFilterRuleCmdlet += makeparam "ExceptIfSentToMemberOf" $HostedContentFilterRule.ExceptIfSentToMemberOf
                $HostedContentFilterRuleCmdlet += makeparam "Priority" $HostedContentFilterRule.Priority
                $HostedContentFilterRuleCmdlet += makeparam "RecipientDomainIs" $HostedContentFilterRule.RecipientDomainIs
                $HostedContentFilterRuleCmdlet += makeparam "SentTo" $HostedContentFilterRule.SentTo
                $HostedContentFilterRuleCmdlet += makeparam "SentToMemberOf" $HostedContentFilterRule.SentToMemberOf
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing rule $($HostedContentFilterRule.Name)."
                Invoke-Expression $HostedContentFilterRuleCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Hosted Content Filter Rules to add."
        }
        
        # HostedOutboundSpamFilterPolicy
        $HostedOutboundSpamFilterPolicyies = Import-Clixml ".\HostedOutboundSpamFilterPolicy.xml"
        $HostedOutboundSpamFilterPolicyCount = $HostedOutboundSpamFilterPolicies.Name.Count
        
        if ($HostedOutboundSpamFilterPolicyCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($HostedOutboundSpamFilterPolicyCount) Hosted Outbound Spam Filter Policies"
            ForEach ($HostedOutboundSpamFilterPolicy in $HostedOutboundSpamFilterPolicies)
            {
                $HostedOutboundSpamFilterPolicyCmdlet = "Set-HostedOutboundSpamFilterPolicy Default"
                $HostedOutboundSpamFilterPolicyCmdlet += makeparam "AdminDisplayName" $HostedOutboundSpamFilterPolicy.AdminDisplayName.Replace("""", "")
                $HostedOutboundSpamFilterPolicyCmdlet += makeparam "BccSuspiciousOutboundAdditionalRecipients" $HostedOutboundSpamFilterPolicy.BccSuspiciousOutboundAdditionalRecipients
                $HostedOutboundSpamFilterPolicyCmdlet += makeparam "BccSuspiciousOutboundMail" $HostedOutboundSpamFilterPolicy.BccSuspiciousOutboundMail
                $HostedOutboundSpamFilterPolicyCmdlet += " -Confirm:`$False"
                $HostedOutboundSpamFilterPolicyCmdlet += makeparam "NotifyOutboundSpam" $HostedOutboundSpamFilterPolicy.NotifyOutboundSpam
                $NotifyOutboundSpamRecipients += makeparam "NotifyOutboundSpamRecipients" $HostedOutboundSpamFilterPolicy.NotifyOutboundSpamRecipients
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing Hosted Outbound Spam Filter policy."
                Invoke-Expression $HostedOutboundSpamFilterPolicyCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Hosted Outbound Spam Filter Policies to add."
        }
        
        # HostedConnectionFilterPolicy
        $HostedConnectionFilterPolicies = Import-Clixml ".\HostedConnectionFilterPolicy.xml"
        $HostedConnectionFilterPolicyCount = $HostedConnectionFilterPolicies.Name.Count
        
        if ($HostedConnectionFilterPolicyCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($HostedConnectionFilterPolicyCount) Hosted Connection Filter Policies"
            ForEach ($HostedConnectionFilterPolicy in $HostedConnectionFilterPolicies)
            {
                $HostedConnectionFilterPolicyCmdlet = "Set-HostedConnectionFilterPolicy"
                $HostedConnectionFilterPolicyCmdlet += makeparam "Identity" $HostedConnectionFilterPolicy.Name
                
                $HostedConnectionFilterPolicyCmdlet += makeparam "AdminDisplayName" $HostedConnectionFilterPolicy.AdminDisplayName.Replace("""", "")
                $HostedConnectionFilterPolicyCmdlet += " -Confirm:`$False"
                $HostedConnectionFilterPolicyCmdlet += makeparam "EnableSafeList" $HostedConnectionFilterPolicy.EnableSafeList
                $HostedConnectionFilterPolicyCmdlet += makeparam "IPAllowList" $HostedConnectionFilterPolicy.IPAllowList
                $HostedConnectionFilterPolicyCmdlet += makeparam "IPBlockList" $HostedConnectionFilterPolicy.IPBlockList
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing Connection Filter policy $($HostedConnectionFilterPolicy.Name)."
                Invoke-Expression $HostedConnectionFilterPolicyCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Hosted Connection Filter Policies to add."
        }
        
        # MalwareFitlerPolicy
        $MalwareFilterPolicies = Import-Clixml ".\MalwareFilterPolicy.xml"
        $MalwareFilterPolicyCount = $MalwareFilterPolicies.Name.Count
        
        If ($MalwareFilterPolicyCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing MalwareFilterPoliciesCount Malware Filter Policies"
            foreach ($MalwareFilterPolicy in $MalwareFilterPolicies)
            {
                If (Get-MalwareFilterPolicy $MalwareFilterPolicy.Name -ea silentlycontinue) { $MalwareFilterPolicyCmdlet = "Set-MalwareFilterPolicy -Identity `"$($MalwareFilterPolicy.Name)`"" }
                Else { $MalwareFilterPolicyCmdlet = "New-MalwareFilterPolicy -Name `"$($MalwareFilterPolicy.Name)`""}
                #$MalwareFilterPolicyCmdlet += makeparam "Name" $MalwareFilterPolicy.Name
                If (!($MalwareFilterPolicy.CustomAlertText -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomAlertText" $MalwareFilterPolicy.CustomAlertText }
                If (!($MalwareFilterPolicy.AdminDisplayName -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "AdminDisplayName" $MalwareFilterPolicy.AdminDisplayName }
                If (!($MalwareFilterPolicy.CustomInternalSubject -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomInternalSubject" $MalwareFilterPolicy.CustomInternalSubject }
                If (!($MalwareFilterPolicy.CustomInternalBody -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomInternalBody" $MalwareFilterPolicy.CustomInternalBody }
                If (!($MalwareFilterPolicy.CustomExternalSubject -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomExternalSubject" $MalwareFilterPolicy.CustomInternalSubject }
                If (!($MalwareFilterPolicy.CustomExternalBody -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomExternalBody" $MalwareFilterPolicy.CustomExternalBody }
                If (!($MalwareFilterPolicy.CustomFromName -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomFromName" $MalwareFilterPolicy.CustomFromName }
                If (!($MalwareFilterPolicy.CustomFromAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomFromAddress" $MalwareFilterPolicy.CustomFromAddress }
                If (!($MalwareFilterPolicy.InternalSenderAdminAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "InternalSenderAdminAddress" $MalwareFilterPolicy.InternalSenderAdminAddress }
                If (!($MalwareFilterPolicy.ExternalSenderAdminAddress -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "ExternalSenderAdminAddress" $MalwareFilterPolicy.ExternalSenderAdminAddress }
                If (!($MalwareFilterPolicy.BypassInboundMessages -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "BypassInboundMessages" $MalwareFilterPolicy.BypassInboundMessages }
                If (!($MalwareFilterPolicy.BypassOutboundMessages -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "BypassOutboundMessages" $MalwareFilterPolicy.BypassOutboundMessages }
                If (!($MalwareFilterPolicy.Action -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "Action" $MalwareFilterPolicy.Action }
                If (!($MalwareFilterPolicy.CustomNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "CustomNotifications" $MalwareFilterPolicy.CustomNotifications }
                If (!($MalwareFilterPolicy.EnableInternalSenderNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableInternalSenderNotifications" $MalwareFilterPolicy.EnableInternalSenderNotifications }
                If (!($MalwareFilterPolicy.EnableExternalSenderNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableExternalSenderNotifications" $MalwareFilterPolicy.EnableExternalSenderNotifications }
                If (!($MalwareFilterPolicy.EnableInternalSenderAdminNotifications -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableInternalSenderAdminNotifications" $MalwareFilterPolicy.EnableInternalSenderAdminNotifications }
                If (!($MalwareFilterPolicy.EnableFileFilter -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "EnableFileFilter" $MalwareFilterPolicy.EnableFileFilter }
                If (!($MalwareFilterPolicy.FileTypes -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "FileTypes" $MalwareFilterPolicy.FileTypes }
                If (!($MalwareFilterPolicy.ZapEnabled -eq "")) { $MalwareFilterPolicyCmdlet += makeparam "ZapEnabled" $MalwareFilterPolicy.ZapEnabled }
                
                # Executing Cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing malware policy $($MalwareFilterPolicy.Name)"
                # Write-Log -ConsoleOutput -LogLevel Info -Message "Will execute $($MalwareFilterPolicyCmdlet)"
                Invoke-Expression $MalwareFilterPolicyCmdlet
            }
        }
                
        # MalwareFilterRule
        $MalwareFilterRules = Import-Clixml ".\MalwareFilterRule.xml"
        $MalwareFilterRuleCount = $MalwareFilterRules.Name.Count
        
        if ($MalwareFilterRuleCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $MalwareFilterRuleCount Malware Filter Rules"
            ForEach ($MalwareFilterRule in $MalwareFilterRules)
            {
                If ((Get-MalwareFilterRule $MalwareFilterRule.Name -ea silentlycontinue)) { $MalwareFilterRuleCmdlet = "Set-MalwareFilterRule -Identity `"$($MalwareFilterRule.Name)`"" }
                Else { $MalwareFilterRuleCmdlet = "New-MalwareFilterRule -Name `"$($MalwareFilterRule.Name)`"" }
                $MalwareFilterRuleCmdlet += makeparam "MalwareFilterPolicy" $MalwareFilterRule.MalwareFilterPolicy
                $MalwareFilterRuleCmdlet += makeparam "Comments" $MalwareFilterRule.Comments
                $MalwareFilterRuleCmdlet += " -Confirm:`$False"
                $MalwareFilterRuleCmdlet += makeparam "Enabled" $MalwareFilterRule.Enabled
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfRecipientDomainIs" $MalwareFilterRule.ExceptIfRecipientDomainIs
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfSentTo" $MalwareFilterRule.ExceptIfSentTo
                $MalwareFilterRuleCmdlet += makeparam "ExceptIfSentToMemberOf" $MalwareFilterRule.ExceptIfSentToMemberOf
                $MalwareFilterRuleCmdlet += makeparam "RecipientDomainIs" $MalwareFilterRule.RecipientDomainIs
                $MalwareFilterRuleCmdlet += makeparam "SentTo" $MalwareFilterRule.SentTo
                $MalwareFilterRuleCmdlet += makeparam "SentToMemberOf" $MalwareFilterRule.SentToMemberOf
                $MalwareFilterRuleCmdlet += " -erroraction silentlycontinue"
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing malware rule $($MalwareFilterRule.Name)."
                Invoke-Expression $MalwareFilterRuleCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Malware Filter Rules to add."
        }
        
        # InboundConnectors
        Write-Log -ConsoleOutput -LogLevel Info -Message "Import inbound connectors."
        $InboundConnectors = Import-Clixml ".\InboundConnector.xml"
        
        $InboundConnectorCount = $InboundConnectors.Name.Count
        
        if ($InboundConnectorCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $InboundConnectorCount Inbound Connectors"
            ForEach ($InboundConnector in $InboundConnectors)
            {
                $InboundConnectorCmdlet = "New-InboundConnector"
                
                $InboundConnectorCmdlet += makeparam "Name" $InboundConnector.Name
                $InboundConnectorCmdlet += makeparam "SenderDomains" $InboundConnector.SenderDomains
                
                If ($InboundConnector.AssociatedAcceptedDomains.Count -gt 0)
                {
                    If ($InboundConnector.AssociatedAcceptedDomains[0].Contains("/"))
                    {
                        # This connector was created in an EOP Standard tenant
                        # Strip out just the domain name
                        $InboundConnectorCmdlet += " -AssociatedAcceptedDomains "
                        ForEach ($accepteddomain in $InboundConnectors.AssociatedAcceptedDomains)
                        {
                            $accepteddomain = $accepteddomain.SubString($accepteddomain.LastIndexOf("/") + 1)
                            $InboundConnectorCmdlet += "`"$accepteddomain`","
                        }
                        $InboundConnectorCmdlet = $InboundConnectorCmdlet.TrimEnd(",")
                    }
                    else
                    {
                        $InboundConnectorCmdlet += makeparam "AssociatedAcceptedDomains" $InboundConnector.AssociatedAcceptedDomains
                    }
                }
                
                $InboundConnectorCmdlet += makeparam "CloudServicesMailEnabled" $InboundConnector.CloudServicesMailEnabled
                $InboundConnectorCmdlet += makeparam "Comment" $InboundConnector.Comment
                $InboundConnectorCmdlet += " -Confirm:`$False"
                $InboundConnectorCmdlet += makeparam "ConnectorSource" $InboundConnector.ConnectorSource
                $InboundConnectorCmdlet += makeparam "ConnectorType" $InboundConnector.ConnectorType
                $InboundConnectorCmdlet += makeparam "Enabled" $InboundConnector.Enabled
                $InboundConnectorCmdlet += makeparam "RequireTls" $InboundConnector.RequireTls
                $InboundConnectorCmdlet += makeparam "RestrictDomainsToCertificate" $InboundConnector.RestrictDomainsToCertificate
                $InboundConnectorCmdlet += makeparam "RestrictDomainsToIPAddresses" $InboundConnector.RestrictDomainsToIPAddresses
                $InboundConnectorCmdlet += makeparam "SenderIPAddresses" $InboundConnector.SenderIPAddresses
                $InboundConnectorCmdlet += makeparam "TlsSenderCertificateName" $InboundConnector.TlsSenderCertificateName
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing Inbound Connector $($InboundConnector.Name)."
                Invoke-Expression $InboundConnectorCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Inbound Connectors to add."
        }
        
        # OutboundConnectors
        Write-Log -ConsoleOutput -LogLevel Info -Message "Import outbound connectors."
        $OutboundConnectors = Import-Clixml ".\OutboundConnector.xml"
        $OutboundConnectorCount = $OutboundConnectors.Name.Count
        
        if ($OutboundConnectorCount -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($OutboundConnectorCount) Outbound Connectors"
            ForEach ($OutboundConnector in $OutboundConnectors)
            {
                $OutboundConnectorCmdlet = "New-OutboundConnector"
                $OutboundConnectorCmdlet += makeparam "Name" $OutboundConnector.Name
                $OutboundConnectorCmdlet += makeparam "AllAcceptedDomains" $OutboundConnector.AllAcceptedDomains
                $OutboundConnectorCmdlet += makeparam "BypassValidation" $OutboundConnector.BypassValidation
                $OutboundConnectorCmdlet += makeparam "CloudServicesMailEnabled" $OutboundConnector.CloudServicesMailEnabled
                $OutboundConnectorCmdlet += makeparam "Comment" $OutboundConnector.Comment
                $OutboundConnectorCmdlet += " -Confirm:`$False"
                $OutboundConnectorCmdlet += makeparam "ConnectorSource" $OutboundConnector.ConnectorSource
                $OutboundConnectorCmdlet += makeparam "ConnectorType" $OutboundConnector.ConnectorType
                $OutboundConnectorCmdlet += makeparam "IsTransportRuleScoped" $OutboundConnector.IsTransportRuleScoped
                $OutboundConnectorCmdlet += makeparam "RecipientDomains" $OutboundConnector.RecipientDomains
                $OutboundConnectorCmdlet += makeparam "RouteAllMessagesViaOnPremises" $OutboundConnector.RouteAllMessagesViaOnPremises
                $OutboundConnectorCmdlet += makeparam "SmartHosts" $OutboundConnector.SmartHosts
                $OutboundConnectorCmdlet += makeparam "TlsDomain" $OutboundConnector.TlsDomain
                $OutboundConnectorCmdlet += makeparam "TlsSettings" $OutboundConnector.TlsSettings
                $OutboundConnectorCmdlet += makeparam "UseMXRecord" $OutboundConnector.UseMXRecord
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Importing Outbound Connector $($OutboundConnector.Name)."
                Invoke-Expression $OutboundConnectorCmdlet
            }
        }
        else
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "No Outbound Connectors to add."
        }
        
        # ATP Tenant Policy
        Write-Log -ConsoleOutput -LogLevel Info -Message "Import ATP Tenant policy."
        $AtpPolicyForO365 = Import-Clixml .\AtpPolicyForO365.xml
        If ($AtpPolicyForO365.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing ATP Tenant Policy."
            $AtpPolicyCmdlet = "Set-AtpPolicyForO365"
            $AtpPolicyCmdlet += makeparam "TrackClicks" $AtpPolicyForO365.TrackClicks
            $AtpPolicyCmdlet += makeparam "BlockUrls" $AtpPolicyForO365.BlockUrls
            $AtpPolicyCmdlet += makeparam "EnableSafeLinksForClients" $AtpPolicyForO365.EnableSafeLinksForClients
            $AtpPolicyCmdlet += makeparam "EnableATPForSPOTeamsODB" $AtpPolicyForO365.EnableATPForSPOTeamsODB
            $AtpPolicyCmdlet += makeparam "AllowClickThrough" $AtpPolicyForO365.AllowClickThrough
            $AtpPolicyCmdlet += makeparam "EnableSafeLinksForWebAccessCompanion" $AtpPolicyForO365.EnableSafeLinksForWebAccessCompanion
            
            # Executing cmdlet
            Write-Log -ConsoleOutput -LogLevel Info -Message "Setting ATP Tenant Policy."
            Invoke-Expression $AtpPolicyCmdlet
        }
        
        # ATP Safe Attachments
        Write-Log -ConsoleOutput -LogLevel Info -Message "Import ATP Safe Attachments Policies."
        [array]$SafeAttachmentPolicies = Import-Clixml .\SafeAttachmentPolicy.xml
        [array]$SafeAttachmentRules = Import-Clixml .\SafeAttachmentRule.xml
        [int]$SafeAttachmentPoliciesCount = $SafeAttachmentPolicies.Name.Count
        [int]$SafeAttachmentRulesCount = $SafeAttachmentRules.Name.Count
        if ($SafeAttachmentPolicies.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($SafeAttachmentPoliciesCount) Safe Attachments Policies."
            foreach ($Policy in $SafeAttachmentPolicies)
            {
                $SafeAttachmentPolicyCmdlet = "New-SafeAttachmentPolicy"
                $SafeAttachmentPolicyCmdlet += makeparam "Redirect" $Policy.Redirect
                $SafeAttachmentPolicyCmdlet += makeparam "Name" $Policy.Name
                $SafeAttachmentPolicyCmdlet += makeparam "AdminDisplayName" $Policy.AdminDisplayName
                $SafeAttachmentPolicyCmdlet += makeparam "Enable" $Policy.Enable
                $SafeAttachmentPolicyCmdlet += makeparam "RedirectAddress" $Policy.RedirectAddress
                $SafeAttachmentPolicyCmdlet += makeparam "Action" $Policy.Action
                $SafeAttachmentPolicyCmdlet += makeparam "ActionOnError" $Policy.ActionOnError
                
                # Executing Cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Adding Safe Attachment Policy $($Policy.Name)."
                Invoke-Expression $SafeAttachmentPolicyCmdlet
            }
        }
        
        if ($SafeAttachmentRules.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($SafeAttachmentRulesCount) Safe Attachments Rules."
            foreach ($rule in $SafeAttachmentRules)
            {
                $SafeAttachmentRuleCmdlet = "New-SafeAttachmentRule"
                $SafeAttachmentRuleCmdlet += makeparam "Priority" $rule.Priority
                $SafeAttachmentRuleCmdlet += makeparam "Name" $rule.Name
                $SafeAttachmentRuleCmdlet += makeparam "SentToMemberOf" $rule.SentToMemberOf
                $SafeAttachmentRuleCmdlet += makeparam "SentTo" $rule.SentTo
                $SafeAttachmentRuleCmdlet += makeparam "Comments" $rule.Comments
                $SafeAttachmentRuleCmdlet += makeparam "RecipientDomainIs" $rule.RecipientDomainIs
                $SafeAttachmentRuleCmdlet += makeparam "SafeAttachmentPolicy" $rule.SafeAttachmentPolicy
                $SafeAttachmentRuleCmdlet += makeparam "ExceptIfRecipientDomainIs" $rule.ExceptIfRecipientDomainIs
                $SafeAttachmentRuleCmdlet += makeparam "ExceptIfSentTo" $rule.ExceptIfSentTo
                $SafeAttachmentRuleCmdlet += makeparam "ExceptIfSentToMemberOf" $rule.ExceptIfSentToMemberOf
                $SafeAttachmentRuleCmdlet += makeparam "Enabled" $rule.Enabled
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Adding Safe Attachment Rule $($rule.Name)."
                Invoke-Expression $SafeAttachmentRuleCmdlet
            }
        }
        
        # ATP Safe Links
        Write-Log -ConsoleOutput -LogLevel Info -Message "Import ATP Safe Links Policies."
        [array]$SafeLinksPolicies = Import-Clixml .\SafeLinksPolicy.xml
        [array]$SafeLinksRules = Import-Clixml .\SafeLinksRule.xml
        [int]$SafeLinksPoliciesCount = $SafeLinksPolicies.Name.Count
        [int]$SafeLinksRulesCount = $SafeLinksRules.Name.Count
        
        If ($SafeLinksPolicies.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($SafeLinksPoliciesCount) Safe Links Policies."
            foreach ($Policy in $SafeLinksPolicies)
            {
                $SafeLinksPolicyCmdlet = "New-SafeLinksPolicy"
                $SafeLinksPolicyCmdlet += makeparam "EnableForInternalSenders" $Policy.EnableForInternalSenders
                $SafeLinksPolicyCmdlet += makeparam "Name" $Policy.Name
                $SafeLinksPolicyCmdlet += makeparam "AdminDisplayName" $Policy.AdminDisplayName
                $SafeLinksPolicyCmdlet += makeparam "DoNotTrackUserClicks" $Policy.DoNotTrackUserClicks
                $SafeLinksPolicyCmdlet += makeparam "ExcludedUrls" $Policy.ExcludedUrls                
                $SafeLinksPolicyCmdlet += makeparam "TrackClicks" $Policy.TrackClicks
                $SafeLinksPolicyCmdlet += makeparam "WhiteListedUrls" $Policy.WhiteListedUrls
                $SafeLinksPolicyCmdlet += makeparam "IsEnabled" $Policy.IsEnabled
                $SafeLinksPolicyCmdlet += makeparam "DoNotAllowClickThrough" $Policy.DoNotAllowClickThrough
                $SafeLinksPolicyCmdlet += makeparam "AllowClickThrough" $Policy.AllowClickThrough
                $SafeLinksPolicyCmdlet += makeparam "DoNotRewriteUrls" $Policy.DoNotRewriteUrls
                $SafeLinksPolicyCmdlet += makeparam "ScanUrls" $Policy.ScanUrls
                $SafeLinksPolicyCmdlet += makeparam "Enabled" $Policy.Enabled
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Adding Safe Links Policy $($Policy.name)."
                Invoke-Expression $SafeLinksPolicyCmdlet
            }
        }
        
        If ($SafeLinksRules.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Info -Message "Importing $($SafeLinksRulesCount) Safe Links Rules."
            foreach ($rule in $SafeLinksRules)
            {
                $SafeLinksRuleCmdlet = "New-SafeLinksRule"
                $SafeLinksRuleCmdlet += makeparam "Priority" $rule.Priority
                $SafeLinksRuleCmdlet += makeparam "Name" $rule.Name
                $SafeLinksRuleCmdlet += makeparam "SentToMemberOf" $rule.SentToMemberOf
                $SafeLinksRuleCmdlet += makeparam "SentTo" $rule.SentTo
                $SafeLinksRuleCmdlet += makeparam "Comments" $rule.Comments
                $SafeLinksRuleCmdlet += makeparam "RecipientDomainIs" $rule.RecipientDomainIs
                $SafeLinksRuleCmdlet += makeparam "ExceptIfRecipientDomainIs" $rule.ExceptIfRecipientDomainis
                $SafeLinksRuleCmdlet += makeparam "SafeLinksPolicy" $rule.SafeLinksPolicy
                $SafeLinksRuleCmdlet += makeparam "ExceptIfSentTo" $rule.ExceptIfSentTo
                $SafeLinksRuleCmdlet += makeparam "ExceptIfSentToMemberOf" $rule.ExceptIfSentToMemberOf
                $SafeLinksRuleCmdlet += makeparam "Enabled" $rule.Enabled
                
                # Executing cmdlet
                Write-Log -ConsoleOutput -LogLevel Info -Message "Adding Safe Links Rule $($rule.Name)."
                Invoke-Expression $SafeLinksRuleCmdlet
            }
        }
        
        # Check existing Transport Rules for Encryption Settings
        [XML]$CheckTransportRules = Get-Content .\TransportRules.xml
        [array]$RulesWithEncryption = $CheckTransportRules.rules.rule | ? { $_.InnerXML -like "*ApplyOME*"} | select -expand Name
        If ($RulesWithEncryption.Count -gt 0)
        {
            Write-Log -ConsoleOutput -LogLevel Warn -Message "The following rules require AADRM to be configured to work properly."
            Write-Log -ConsoleOutput -LogLevel Warn -Message $RulesWithEncryption
        }
        else
        {
        Write-Log -ConsoleOutput -LogLevel Success -Message "No transport rules with encryption identified."    
        }
        
        # Enable Azure Rights Management
        If ($AADRM)
        {
            Switch ($AADRM)
            {
                GCC
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.govus.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                
                NA
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.na.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                EU
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.eu.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                AP
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.ap.aadrm.com/TenantManagement/ServicePartner.svc"
                }
                SA
                {
                    $RMSOnlineKeySharingLocation = "https://sp-rms.sa.aadrm.com/TenantManagement/ServicePartner.svc"
                }
            }
            
            If (!(Get-Module -ListAvailable AADRM))
            {
                If ($InstallModules)
                {
                    Write-Log -ConsoleOutput -LogLevel Error -Message "AADRM Module not present. Attempting to download and install."
                    InstallSupportingModules
                    Install-Module AADRM -Force
                }
            }
            
            If (!(Get-Module -ListAvailable AADRM))
            {
                If ($RulesWithEncryption.Count -gt 0)
                {
                    Write-Log -ConsoleOutput -LogLevel Error -Message "The following transport rules may not import due to Encryption Settings."
                    Write-Log -ConsoleOutput -LogLevel Error -Message $RulesWithEncryption
                }
            }
            Else
            {
                Import-Module AADRM
                If (!($TargetTenantCredential))
                {
                    $TargetTenantCredential = Get-Credential -Message "Target Office 365 Credential"
                    Connect-AADRMService -Credential $TargetTenantCredential
                    Enable-AADRM
                    Set-IRMConfiguration -RMSOnlineKeySharingLocation $RMSOnlineKeySharingLocation
                    Import-RMSTrustedPublishingDomain -RMSOnline -name "RMS Online"
                    Set-IRMConfiguration -InternalLicensingEnabled $true
                }
            }
        }
        
        # TransportRules
        Write-Log -ConsoleOutput -LogLevel Info -Message "Processing Transport Rules."
        [Byte[]]$Data = Get-Content -Path ".\TransportRules.xml" -Encoding Byte -ReadCount 0
        Import-TransportRuleCollection -FileData $Data -Confirm:$false -Force
        Get-PSSession | Remove-PSSession
        Write-Log -ConsoleOutput -LogLevel Success -Message "Import completed task completed."
    }
    
    ConfirmDomains
    {
        If (!$UseExistingSession) { TargetTenantLogon }
        
        # Confirm MSOLDomains
        $Domains = Import-Clixml .\Domains.xml
        foreach ($domain in $domains)
        {
            If ((Get-MsolDomain -DomainName $domain.name).Status -eq "Unverified")
            {
                Write-Log -ConsoleOutput -LogLevel Info -Message "Checking $($domain.name)."
                $check = Resolve-DnsName -Type TXT -Name $domain.name
                If ($check.Strings -match $domain.value)
                {
                    Write-Log -ConsoleOutput -LogLevel Success -Message "DNS TXT Record for $($domain.name) found, attempting confirmation."
                    Confirm-MsolDomainin -DomainName $domain.name
                }
                Else
                {
                    Write-Log -ConsoleOutput -LogLevel Info -Message "DNS TXT record for $($domain.name) not found. Please retry later."
                }
            }
            Else
            {
                Write-Log -ConsoleOutput -LogLevel Info -Message "Domain $($domain.name) is already verified."
            }
        }
        Get-PSSession | Remove-PSSession
        Write-Log -ConsoleOutput -LogLevel Success -Message "Domain configuration task completed."
    }
}