Exchange 2010 Powershell指令碼攻略(五)
CheckInvalidRecipients
Param(
[string] $OrganizationalUnit,
[string] $ResultSize = "Unlimited",
[string] $Filter,
[string] $DomainController,
[switch] $FixErrors,
[switch] $RemoveInvalidProxies,
[switch] $ShowInvalidProxies,
[switch] $OutputObjects
)
# Catch any random input and output the help text
if ($args) {
@"
Usage: CheckInvalidRecipients.ps1 [-OrganizationalUnit
[-Filter
[-ShowInvalidProxies] [-OutputObjects]
This script is designed to return information on invalid recipient objects and possible
attemtpt to fix them.
-OrganizationalUnit: The OU the script will run against. The default is to run against
the current session scope.
-ResultSize: The maximum number of recipients of each type to return.
The four types are: User, Contact, Group, and DynamicDistributionGroup.
The default will return all recipients in the current scope.
-Filter: The filter that should used to retrieve recipients.
-DomainController: The domain controller the script should run against. The default is to
run against a well-connected domain controller in the current scope.
-FixErrors: Script will attempt to fix recipient errors it encounters.
-RemoveInvalidProxies: Script will attempt to remove invalid email addresses it encounters.
(-RemoveInvalidProxies must be specified with -FixErrors)
-ShowInvalidProxies: Script will display invalid email addresses it encounters.
-OutputObjects: Script will output any objects it processes to the pipeline.
NOTE: This script may re-read recipient data if it is necessary to complete the desired operation.
To improve performance, we will not re-read the data unless one of the following parameters
is specified: -FixErrors, -ShowInvalidProxies
This means piping objects from the Get-Recipient task will only work correctly if one of these
parameters is specified. (This is because the output from Get-Recipient never returns
validation errors)
Currently, the script can fix the following errors:
1. Primary SMTP Address Problems: If a recipient has multiple SMTP addresses listed as primary or
the primary SMTP is invalid, the script will try to set the
WindowsEmailAddress as the primary SMTP address, since that is
the address Exchange 2003 would have recognized as the primary
(although E12 does not).
2. External Email Address Problems: If a recipient has an external email address, but that address
is missing from the EmailAddresses collection, the script will
attempt to add it to the EmailAddresses.
3. Invalid Email Addresses: If a recipient has invalid email addresses in their EmailAddresses
collection it may prevent some scripts from working correctly on
that recipient. In order to prevent this potential problem the
script is capable of removing any offending email addresses from
the recipient. To remove invalid email addresses, please specify
both the -FixErrors and the -RemoveInvalidProxies parameters
Example Usages:
Display validation errors for all recipients in the current scope:
.CheckInvalidRecipients.ps1
Fix all recipients in the 'Users' container that have invalid Primary SMTP addresses:
.CheckInvalidRecipients.ps1 -OrganizationalUnit 'Users' -FixErrors
Return all recipients in the current scope after fixing any email address problems:
.CheckInvalidRecipients.ps1 -FixErrors -RemoveInvalidProxies -OutputObjects
Display validation errors and invalid email addresses for mailboxes in the current scope:
Get-Recipient -RecipientType UserMailbox | .CheckInvalidRecipients.ps1 -ShowInvalidProxies
"@
exit
}
############################################################ Function Declarations ################################################################
function HasValidWindowsEmailAddress($obj)
{
return $obj.WindowsEmailAddress.IsValidAddress
}
function HasInvalidPrimarySmtp($obj)
{
return !$obj.PrimarySmtpAddress.IsValidAddress
}
function IsValid($obj)
{
if (!$obj.IsValid)
{ return $false }
foreach ($address in $obj.EmailAddresses)
{
if ($address -is [Microsoft.Exchange.Data.InvalidProxyAddress])
{ return $false }
}
return $true
}
function WriteErrorMessage($str)
{
Write-host $str -ForegroundColor Red
}
function WriteInformation($str)
{
Write-host $str -ForegroundColor Yellow
}
function WriteSuccess($str)
{
Write-host $str -ForegroundColor Green
}
function WriteWarning($str)
{
$WarningPreference = $Global:WarningPreference
write-warning $str
}
function PrintValidationError($obj)
{
foreach($err in $obj.Validate())
{
WriteErrorMessage('{0},{1},{2}' -f $obj.Id,$err.PropertyDefinition.Name,$err.Description)
}
}
function EvaluateErrors($Recipient)
{
PrintValidationError($Recipient)
$tasknoun = $null
# We're comparing the RecipientType to the enum value instead of strings, because the strings may be localized and then this comparison would fail
switch ($Recipient.RecipientType)
{
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::UserMailbox} { $tasknoun = "Mailbox" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::MailUser} { $tasknoun = "Mailuser" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::MailContact} { $tasknoun = "Mailcontact" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::MailUniversalDistributionGroup} { $tasknoun = "DistributionGroup" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::MailUniversalSecurityGroup} { $tasknoun = "DistributionGroup" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::MailNonUniversalGroup} { $tasknoun = "DistributionGroup" }
{$_ -eq [Microsoft.Exchange.Data.Directory.Recipient.RecipientType]::DynamicDistributionGroup} { $tasknoun = "DynamicDistributionGroup" }
}
if (($tasknoun -ne $null) -AND ($FixErrors -OR $ShowInvalidProxies))
{
# Prepare the appropriate get/set tasks that need to run
$GetRecipientCommand = "get-$tasknoun"
if (![String]::IsNullOrEmpty($DomainController))
{ $GetRecipientCommand += " -DomainController $DomainController" }
$SetRecipientCommand = "set-$tasknoun"
if (![String]::IsNullOrEmpty($DomainController))
{ $SetRecipientCommand += " -DomainController $DomainController" }
# Read the object using the correct Get-Task, so we get all the email properties
$Recipient = &$GetRecipientCommand $Recipient.Identity
# Nothing to do if the recipient is completely valid except output it to the pipeline
if (IsValid($Recipient))
{
# Output the object to the pipeline
if ($OutputObjects)
{ Write-Output $Recipient }
return;
}
# Collect all the invalid proxy addresses in case we need them later
$InvalidProxies = @()
foreach ($Address in $Recipient.EmailAddresses)
{
if ($Address -is [Microsoft.Exchange.Data.InvalidProxyAddress])
{
$InvalidProxies += $Address
}
}
if ($ShowInvalidProxies -AND ($InvalidProxies.Length -gt 0))
{
foreach ($Address in $InvalidProxies)
{
WriteErrorMessage('{0},{1},{2}' -f $Recipient.Id,"EmailAddresses",$Address.ParseException.ToString())
}
}
if ($FixErrors)
{
$RecipientModified = $false
# Fix the major PrimarySmtpAddress problems
# If the WindowsEmailAddress is valid, we'll set that as the Primary since Exchange 2003 used that as the Primary
if ((HasValidWindowsEmailAddress($Recipient)) -AND
(HasInvalidPrimarySmtp($Recipient)))
{
$Recipient.PrimarySmtpAddress = $Recipient.WindowsEmailAddress
WriteInformation("New PrimarySmtpAddress for {0}: {1}" -f $Recipient.Identity, $Recipient.WindowsEmailAddress)
$RecipientModified = $true
}
# If the ExternalEmailAddress is missing from the EmailAddresses collection, we should add it back
if (($null -ne $Recipient.ExternalEmailAddress) -AND
!($Recipient.EmailAddresses.Contains($Recipient.ExternalEmailAddress)))
{
$Recipient.EmailAddresses.Add($Recipient.ExternalEmailAddress)
$RecipientModified = $true
}
# Remove all the invalid proxy addresses if the user specified the RemoveInvalidProxies flag
if ($RemoveInvalidProxies -AND ($InvalidProxies.Length -gt 0))
{
foreach ($Address in $InvalidProxies)
{
# Using this DummyVariable so the script doesn't output the result of the Remove operation
$DummyVariable = $Recipient.EmailAddresses.Remove($Address)
WriteInformation("Removed invalid proxy address from {0}: {1}" -f $Recipient.Identity, $Address)
}
$RecipientModified = $true
}
# Let's try to save the object back to AD
if ($RecipientModified)
{
$numErrors = $error.Count
&$SetRecipientCommand -Instance $Recipient
if ($error.Count -eq $numErrors)
{
WriteSuccess("Successfully saved '{0}'" -f $Recipient.Identity)
}
else
{
WriteErrorMessage("Error while saving '{0}'" -f $Recipient.Identity)
}
}
# Re-read the recipient if we modified it in any way and we want to output it to the pipeline
if ($OutputObjects)
{ $Recipient = &$GetRecipientCommand $Recipient.Identity }
} # if ($FixErrors)
} # if (($tasknoun -ne $null) -AND ($FixErrors -OR $ShowInvalidProxies))
# Output the object to the pipeline
if ($OutputObjects)
{ Write-Output $Recipient }
} # EvaluateErrors
############################################################ Function Declarations End ############################################################
############################################################ Main Script Block ####################################################################
#Ignore Warnings output by the task
$WarningPreference = 'SilentlyContinue'
if ($RemoveInvalidProxies -AND !$FixErrors)
{ WriteWarning("RemoveInvalidProxies has no effect unless FixErrors is also specified") }
# Check if we have any pipeline input
# If yes, MoveNext will return true and we won't run our get tasks
if ($input.MoveNext())
{
# Reset the enumerator so we can look at the first object again
$input.Reset()
if ($ResultSize -NE "Unlimited")
{ WriteWarning("ResultSize parameter has no effect when piping input") }
if (![String]::IsNullOrEmpty($OrganizationalUnit))
{ WriteWarning("OrganizationalUnit parameter has no effect when piping input") }
if (![String]::IsNullOrEmpty($Filter))
{ WriteWarning("Filter parameter has no effect when piping input") }
foreach ($Recipient in $input)
{
# skip over inputs that we can't handle
if ($Recipient -eq $null -OR
$Recipient.RecipientType -eq $null -OR
$Recipient -isnot [Microsoft.Exchange.Data.Directory.ADObject])
{ continue; }
EvaluateErrors($Recipient)
}
}
else
{
$cmdlets =
@("get-User",
"get-Contact",
"get-Group",
"get-DynamicDistributionGroup")
foreach ($task in $cmdlets)
{
$command = "$task -ResultSize $ResultSize"
if (![String]::IsNullOrEmpty($OrganizationalUnit))
{ $command += " -OrganizationalUnit $OrganizationalUnit" }
if (![String]::IsNullOrEmpty($DomainController))
{ $command += " -DomainController $DomainController" }
if (![String]::IsNullOrEmpty($Filter))
{ $command += " -Filter $Filter" }
invoke-expression $command | foreach { EvaluateErrors($_) }
}
}
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23700676/viewspace-1052331/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Exchange 2010 Powershell指令碼攻略(十五)指令碼
- Exchange 2010 Powershell指令碼攻略(十四)指令碼
- Exchange 2010 Powershell指令碼攻略(十三)指令碼
- Exchange 2010 Powershell指令碼攻略(十二)指令碼
- Exchange 2010 Powershell指令碼攻略(十一)指令碼
- Exchange 2010 Powershell指令碼攻略(十)指令碼
- Exchange 2010 Powershell指令碼攻略(九)指令碼
- Exchange 2010 Powershell指令碼攻略(八)指令碼
- Exchange 2010 Powershell指令碼攻略(七)指令碼
- Exchange 2010 Powershell指令碼攻略(六)指令碼
- Exchange 2010 Powershell指令碼攻略(四)指令碼
- Exchange 2010 Powershell指令碼攻略(三)指令碼
- Exchange 2010 Powershell指令碼攻略(二)指令碼
- Exchange 2010 Powershell指令碼攻略(一)指令碼
- powershell指令碼指令碼
- 五個實用的SQL Server PowerShell指令碼OMSQLServer指令碼
- PowerShell 指令碼中的密碼指令碼密碼
- PowerShell 指令碼執行策略指令碼
- powershell重新命名指令碼指令碼
- Exchange 2010搭建
- Bash指令碼debug攻略指令碼
- 開機自啟動Powershell指令碼指令碼
- linux shell 指令碼攻略筆記Linux指令碼筆記
- 【黑客基礎】Windows PowerShell 指令碼學習(上)黑客Windows指令碼
- 最簡單的一個powershell的指令碼指令碼
- Exchange 2010需要的網路埠
- 微軟宣佈全新命令列+指令碼工具:PowerShell 7微軟命令列指令碼
- 利用powershell指令碼Windows hosts記錄替換IP指令碼Windows
- Win10使用Powershell提示禁止執行指令碼怎麼辦 Win10使用Powershell提示禁止執行指令碼如何解決Win10指令碼
- shell指令碼攻略--DNS正向解析一鍵部署指令碼DNS
- 利用 Powershell 編寫簡單的瀏覽器指令碼瀏覽器指令碼
- 【連結】LINUX SHELL指令碼攻略筆記[速查]Linux指令碼筆記
- 《Linux Shell指令碼攻略(第2版)》書評Linux指令碼
- nuget打包檔案丟失如何使用powershell指令碼解決指令碼
- 使用VSCode遠端除錯惡意Powershell指令碼VSCode除錯指令碼
- 【VMware VCF】使用 PowerShell 指令碼管理 SDDC Manager 中的軟體包。指令碼
- Linux基礎五(shell指令碼)Linux指令碼
- PowerShell 指令碼來監控 CPU、記憶體和磁碟使用情況:指令碼記憶體