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 ] [-ResultSize ]
[-Filter ] [-DomainController ] [-FixErrors] [-RemoveInvalidProxies]
[-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/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23700676/viewspace-1052331/