|
| 1 | +# Copyright (c) Microsoft Corporation. |
| 2 | +# Licensed under the MIT License. |
| 3 | + |
| 4 | +# .SYNOPSIS |
| 5 | +# SetMailPublicFolderExternalAddress.ps1 |
| 6 | +# Stamps ExternalEmailAddress property of the mail-enabled public folders with their respective EXO smtp address. |
| 7 | +# |
| 8 | +# .PARAMETER ExecutionSummaryFile |
| 9 | +# The file path where operation summary will be logged. |
| 10 | +# |
| 11 | +# .PARAMETER Confirm |
| 12 | +# The Confirm switch causes the script to pause processing and requires you to acknowledge what the script will do before processing continues. You don't have to specify |
| 13 | +# a value with the Confirm switch. |
| 14 | +# |
| 15 | +# .EXAMPLE |
| 16 | +# .\SetMailPublicFolderExternalAddress.ps1 -ExecutionSummaryFile:summary.csv |
| 17 | + |
| 18 | +param( |
| 19 | + [Parameter(Mandatory=$true)] |
| 20 | + [ValidateNotNullOrEmpty()] |
| 21 | + [string] $ExecutionSummaryFile, |
| 22 | + |
| 23 | + [Parameter(Mandatory=$false)] |
| 24 | + [bool] $Confirm = $true |
| 25 | +) |
| 26 | + |
| 27 | +# cSpell:words mepf, mepfs |
| 28 | + |
| 29 | +$LocalizedStrings = ConvertFrom-StringData @' |
| 30 | +FindingPublicFoldersAcceptedDomain = Locating the well-known accepted domain for public folder email routing... |
| 31 | +FoundPublicFolderAcceptedDomain = Found '{0}' |
| 32 | +EnumeratingMailEnabledPublicFolders = Enumerating mail-enabled public folders... |
| 33 | +EnumeratingMailEnabledPublicFoldersComplete = Enumerating mail-enabled public folders completed... {0} folder(s) found |
| 34 | +StampingMailEnabledPublicFolders = Stamping ExternalEmailAddress on the mail-enabled public folder(s)... |
| 35 | +StampedMailEnabledPublicFolders = Stamped Folder(s) : {0} |
| 36 | +AlreadyStampedMailEnabledPublicFolders = Following mail-enabled public folder(s) are skipped as their ExternalEmailAddress property is stamped with a different email address. Please update these manually, if required: \n{0} |
| 37 | +MissingExoDomain = Cannot find an accepted domain with the well-known name 'PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99'. This is created as part of public folders migration and should be present for mail routing to Exchange Online to work correctly |
| 38 | +NoMailEnabledPublicFolders = No mail-enabled public folders found |
| 39 | +ProgressBarActivity = Stamping external email address on the mail-enabled public folders... |
| 40 | +ConfirmationTitle = Stamp ExternalEmailAddress on the mail-enabled public folders |
| 41 | +ConfirmationQuestion = Total mail-enabled public folder(s): {0}\nSkipping {1} mail-enabled public folder(s) which are already stamped with their exchange online addresses.\nSkipping {2} mail-enabled public folder(s) which are stamped with a different ExternalEmailAddress.\nThis script will update the remaining {3} mail-enabled public folder(s) without an ExternalEmailAddress.\nDo you really want to proceed? |
| 42 | +ConfirmationYesOption = &Yes |
| 43 | +ConfirmationNoOption = &No |
| 44 | +ConfirmationYesOptionHelp = Proceed and stamp ExternalEmailAddress on mail-enabled public folder(s) which aren't already stamped |
| 45 | +ConfirmationNoOptionHelp = STOP! mail-enabled public folders will not be stamped |
| 46 | +TitleForListOfMepfsRequireStamping = Following {0} mail-enabled public folder(s) requires stamping: |
| 47 | +TitleForListOfMepfsStampedWithValidAddress = Following {0} mail-enabled public folder(s) are already stamped with their exchange online addresses: |
| 48 | +TitleForListOfMepfsStampedWithOtherAddress = Following {0} mail-enabled public folder(s) are stamped with different addresses: |
| 49 | +NoMailEnabledPublicFoldersRequiresStamping = No mail-enabled public folder requires an ExternalEmailAddress stamping |
| 50 | +ExecutionSummaryFile = Execution summary is stored in {0} file |
| 51 | +StampingConfirmation = Confirmation for stamping: {0} |
| 52 | +RunningWithConfirmation = Running with user confirmation |
| 53 | +'@ |
| 54 | + |
| 55 | +if (Test-Path $ExecutionSummaryFile) { |
| 56 | + Remove-Item $ExecutionSummaryFile -Confirm:$false -Force |
| 57 | +} |
| 58 | + |
| 59 | +$null = New-Item -Path $ExecutionSummaryFile -ItemType File -Force -ErrorAction:Stop |
| 60 | + |
| 61 | +# Find EXO specific Public Folders accepted domain |
| 62 | +Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.FindingPublicFoldersAcceptedDomain |
| 63 | + |
| 64 | +$domain = Get-AcceptedDomain -Identity PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99 |
| 65 | + |
| 66 | +if ($null -eq $domain -or $null -eq $domain.DomainName -or [string]::IsNullOrWhiteSpace($domain.DomainName.ToString())) { |
| 67 | + Write-Error $LocalizedStrings.MissingExoDomain |
| 68 | + exit |
| 69 | +} |
| 70 | + |
| 71 | +$domain = $domain.DomainName.ToString().Trim() |
| 72 | + |
| 73 | +Write-Host "[$($(Get-Date).ToString())]" ($LocalizedStrings.FoundPublicFolderAcceptedDomain -f $domain) |
| 74 | + |
| 75 | +Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.EnumeratingMailEnabledPublicFolders |
| 76 | + |
| 77 | +# Total mail-enabled Public Folders |
| 78 | +$mepfs = Get-MailPublicFolder -ResultSize:Unlimited |
| 79 | + |
| 80 | +if ($null -eq $mepfs -or $mepfs.Count -eq 0) { |
| 81 | + Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.NoMailEnabledPublicFolders |
| 82 | + Add-Content $ExecutionSummaryFile $LocalizedStrings.NoMailEnabledPublicFolders |
| 83 | + exit |
| 84 | +} |
| 85 | + |
| 86 | +$totalMepfs = $mepfs.Count |
| 87 | +$mepfsRequireStamping = @() |
| 88 | +$listOfMepfsStampedWithValidAddress = "`t" |
| 89 | +$listOfMepfsStampedWithOtherAddress = "`t" |
| 90 | +$listOfMepfsRequireStamping = "`t" |
| 91 | +$totalMepfsRequireStamping = 0 |
| 92 | +$totalMepfsStampedWithValidAddress = 0 |
| 93 | +$totalMepfsStampedWithOtherAddress = 0 |
| 94 | + |
| 95 | +foreach ($mepf in $mepfs) { |
| 96 | + if ($null -eq $mepf.ExternalEmailAddress -or [string]::IsNullOrWhiteSpace($mepf.ExternalEmailAddress.ToString())) { |
| 97 | + $mepfsRequireStamping += $mepf |
| 98 | + $listOfMepfsRequireStamping += $mepf.DisplayName + " (" + $mepf.PrimarySmtpAddress + ")`n`t" |
| 99 | + $totalMepfsRequireStamping++ |
| 100 | + } else { |
| 101 | + $stampedSmtpAddress = $mepf.ExternalEmailAddress.ToString().ToLower() |
| 102 | + $primarySmtpAddress = $mepf.PrimarySmtpAddress.ToString() |
| 103 | + $alias = $primarySmtpAddress.Substring(0, $primarySmtpAddress.IndexOf('@')) |
| 104 | + $externalEmailAddress = ($alias + '@' + $domain).ToLower() |
| 105 | + $externalEmailAddressWithSmtpPrefix = 'smtp:' + $externalEmailAddress |
| 106 | + |
| 107 | + if ($stampedSmtpAddress.Equals($externalEmailAddress) -or $stampedSmtpAddress.Equals($externalEmailAddressWithSmtpPrefix)) { |
| 108 | + $listOfMepfsStampedWithValidAddress += $mepf.DisplayName + " (" + $mepf.PrimarySmtpAddress + ") => " + $mepf.ExternalEmailAddress + "`n`t" |
| 109 | + $totalMepfsStampedWithValidAddress++ |
| 110 | + } else { |
| 111 | + $listOfMepfsStampedWithOtherAddress += $mepf.DisplayName + " (" + $mepf.PrimarySmtpAddress + ") => " + $mepf.ExternalEmailAddress + "`n`t" |
| 112 | + $totalMepfsStampedWithOtherAddress++ |
| 113 | + } |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +Write-Host "[$($(Get-Date).ToString())]" ($LocalizedStrings.EnumeratingMailEnabledPublicFoldersComplete -f $totalMepfs) |
| 118 | + |
| 119 | +Add-Content $ExecutionSummaryFile ($LocalizedStrings.TitleForListOfMepfsRequireStamping -f $totalMepfsRequireStamping) |
| 120 | +Add-Content $ExecutionSummaryFile $listOfMepfsRequireStamping |
| 121 | +Add-Content $ExecutionSummaryFile ($LocalizedStrings.TitleForListOfMepfsStampedWithValidAddress -f $totalMepfsStampedWithValidAddress) |
| 122 | +Add-Content $ExecutionSummaryFile $listOfMepfsStampedWithValidAddress |
| 123 | +Add-Content $ExecutionSummaryFile ($LocalizedStrings.TitleForListOfMepfsStampedWithOtherAddress -f $totalMepfsStampedWithOtherAddress) |
| 124 | +Add-Content $ExecutionSummaryFile $listOfMepfsStampedWithOtherAddress |
| 125 | + |
| 126 | +if ($mepfsRequireStamping.Count -gt 0) { |
| 127 | + if ($Confirm) { |
| 128 | + # Ask for the confirmation |
| 129 | + $title = $LocalizedStrings.ConfirmationTitle |
| 130 | + $message = ($LocalizedStrings.ConfirmationQuestion -f $totalMepfs, $totalMepfsStampedWithValidAddress, $totalMepfsStampedWithOtherAddress, $totalMepfsRequireStamping) |
| 131 | + $yes = New-Object System.Management.Automation.Host.ChoiceDescription $LocalizedStrings.ConfirmationYesOption, $LocalizedStrings.ConfirmationYesOptionHelp |
| 132 | + $no = New-Object System.Management.Automation.Host.ChoiceDescription $LocalizedStrings.ConfirmationNoOption, $LocalizedStrings.ConfirmationNoOptionHelp |
| 133 | + |
| 134 | + [System.Management.Automation.Host.ChoiceDescription[]]$options = $no, $yes |
| 135 | + $confirmation = $host.ui.PromptForChoice($title, $message, $options, 0) |
| 136 | + |
| 137 | + $answer = "No" |
| 138 | + if ($confirmation -eq 1) { |
| 139 | + $answer = "Yes" |
| 140 | + } |
| 141 | + |
| 142 | + Add-Content $ExecutionSummaryFile ($LocalizedStrings.StampingConfirmation -f $answer) |
| 143 | + |
| 144 | + # Exit, if answer is "No" |
| 145 | + if ($confirmation -eq 0) { |
| 146 | + Write-Host "[$($(Get-Date).ToString())]" ($LocalizedStrings.ExecutionSummaryFile -f $ExecutionSummaryFile) |
| 147 | + exit |
| 148 | + } |
| 149 | + } else { |
| 150 | + # Running with user confirmation |
| 151 | + Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.RunningWithConfirmation |
| 152 | + Add-Content $ExecutionSummaryFile $LocalizedStrings.RunningWithConfirmation |
| 153 | + } |
| 154 | + |
| 155 | + Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.StampingMailEnabledPublicFolders |
| 156 | + |
| 157 | + $processed = 0 |
| 158 | + |
| 159 | + # Stamp mail-enabled public folders |
| 160 | + foreach ($mepf in $mepfsRequireStamping) { |
| 161 | + $primarySmtpAddress = $mepf.PrimarySmtpAddress.ToString() |
| 162 | + $alias = $primarySmtpAddress.Substring(0, $primarySmtpAddress.IndexOf('@')) |
| 163 | + $externalEmailAddress = $alias + '@' + $domain |
| 164 | + $mepf | Set-MailPublicFolder -ExternalEmailAddress $externalEmailAddress |
| 165 | + $processed++ |
| 166 | + Write-Progress -Activity $LocalizedStrings.ProgressBarActivity -Status ($LocalizedStrings.StampedMailEnabledPublicFolders -f $processed) -PercentComplete (100*($processed/$totalMepfsRequireStamping)) |
| 167 | + } |
| 168 | + |
| 169 | + Write-Host "[$($(Get-Date).ToString())]" ($LocalizedStrings.StampedMailEnabledPublicFolders -f $mepfsRequireStamping.Count) |
| 170 | + Add-Content $ExecutionSummaryFile ($LocalizedStrings.StampedMailEnabledPublicFolders -f $mepfsRequireStamping.Count) |
| 171 | +} else { |
| 172 | + Write-Host "[$($(Get-Date).ToString())]" $LocalizedStrings.NoMailEnabledPublicFoldersRequiresStamping |
| 173 | + Add-Content $ExecutionSummaryFile $LocalizedStrings.NoMailEnabledPublicFoldersRequiresStamping |
| 174 | +} |
| 175 | + |
| 176 | +if ($totalMepfsStampedWithOtherAddress -gt 0) { |
| 177 | + Write-Warning ($LocalizedStrings.AlreadyStampedMailEnabledPublicFolders -f $listOfMepfsStampedWithOtherAddress) |
| 178 | +} |
| 179 | + |
| 180 | +Write-Host "[$($(Get-Date).ToString())]" ($LocalizedStrings.ExecutionSummaryFile -f $ExecutionSummaryFile) |
0 commit comments