Office365MailAliases.psm1
<#
.SYNOPSIS This module contains functions to create mail aliases in Office 365 .DESCRIPTION These mail aliases are created per domain name or organization. This is to make sure that organizations get unique email addresses. You need at least "User administrator" permissions and the appropriate Exchange permissions to run the "New-MailAlias" command. .INPUTS None .OUTPUTS None .NOTES Author: Jean-Paul van Ravensberg, Cloudenius.com .EXAMPLE Select-MailAlias -DomainName Google.com -ExportAliasesToMailDraft -Verbose Create a mail alias for Google.com and provide Verbose output. After selecting the mail alias, create a draft mail in the mailbox of the user that contains all the used mail aliases. .EXAMPLE New-MailAlias -NumberOfAliases 9 -Verbose Warm up aliases for later use and provide Verbose output. #> Function New-MailAlias { param( [parameter(Mandatory = $true, HelpMessage = "Specify the amount of aliases required")] [ValidateNotNullOrEmpty()] [int]$NumberOfAliases, [parameter(Mandatory = $true, HelpMessage = "Specify the domain name that is used for the email address. E.g. johndoe.com")] [ValidateNotNullOrEmpty()] [string]$EmailDomain, [parameter(Mandatory = $true, HelpMessage = "Specify the owner of the alias. E.g. john@johndoe.com")] [ValidateNotNullOrEmpty()] [string]$Owner, [parameter(Mandatory = $true, HelpMessage = "Specify the prefix that will be used to create the alias. E.g. JD")] [ValidateNotNullOrEmpty()] [string]$GroupNamePrefix ) ## Login to Office 365 If (!(Get-PSSession | Where-Object {$_.ComputerName -eq "outlook.office365.com" -and $_.State -eq "Opened"})) { Connect-EXOPSSession } Write-Verbose "Creating $NumberOfAliases aliases" Foreach ($i in 1..$NumberOfAliases) { $Random = Get-Random -Minimum 10000 -Maximum 99999 $GroupName = $GroupNamePrefix + $Random $GroupEmail = ($GroupName + "@" + $EmailDomain) Write-Verbose "Creating alias $i with name $GroupName" If (Get-DistributionGroup | Where-Object {$_.Name -like "*$GroupName*"}) { Write-Verbose "Distribution Group name is not unique. Will skip name $GroupName" } Else { # Create the new Distribution Group Try { New-DistributionGroup -Name $GroupName -Type "Security" -ManagedBy $Owner -PrimarySmtpAddress $GroupEmail } Catch [Exception] { Write-Error "Distribution Group already exists or another error occurred" Break } # Allow external senders to mail to the address & set _CLAIMABLE suffix Set-DistributionGroup -Identity $GroupName -RequireSenderAuthenticationEnabled:$false -DisplayName $($GroupName + "_CLAIMABLE") # Modify the new Distribution Group with SendOnBehalf permissions Add-RecipientPermission -Identity $GroupName -AccessRights SendAs -Trustee $Owner -Confirm:$false # Add the owner to the Distribution Group Add-DistributionGroupMember -Identity $GroupName -Member $Owner Write-Verbose "Created group called $GroupName with owner $Owner" } } } Function Select-MailAlias { param( [parameter(Mandatory = $true, HelpMessage = "Specify the domain name of the website")] [ValidateNotNullOrEmpty()] [string]$DomainName, [parameter(Mandatory = $false, HelpMessage = "Create a draft mail in the mailbox of the user that contains all the used mail aliases")] [switch]$ExportAliasesToMailDraft ) ## Login to Office 365 If (!(Get-PSSession | Where-Object {$_.ComputerName -eq "outlook.office365.com" -and $_.State -eq "Opened"})) { Connect-EXOPSSession } Write-Verbose "Claiming an alias for $DomainName" # Check if domain name already exists in Distribution Group $ExistingDistributionGroup = Get-DistributionGroup | Where-Object {$_.DisplayName -like "$DomainName - *"} If ($ExistingDistributionGroup) { Write-Output "Alias for domain name '$($DomainName)' already exists. Returning the alias already in use" $DistributionGroup = $ExistingDistributionGroup $EmailDomain = $DistributionGroup.PrimarySmtpAddress.Split('@')[1] $DisplayName = $DomainName + " - " + $EmailDomain } Else { # Search for unused alias and return the oldest one $ClaimableDistributionGroups = Get-DistributionGroup | Where-Object {$_.DisplayName -Like "*_CLAIMABLE"} | Sort-Object WhenCreatedUtc If (!($ClaimableDistributionGroups)) { Write-Error "No claimable Mail Aliases found. Please run New-MailAlias first." Break } While (!($ClaimableDistributionGroups = Get-DistributionGroup | Where-Object {$_.DisplayName -Like "*_CLAIMABLE"})) { Write-Output "Waiting for a new claimable Distribution Group. Pause 5 seconds..." Start-Sleep -Seconds 5 } Write-Verbose "Found $($ClaimableDistributionGroups.GetType().Count) claimable Distribution Group(s)" # Rename unused alias & change description $DistributionGroup = $ClaimableDistributionGroups[0] Write-Verbose "Picking $DistributionGroup for the rename" If ($DistributionGroup.WhenCreated.AddHours(1) -gt (Get-Date)) { Write-Warning "Be aware that this alias is <60 minutes old and might not be active yet" } # Change the Display Name for the Distribution Group $EmailDomain = $DistributionGroup.PrimarySmtpAddress.Split('@')[1] $DisplayName = $DomainName + " - " + $EmailDomain Set-DistributionGroup -Identity $DistributionGroup.Name -DisplayName $DisplayName } # Create the draft mail in the mailbox of the user that contains all the used mail aliases If ($ExportAliasesToMailDraft) { $MailMessage = New-MailMessage -Body (Get-UsedMailAlias | Select-Object Name, DisplayName | Sort-Object DisplayName | Out-String) -Subject "Used Mailbox Aliases" if ($MailMessage) { Write-Output "Successfully created draft mail message with subject '$($MailMessage.Subject)' and object state '$($MailMessage.ObjectState)'" } Else { Write-Warning "Something went wrong with creating the draft mail message" } } # Return the new name of the alias return New-Object PSObject -Property ([ordered]@{"Name" = $DistributionGroup.Name; "DisplayName" = $DisplayName; "E-mail" = $DistributionGroup.PrimarySmtpAddress}) } Function Get-UsedMailAlias { param( [parameter(Mandatory = $false, HelpMessage = "Name prefix that is used to identify the Mail Aliases")] [ValidateNotNullOrEmpty()] [string]$GroupNamePrefix, [parameter(Mandatory = $false, HelpMessage = "Create a draft mail in the mailbox of the user that contains all the used mail aliases")] [switch]$ExportAliasesToMailDraft ) ## Login to Office 365 If (!(Get-PSSession | Where-Object {$_.ComputerName -eq "outlook.office365.com" -and $_.State -eq "Opened"})) { Connect-EXOPSSession } # Check if domain name already exists in Distribution Group $ExistingDistributionGroup = Get-DistributionGroup | Where-Object ` {$_.Name -like "$GroupNamePrefix*" -and $_.DisplayName -notlike "*_CLAIMABLE"} # Create the draft mail in the mailbox of the user that contains all the used mail aliases If ($ExistingDistributionGroup -and $ExportAliasesToMailDraft) { $MailMessage = New-MailMessage -Body ($ExistingDistributionGroup | Select-Object Name, DisplayName | Sort-Object DisplayName | Out-String) -Subject "Used Mailbox Aliases" if ($MailMessage) { Write-Output "Successfully created draft mail message with subject '$($MailMessage.Subject)' and object state '$($MailMessage.ObjectState)'" } Else { Write-Warning "Something went wrong with creating the draft mail message" } } # Return the new name of the alias(es) If ($ExistingDistributionGroup) { return $ExistingDistributionGroup | Select-Object Name, DisplayName, PrimarySmtpAddress | Sort-Object DisplayName } Else { return } } Function Get-UnusedMailAlias { param( [parameter(Mandatory = $false, HelpMessage = "Name prefix that is used to identify the Mail Aliases")] [ValidateNotNullOrEmpty()] [string]$GroupNamePrefix ) ## Login to Office 365 If (!(Get-PSSession | Where-Object {$_.ComputerName -eq "outlook.office365.com" -and $_.State -eq "Opened"})) { Connect-EXOPSSession } # Check if domain name already exists in Distribution Group $ExistingDistributionGroup = Get-DistributionGroup | Where-Object ` {$_.Name -like "$GroupNamePrefix*" -and $_.DisplayName -like "*_CLAIMABLE"} # Return the names of the unused alias(es) If ($ExistingDistributionGroup) { return $ExistingDistributionGroup | Select-Object Name, DisplayName, PrimarySmtpAddress } Else { return } } Function Set-MailAliasToArchived { param( [parameter(Mandatory = $true, HelpMessage = "Specify the domain name of the website")] [ValidateNotNullOrEmpty()] [string]$DomainName ) ## Login to Office 365 If (!(Get-PSSession | Where-Object {$_.ComputerName -eq "outlook.office365.com" -and $_.State -eq "Opened"})) { Connect-EXOPSSession } # Check if domain name already exists in Distribution Group $ExistingDistributionGroup = Get-DistributionGroup | Where-Object ` {$_.DisplayName -like "$DomainName - *"} # Add "(Archived)" prefix to display name If ($ExistingDistributionGroup.DisplayName -like "(Archived)*") { Write-Output "Domain name is already archived, see:" } else { Write-Output "Changing displayName from '$($ExistingDistributionGroup.DisplayName)' to '(Archived) $($ExistingDistributionGroup.DisplayName)'" Set-DistributionGroup -Identity $ExistingDistributionGroup.Identity -DisplayName "(Archived) $($ExistingDistributionGroup.DisplayName)" # Return the new name of the alias Write-Output "Done, new result:" } return Get-DistributionGroup -Identity $ExistingDistributionGroup.Identity | Select-Object Name, DisplayName, PrimarySmtpAddress } |