UpdateEAPsSelectively.ps1

<#PSScriptInfo
 
.VERSION 2.0
 
.GUID 2597e815-2d87-47ec-9b08-765a2042c6cc
 
.DESCRIPTION Update Email Address Teamplate tool.
 
.AUTHOR Aaron Guilmette
 
.COMPANYNAME Microsoft
 
.COPYRIGHT 2022
 
.TAGS Email Address Policy Template
 
.LICENSEURI
 
.PROJECTURI https://www.undocumented-features.com/2015/10/15/add-an-email-address-template-to-all-email-address-policies/
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
#>


<#
THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR RESULTS FROM THE USE OF
THIS CODE REMAINS WITH THE USER.
 
Author: Aaron Guilmette
        aaron.guilmette@microsoft.com
 
 
#>


<#
.SYNOPSIS
Add an email address template to all policies, either in bulk or selectively.
It's useful for when you have multiple polcies (dozens or hundreds) that need
the same proxy address template applied. This can also use a domain list as
input for pre-staging Email Address Policies for the Office 365 Hybrid
Configuration Wizard.
 
.PARAMETER DomainList
Use this option to specify templates which only contain the domains
listed in this file. Generate the list by running Get-AcceptedDomain
| Select DomainName | Export-Csv -NoTypeInformation Domains.csv.
 
.PARAMETER DomainType
When used with -NewAcceptedDomain, this will specify the type of the
new domain. Acceptable values are Authoritative or InternalRelay. If
DomainType is not specified or domain suffix is onmicrosoft.com,
domain will be configured as InternalRelay.
 
.PARAMETER EmailAddressTemplateDomain
This parameter is used to specify the domain you want to add as an
email address template domain. If the domain is not currently an
accepted domain, you can use the -NewAcceptedDomain parameter or add
the domain separately and re-run the script.
 
.PARAMETER NewAcceptedDomain
This parameter is used to specify the new accepted domain for which
to add an email address template. For example, if you are using
this script to pre-stage email address policies for an Office 365
tenant named contoso, you could specify -NewAcceptedDomain
contoso.mail.onmicrosoft.com.
 
.PARAMETER NewFormat
This parameter is used to define the left-hand side of the email
address template. %m (alias) is the default. You can specify any
accepted format. For example, if the user is John Smith, specifying
%g1%s will result in the alias(left hand side) address being generated
as jsmith.
 
.EXAMPLE
UpdateEAPsSelectively.ps1 -DomainList Domains.csv -EmailAddressTemplateDomain contoso.mail.onmicrosoft.com
 
Add a new email address template for contoso.mail.onmicrosoft.com to
all of the domains listed in Domains.csv.
 
.EXAMPLE
UpdateEAPsSelectively.ps1 -EmailAddressTemplateDomain contoso.mail.onmicrosoft.com -NewFormat %g1%s
 
Add a new email address template for contoso.mail.onmicrosoft.com with
the prefix %g1%s (1st letter of given name, full surname)
 
.LINK
https://undocumented-features.com/archive/2015/10/15/add-an-email-address-template-to-all-email-address-policies.aspx
#>


# Parameters
[CmdletBinding()]
Param(
    [Parameter(Mandatory=$false,HelpMessage='List of Domains to Update')]
        [ValidateScript({Test-Path $_;if (!((gc $_ | Select-Object -First 1) -like "*Domainname*")) 
            { Write-Host -Fore Red "Please make sure input CSV only contains header DomainName.";Break }})]
        [string]$DomainList = "Domains.csv",
        
    [Parameter(Mandatory=$false,HelpMessage='New Email Address Template Domain')]
        [string]$EmailAddressTemplateDomain,

    [Parameter(Mandatory=$false,HelpMessage='New Email Address Template Format, such as %m')]
        [String]$NewFormat,
            
    [Parameter(ParameterSetName='NewAcceptedDomainSet',Mandatory=$false,HelpMessage='New Accepted Domain parameter. If this is for Office 365 Hybrid Configuration Wizard EAP Pre-Staging, use the tenant target address, such as contoso.mail.onmicrosoft.com.')]
        [string]$NewAcceptedDomain,
        
        [Parameter(ParameterSetName='NewAcceptedDomainSet',Mandatory=$false,HelpMessage='InternalRelay or Authoritative. For Office 365 Hybrid Configuration Wizard EAP Pre-Staging, enter InternalRelay.')]
        [ValidateSet("InternalRelay","Authoritative")]
        [string]$DomainType = "InternalRelay"
    )

# Check to see if NewDomain is present, and if present, create new Accepted Domain
# If $NewAcceptedDomain ends in "onmicrosoft.com", set type to InternalRelay regardless of previous configuration
If ($NewAcceptedDomain) {
    If ($NewAcceptedDomain -like "*onmicrosoft.com")
        {
        $DomainType = "InternalRelay"
        New-AcceptedDomain -DomainName $NewAcceptedDomain -DomainType $DomainType -Name $NewAcceptedDomain
        }
    Else
        {
        New-AcceptedDomain -DomainName $NewAcceptedDomain -DomainType $DomainType -Name $NewAcceptedDomain
        }
    }

# Check to see if NewDomain is present, if not, prompt
If (!($EmailAddressTemplateDomain)) {
    $EmailAddressTemplateDomain = Read-Host "Domain for email address template. If this is for Office 365 Hybrid Configuration Wizard EAP Pre-Staging, use the tenant target address, such as contoso.mail.onmicrosoft.com."
    If (!(Get-AcceptedDomain $EmailAddressTemplateDomain -EA SilentlyContinue))
        {
        Write-Host -ForegroundColor Red "Domain $EmailAddressTemplateDomain is not an accepted domain."
        Write-Host -ForegroundColor Red "Please configure $EmailAddressTemplateDomain as an accepted domain"
        Write-Host -ForegroundColor Red "before running this script or use the -NewAcceptedDomain."
        Write-Host -ForegroundColor Red "parameter."
        Write-Host -ForegroundColor Red `n
        Write-Host -ForegroundColor Red "Exiting."
        Break
        }
    }
$defaultFormat = "%m"
If (!($newFormat))
    {
    $newFormat = Read-Host "New email address template format [$($defaultFormat)]"
    }
$newFormat = ($defaultFormat,$newFormat)[[bool]$newFormat]
$newTemplate = "smtp:$newFormat@$EmailAddressTemplateDomain"

# Retreive the current EAPs
$policies = Get-EmailAddressPolicy

# If $DomainList was Specified, process only EAPs matching those domains
If ($DomainList)
    {
    $DomainsToProcess = Import-Csv $DomainList
    Write-Host -ForegroundColor Green "Checking $($policies.Count) policies for $($DomainsToProcess.Count) domains."
    Foreach ($Domain in $DomainsToProcess)
        {
            Foreach ($policy in $policies)
            {
            #Write-Host -Fore cyan "Checking Domain $($domain.domainname) in $($policy.Name)"
            $polcheck = $policy.EnabledEmailAddressTemplates[0].AddressTemplateString
            If ($polcheck -match $domain.DomainName)
                {
                Write-Host -fore green "Found $($domain.domainName) in $($policy.name)"
                Write-Host -ForegroundColor green "Updating policy $($policy.name)."
                    $templates = $policy.EnabledEmailAddressTemplates
                    if (!($policy.EnabledEmailAddressTemplates -contains "$newTemplate"))
                        {
                        $templates += "$newTemplate"
                        Set-EmailAddressPolicy -Identity $policy.Name -EnabledEmailAddressTemplates $templates 
                        }
                    Else
                        {
                        Write-Host -ForegroundColor Cyan " Template $newTemplate already present."
                        }
                }
            Else
                {
                }
            }
        }
    }
Else
    {
    $policiesTitle = "Email Address Policy Selection"
    $policiesMessage = "Do you want to process all $($policies.Count) policies?"
    $policiesYes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Add email address template to all policies."
    $policiesNo = New-Object System.Management.Automation.Host.ChoiceDescription "&No","Let me choose which policies to update."
    $policiesOptions = [System.Management.Automation.Host.ChoiceDescription[]]($policiesYes,$policiesNo)
    $policiesResult = $host.UI.PromptForChoice($policiesTitle,$policiesMessage,$policiesOptions,0)

    # Policy processing
    Switch ($policiesResult)
        {
        0    { # Do all
                Foreach ($policy in $policies)
                {
                    Write-Host -ForegroundColor green "Updating policy $policy"
                    $templates = $policy.EnabledEmailAddressTemplates
                    if (!($policy.EnabledEmailAddressTemplates -contains "$newTemplate"))
                        {
                        $templates += "$newTemplate"
                        Set-EmailAddressPolicy -Identity $policy.Name -EnabledEmailAddressTemplates $templates 
                        }
                    Else
                        {
                        Write-Host -ForegroundColor Cyan " Template $newTemplate already present."
                        }
                }
            }
        1    { # Do Selective
            Foreach ($policy in $policies) {
                $policySelectiveTitle = "Select policies to process."
                $policySelectiveMessage = "Do you want to add the template to ($policy)?"
                $policySelectiveYes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Add email address template to this policy."
                $policySelectiveNo = New-Object System.Management.Automation.Host.ChoiceDescription "&No","No, skip this policy."
                $policySelectiveOptions = [System.Management.Automation.Host.ChoiceDescription[]]($policySelectiveYes,$policySelectiveNo)
                $policySelectiveResult = $host.UI.PromptForChoice($policySelectiveTitle,$policySelectiveMessage,$policySelectiveOptions,0)
                Switch ($policySelectiveResult)
                    {
                    0    {
                        Write-Host -ForegroundColor green "Updating policy $policy"
                        $templates = $policy.EnabledEmailAddressTemplates
                        If (!($policy.EnabledEmailAddressTemplates -contains "$newTemplate"))
                            {
                            $templates += "$newTemplate"
                            Set-EmailAddressPolicy -Identity $policy.Name -EnabledEmailAddressTemplates $templates 
                            }
                        Else
                        {
                        Write-Host -ForegroundColor Cyan " Template $newTemplate already present."
                        }
                        }
                    1     { 
                        Write-Host -ForegroundColor Cyan "Skipping policy $policy." 
                        }
                    }
                }
            }
        }
    }