Exchange 2010 Powershell指令碼攻略(五)

ImSunkist發表於2011-07-12

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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章