# credit goes to:
# - Mike Pfeiffer for Add-EmailAddress
# - Paul Cunningham for his article and script on Office 365 email address policies (https://practical365.com/exchange-online/office-365-email-address-policies/)
# - Paul Cunningham for Add-SMTPAddresses.ps1 which I've based my script on
# - TessellatingHeckler for help with parsing templates
# Changelog
# ver 0.1 - 02.08.2016 -Initial script
# ver 0.2 - 03.08.2016 - Fix for $null-valued expression in Connect-Ex/Disconnect-Ex
Function Connect-EX ([string] $login, [string] $password, [string] $URL = "https://ps.outlook.com/powershell", [string] $sessionName = "Exchange Online", $Authentication = "Basic", $SupressWarnings = $true) {
if ($sessionName -eq $null -or $sessionName.Trim() -eq "") { $sessionName = "Exchange Online" }
Write-Color -Text "[*] Connecting to $sessionName PowerShell" -Color Yellow
# Kerberos for On-Premise Exchange on Active Directory joined machines, Basic for Office365 or non-domain joined computer
$WarningPreference = $SupressWarnings
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)
$sessionOption = New-PSSessionOption -SkipRevocationCheck -SkipCACheck -SkipCNCheck
if ($SupressWarnings) { $suppress = "SilentlyContinue" } else { $suppress = "Continue" }
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $URL -Credential $Credentials -Authentication $Authentication -AllowRedirection -Name $sessionName -SessionOption $sessionOption -WarningAction $suppress
$output = Import-PSSession $session -AllowClobber -DisableNameChecking
if (-not $SupressWarnings) { $output }
}
Function Disconnect-EX ($sessionName = "Exchange Online") {
if ($sessionName -eq $null -or $sessionName.Trim() -eq "") { $sessionName = "Exchange Online" }
Remove-PSSession -Name $sessionName
Write-Color -Text "[*] Disconnected from $sessionName" -Color Yellow
}
Function Remove-StringLatinCharacters {
PARAM ([string]$String)
[Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String))
}
Function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = "White", [int]$StartTab = 0, [int] $LinesBefore = 0,[int] $LinesAfter = 0) {
$DefaultColor = $Color[0]
if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host "`n" -NoNewline } } # Add empty line before
if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host "`t" -NoNewLine } } # Add TABS before text
if ($Color.Count -ge $Text.Count) {
for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
} else {
for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -NoNewLine }
}
Write-Host
if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host "`n" } } # Add empty line after
}
Function Get-NameSection {
# Returns the first $num characters of a name
# unless $num is 0, missing or longer than the name
# then returns the entire name
param([string]$name, [int]$num)
if (-not $num -or $num -gt $name.Length) {
$name
} else {
$name.Substring(0, $num)
}
}
Function Add-EmailAddress {
param($Identity, $EmailAddress)
begin {
$mb = Get-Mailbox $Identity
if($mb.EmailAddressPolicyEnabled) {
Set-Mailbox $Identity -EmailAddressPolicyEnabled $false
$policy += 1
}
$addresses = $mb.EmailAddresses += $EmailAddress
}
process {
Set-Mailbox $Identity -EmailAddresses $addresses
}
end {
if($policy) {Set-Mailbox $Identity -EmailAddressPolicyEnabled $true}
}
}
Function ProcessEmail ($Mailbox, $FullEmail) {
$RequireAdd = $true
$addresses = $Mailbox.EmailAddresses
foreach ($address in $addresses) {
if ($address -imatch "sip:") { continue }
if ($address -ireplace("smtp:","") -ieq $FullEmail) {
#$FullEmail
$requireAdd = $false
break
}
}
$Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailToAdd -Value $FullEmail
$Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailRequiresAdding -Value $RequireAdd
return ,$mailbox
}
Function Add-EmailAddressToUsersFromTemplate([string] $EmailTemplate, [bool] $ShowSummaryTable = $true, [bool] $ShowSummaryLines = $true, [bool] $Commit = $false, [string[]] $ExcludeUsers) {
$collection = @()
Get-User -ResultSize Unlimited | Where { $_.RecipientType -eq 'UserMailbox' } | ForEach { $Users = @{} } { $Users[$_.SamAccountName] = $_ }
$AllMailboxes = Get-Mailbox -ResultSize Unlimited | Where { $_.RecipientTypeDetails -eq "UserMailbox" } | ForEach {
$PrimarySmtpDomain = $_.PrimarySmtpAddress.split("@")
$firstNameNonLatin = Remove-StringLatinCharacters -String $Users[$_.SamAccountName].FirstName
$lastnameNonLatin = Remove-StringLatinCharacters -String $Users[$_.SamAccountName].LastName
New-Object psobject |
Add-Member -PassThru NoteProperty Alias $_.Alias |
Add-Member -PassThru NoteProperty Name $_.Name |
Add-Member -PassThru NoteProperty DisplayName $_.DisplayName |
Add-Member -PassThru NoteProperty FirstName $Users[$_.SamAccountName].FirstName |
Add-Member -PassThru NoteProperty LastName $Users[$_.SamAccountName].LastName |
Add-Member -PassThru NoteProperty FirstNameNonLatin $firstNameNonLatin |
Add-Member -PassThru NoteProperty LastNameNonLatin $lastnameNonLatin |
Add-Member -PassThru NoteProperty EmailAddressPolicyEnabled $_.EmailAddressPolicyEnabled |
Add-Member -PassThru NoteProperty PrimarySmtpAddress $_.PrimarySmtpAddress |
Add-Member -PassThru NoteProperty PrimarySmtpDomain $PrimarySmtpDomain[1] |
Add-Member -PassThru NoteProperty EmailAddresses $_.EmailAddresses |
Add-Member -PassThru NoteProperty RecipientType $_.RecipientType |
Add-Member -PassThru NoteProperty RecipientTypeDetails $_.RecipientTypeDetails |
Add-Member -PassThru NoteProperty IsResource $_.IsResource |
Add-Member -PassThru NoteProperty IsShared $_.IsShared |
Add-Member -PassThru NoteProperty IsLinked $_.IsLinked |
Add-Member -PassThru NoteProperty ExchangeUserAccountControl $_.ExchangeUserAccountControl |
Add-Member -PassThru NoteProperty AddressBookPolicy $_.AddressBookPolicy |
Add-Member -PassThru NoteProperty Identity $_.Identity |
Add-Member -PassThru NoteProperty DistinguishedName $_.DistinguishedName |
Add-Member -PassThru NoteProperty OrganizationalUnit $_.OrganizationalUnit |
Add-Member -PassThru NoteProperty AddressListMembership $_.AddressListMembership |
Add-Member -PassThru NoteProperty RulesQuota $_.RulesQuota |
Add-Member -PassThru NoteProperty UserPrincipalName $_.UserPrincipalName |
Add-Member -PassThru NoteProperty SamAccountName $_.SamAccountName |
Add-Member -PassThru NoteProperty UseDatabaseQuotaDefaults $_.UseDatabaseQuotaDefaults
}
foreach ($Mailbox in $AllMailboxes) {
$skip = $false;
foreach ($Excluded in $ExcludeUsers) {
if ($($Mailbox.UserPrincipalName) -eq $Excluded) {
$skip = $true;
}
}
if ($skip) { continue }
$FirstName = $Mailbox.FirstnameNonLatin
$LastName = $Mailbox.LastNameNonLatin
$Alias = $Mailbox.Alias
$DisplayName = $Mailbox.DisplayName
$FullEmail = $EmailTemplate
$FullEmail = [regex]::Replace($FullEmail, '%(\d*)g', {param($m) Get-NameSection $FirstName $m.Groups[1].Value })
$FullEmail = [regex]::Replace($FullEmail, '%(\d*)s', {param($m) Get-NameSection $LastName $m.Groups[1].Value })
$Mailbox = ProcessEmail ($Mailbox) ($FullEmail)
$collection += $Mailbox
}
if ($ShowSummaryTable) {
$collection | ft UserPrincipalName, DisplayName, NewEmailToAdd, NewEmailRequiresAdding
}
if ($ShowSummaryLines) {
foreach ($mail in $collection) {
if ($($mail.NewEmailRequiresAdding) -eq $true) {
Write-Color "Following e-mail will be added ", "$($mail.NewEmailToAdd)", " to user (UPN): ", "$($mail.UserPrincipalName)" -Color White,Green,White,Green
} else {
Write-Color "Following e-mail will be skipped ", "$($mail.NewEmailToAdd)", " to user (UPN): ", "$($mail.UserPrincipalName)" -Color White,Yellow,White,Yellow
}
}
}
if ($Commit) {
Write-Color -LinesBefore 1
foreach ($mail in $collection) {
if ($($mail.NewEmailRequiresAdding) -eq $true) {
Write-Color "Adding e-mail ", "$($mail.NewEmailToAdd)", " to user (UPN): ", "$($mail.UserPrincipalName)" -Color White,Green,White,Green
Add-EmailAddress -Identity $($mail.UserPrincipalName) -EmailAddress $($mail.NewEmailToAdd)
}
}
} else {
Write-Color -Text "Changes not committed, re-run the script with the -Commit switch when you're ready to apply the changes." -LinesBefore 1
Write-Color -Text "No changes made due to -Commit switch not being specified." -Color Magenta
}
}