instagram arrow-down
Kalle Lilja

Archives

Create a CatchAll Subdomain – Office365

Using Powershell

By setting up a “catch-all” domain you enable the functionality of receiving ANY email sent to a specific domain, this in turn lets you catch for example any potential lost emails due to misspelling. However, this is in almost all cases a bad idea since based on the fact that if a spamming campaign got a hold of this catch-all domain the server could be victim to a DDoS if no spam protection is in place.
Proceed with caution, keep an eye on the logs.

Anyhow, with the warnings out of the way, lets get started.
The use-case i was faced with was a client who registered lots and lots of external services with unique email addresses that needed to be kept active for verification, password resets, and so on.
The client promptly didn’t want to manage the alias setup internally and liked a solution that didn’t involve daily ticket submissions.
My end goal in this was to end up with a catch-all domain news.contoso.com who in turn forwards all incoming email to a set of users via Distribution Group newsteam@contoso.com for review.

The logic used will be to set the subdomain up as an InternalRelay, this in turn allows the Exchange server to accept all messages without first verifying the recipient, an essential part of the catch-all process.
The forwarding step will be handled with a Transport Rule, the caveat however is that a transport rule can’t redirect messages to a group natively, we’ll create a Shared mailbox as a middle man, this could of course be a fully featured user mailbox as well if needed.

Setup

Subdomain

First and foremost you’ll need to configure and verify the subdomain news.contoso.com for use with Office 365 and Exchange Online. This is essentially a repeat of the initial domain setup.

Exchange Online

I’m almost positive every setting needed is exposed to the GUI, so this should be followable that way but I’ll perform the configuration via Powershell.
Start off by connecting to Exchange Online via Powershell.

# Connect to Office 365
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session

Adjust the subdomain to act as InternalRelay.

Get-AcceptedDomain "news.contoso.com" | Set-AcceptedDomain -DomainType InternalRelay

Create the Distribution Group followed by the Shared Mailbox.
Remember to add users to the group as needed.

# Create Distribution Group newsteam@contoso.com, enable external emails and hide from GAL
New-DistributionGroup -Name "newsteam@contoso.com" -PrimarySmtpAddress "newsteam@contoso.com" -RequireSenderAuthenticationEnabled $false -MemberJoinRestriction closed | Set-DistributionGroup -HiddenFromAddressListsEnabled $True

# Create Shared Mailbox news@news.contoso.com and set forward to newsteam@contoso.com
New-Mailbox -Shared -Name "news@news.contoso.com" -DisplayName "news@news.contoso.com" -PrimarySmtpAddress "news@news.contoso.com" | Set-Mailbox -ForwardingAddress "newsteam@contoso.com"
# New-Mailbox -Name $sharedMbx -DisplayName $sharedMbx -PrimarySmtpAddress $sharedMbx | Set-Mailbox -ForwardingAddress $distGrp -DeliverToMailboxAndForward $True

Lastly, tie it all together with a Transport Rule to handle the forwarding.

# Create CatchAll TransportRule
New-TransportRule -Name "news.contoso.com Catch-All Transport Rule" -SenderAddressLocation HeaderOrEnvelope -RecipientDomainIs "news.contoso.com" -RedirectMessageTo "news@news.contoso.com" -Comments "Forward all messages for *@news.contoso.com to news@news.contoso.com who forwards to newsteam@contoso.com."

I’ve created and distributed a more complete installation procedure/command reference over on GitHub as well as below.

<#
    .SYNOPSIS
    Create a catch-all subdomain and forward incomming mail to a Distribution Group in primary domain.
    .DESCRIPTION
    Set up a subdomain to act as catch-all in o365 and forward email to a distribution group.
    Should be used with care as there is no recipient filtering enabled this way, but it removes the need to create separate aliases to recieve emails.
    Workes by setting the subdomain as InteralRelay followed coupled with a Transport rule to forward all incomming email to a Shared mailbox who inturn forwards to a Distribution group.
     (Transport rules can't as of writing forward directly to a group)
    .INPUTS
    Needs o365 Administrative cretentials via $UserCredential
    .OUTPUTS
    Shared Mailbox: $sharedMbx
    Distribution Group: $distGrp
    Transport Rule: "$subDomain Catch-All Transport Rule"
    .EXAMPLE
    .\O365-CatchAllDomain.ps1
    .NOTES
    Assumes subdomain registration and validation already complete.
    # https://support.office.com/en-us/article/Domains-FAQ-1272bad0-4bd4-4796-8005-67d6fb3afc5a#bkmk_caniaddcustomsubdomainsormultipledomainstooffice365
    .NOTES
    Remember to swap the # Variables to match your settings.
#>

# Connect to Office 365
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session

# Variables
$subDomain = "news.contoso.com"
$sharedMbx = "news@$subDomain"
$distGrp = "newsteam@contoso.com"

# Set Subdomain to InternalRelay (Accept all incomming messages)
Get-AcceptedDomain $subDomain | Set-AcceptedDomain -DomainType InternalRelay

# Create Distribution Group $distGrp, enable external emails and hide from GAL
New-DistributionGroup -Name $distGrp -PrimarySmtpAddress $distGrp -RequireSenderAuthenticationEnabled $false -MemberJoinRestriction closed | Set-DistributionGroup -HiddenFromAddressListsEnabled $True

# Create Shared Mailbox $sharedMbx and set forward to $distGrp
New-Mailbox -Shared -Name $sharedMbx -DisplayName $sharedMbx -PrimarySmtpAddress $sharedMbx | Set-Mailbox -ForwardingAddress $distGrp

# Create CatchAll TransportRule
New-TransportRule -Name "$subDomain Catch-All Transport Rule" -SenderAddressLocation HeaderOrEnvelope -RecipientDomainIs $subDomain -RedirectMessageTo $sharedMbx -Comments "Forward all messages for *@$subDomain to $sharedMbx who forwards to $distGrp."