Script Bug Get-Recipient
I have a bug in my script that I cannot figure out. I am creating a script to populate DGs based on a CSV input file. Here is the script: # Script name: UpdateGlobalDGs.ps1 # Created on: 5/4/2010 # Author: Dan DeStefano # Purpose: Update membership of global distribution groups. # Parameters: # -InputFile <path to input file> - REQUIRED # Text document with a list of e-mail addresses to add to DG. Only one e-mail # address per line and there cannot be spaces before or after e-mail address # -DGName <DG alias, domain\account name, DN or GUID> - REQUIRED # Distribution group to be updated # Define input parameters Param($InputFile = $(Read-Host -Prompt 'Provide path and file name for list of e-mail addresses'),` $DGName = $(Read-Host -Prompt 'Provide name of DG to be processed')) # Set default scope to entire forest $AdminSessionADSettings.ViewEntireForest = $True # Load list of e-mail addresses into array $NewMemberList = Import-Csv -Path $InputFile # Resolve value of "DGName" parameter into valid object and define as variable $DG = Get-DistributionGroup -Identity $DGName # Load current membership list for DG into variable $OldMemberList = Get-DistributionGroupMember -Identity $DG.Name -ResultSize 'unlimited' # Export current DG members' primary e-mail addresses to file, then remove all members foreach ($OldMember in $OldMemberList) { $OldMember.PrimarySmtpAddress.ToString() | Out-File -Append -FilePath OldMemberList.txt Remove-DistributionGroupMember -Identity $DG.Alias -Member $OldMember.Identity -Confirm:$false } Write-Host "`n" ($NewMemberList.length) "total e-mail addresses to be processed against" `"($DG.Name)`" ` "distribution group`n" # Iterate through all e-mail addresses from list foreach ($NewMember in $NewMemberList) { # Resolve e-mail address from input file to valid recipient object and load variable $Recipient = Get-Recipient -Identity $NewMember."Email Address" $NewMember."Email Address" # If more or less than 1 recipient returned, update error log. Otherwise, append to array if ($Recipient -eq $null) { Out-File -Append -FilePath Error.log -InputObject (("There is no recipient object for ") + ($NewMember."Email Address") + ("`r`n")) continue } elseif ($Recipient.Length -ne $null) { Out-File -Append -FilePath Error.log -InputObject (("There are multiple recipient objects for ") + ($NewMember."Email Address") + ("`r`n")) continue } else { Add-DistributionGroupMember -Identity $DG.Alias -Member $Recipient.PrimarySmtpAddress.ToString() -WhatIf } } Here is an example of the input CSV Emplid,First Name,Middle Name,Last Name,Email Address 00000,Valid,,User0,vuser0@domain.com ,Valid,,User1,vuser1@domain.com ,Valid,,User2,vuser2@domain.com ,Valid,,User3,vuser3@domain.com ,Invalid,,User1,iuser1@domain.com Everything works fine. Even with the invalid user that was entered purposefully. However, if I intentionally put invalid data in the CSV file as follows, I get strange results. Notice there is no second "," after the "First Name" field in "valid user2" and "invalid user1": Emplid,First Name,Middle Name,Last Name,Email Address 00000,Valid,,User0,vuser0@domain.com ,Valid,,User1,vuser1@domain.com ,Valid,User2,vuser2@domain.com ,Valid,,User3,vuser3@domain.com ,Invalid,User1,iuser1@domain.com This causes the "email address" field to be null. I thought this would make the get-recipient command fail stating that "there is no value for the -identity parameter" - the way it does when running the command interactively. However, this is not what happens. Instead, it runs the command as if there were no parameters specified at all (I.E. just typing "get-recipient" and hitting Enter) - returning the first 1000 recipients then erroring stating the recipient limit has been reached. Can someone explain this behavior? The only solution I can think of would be to put the get-recipient cmdlet into an "if" statement that only runs if the $NewMember."Email Address" variable is not equal to $null. However, this does not seem too elegant to me and feels like a kludge. Any help would be appreciated. Also, I would welcome any other recommendations regarding the script. Dan
June 1st, 2010 10:12pm

In general, it's a lot more elegant to perform your own validity checks on the input data than to depend on the cmdlets you are running to do it for you. What happens when you enter: Get-Recipient -Identity $Null ? I get a list of all recipients. That's on Exchange 2010. I don't know what version you're running since you didn't say. -- Ed Crowley MVP "There are seldom good technological solutions to behavioral problems." . "Dan DeStefano" wrote in message news:11ff3aec-a81c-4b24-aa6b-7bc04af65c26... I have a bug in my script that I cannot figure out. I am creating a script to populate DGs based on a CSV input file. Here is the script: # Script name: UpdateGlobalDGs.ps1 # Created on: 5/4/2010 # Author: Dan DeStefano # Purpose: Update membership of global distribution groups. # Parameters: # -InputFile <path to input file> - REQUIRED # Text document with a list of e-mail addresses to add to DG. Only one e-mail # address per line and there cannot be spaces before or after e-mail address # -DGName <DG alias, domain\account name, DN or GUID> - REQUIRED # Distribution group to be updated # Define input parameters Param($InputFile = $(Read-Host -Prompt 'Provide path and file name for list of e-mail addresses'),` $DGName = $(Read-Host -Prompt 'Provide name of DG to be processed')) # Set default scope to entire forest $AdminSessionADSettings.ViewEntireForest = $True # Load list of e-mail addresses into array $NewMemberList = Import-Csv -Path $InputFile # Resolve value of "DGName" parameter into valid object and define as variable $DG = Get-DistributionGroup -Identity $DGName # Load current membership list for DG into variable $OldMemberList = Get-DistributionGroupMember -Identity $DG.Name -ResultSize 'unlimited' # Export current DG members' primary e-mail addresses to file, then remove all members foreach ($OldMember in $OldMemberList) { $OldMember.PrimarySmtpAddress.ToString() | Out-File -Append -FilePath OldMemberList.txt Remove-DistributionGroupMember -Identity $DG.Alias -Member $OldMember.Identity -Confirm:$false } Write-Host "`n" ($NewMemberList.length) "total e-mail addresses to be processed against" `"($DG.Name)`" ` "distribution group`n" # Iterate through all e-mail addresses from list foreach ($NewMember in $NewMemberList) { # Resolve e-mail address from input file to valid recipient object and load variable $Recipient = Get-Recipient -Identity $NewMember."Email Address" $NewMember."Email Address" # If more or less than 1 recipient returned, update error log. Otherwise, append to array if ($Recipient -eq $null) { Out-File -Append -FilePath Error.log -InputObject (("There is no recipient object for ") + ($NewMember."Email Address") + ("`r`n")) continue } elseif ($Recipient.Length -ne $null) { Out-File -Append -FilePath Error.log -InputObject (("There are multiple recipient objects for ") + ($NewMember."Email Address") + ("`r`n")) continue } else { Add-DistributionGroupMember -Identity $DG.Alias -Member $Recipient.PrimarySmtpAddress.ToString() -WhatIf } } Here is an example of the input CSV Emplid,First Name,Middle Name,Last Name,Email Address 00000,Valid,,User0,vuser0@domain.com ,Valid,,User1,vuser1@domain.com ,Valid,,User2,vuser2@domain.com ,Valid,,User3,vuser3@domain.com ,Invalid,,User1,iuser1@domain.com Everything works fine. Even with the invalid user that was entered purposefully. However, if I intentionally put invalid data in the CSV file as follows, I get strange results. Notice there is no second "," after the "First Name" field in "valid user2" and "invalid user1": Emplid,First Name,Middle Name,Last Name,Email Address 00000,Valid,,User0,vuser0@domain.com ,Valid,,User1,vuser1@domain.com ,Valid,User2,vuser2@domain.com ,Valid,,User3,vuser3@domain.com ,Invalid,User1,iuser1@domain.com This causes the "email address" field to be null. I thought this would make the get-recipient command fail stating that "there is no value for the -identity parameter" - the way it does when running the command interactively. However, this is not what happens. Instead, it runs the command as if there were no parameters specified at all (I.E. just typing "get-recipient" and hitting Enter) - returning the first 1000 recipients then erroring stating the recipient limit has been reached. Can someone explain this behavior? The only solution I can think of would be to put the get-recipient cmdlet into an "if" statement that only runs if the $NewMember."Email Address" variable is not equal to $null. However, this does not seem too elegant to me and feels like a kludge. Any help would be appreciated. Also, I would welcome any other recommendations regarding the script. Dan Ed Crowley MVP "There are seldom good technological solutions to behavioral problems."
Free Windows Admin Tool Kit Click here and download it now
June 2nd, 2010 7:48am

Sorry, I am on Exchange 2007 SP2 Rollup4. If I enter get-recipient -id $null interactively, it does return all recipients (well, the first 1000 anyway). I am not sure what you mean by perform my own validity checks on the input data? I thought that is what I was trying to do with the get-recipient cmdlet? If you mean that I should make sure the data in the CSV file is accurate and properly formatted, then I agree. However, this file is being generated by another team, then uploaded to a share. So then I guess there is no way to avoid this other than putting the get-recipient cmdlet into an 'if' statement?
June 2nd, 2010 3:28pm

Get-recipient $null is going to return a wildcard list of recipients. If $NewMember."Email Address" is null, then get-recipient $NewMember."Email Address" is going to return a wildcard list of recipients. It is what it is. if ($NewMember."Email Address") {$Recipient = Get-Recipient -Identity $NewMember."Email Address"} will prevent that. [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
Free Windows Admin Tool Kit Click here and download it now
June 2nd, 2010 3:41pm

I just tested the following, and it will return an error on null input, and still work if there is input there. Whether it's more or less "inelegant" or kludgy than using the IF is, IMHO, a matter of opinion. get-recipient ($NewMember."Email Address" + "")[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
June 2nd, 2010 3:49pm

Thanks, MJ. I decided to just use the 'if' statement because then i can just put in an else to write to a log file to make it easier to determine errors in the csv: if ($NewMember."Email Address" -ne $null) { $Recipient = Get-Recipient -Identity $NewMember."Email Address" } else { Out-File -Append -FilePath Error.log -InputObject (("There is no e-mail address for ") + ($NewMember)) $InvalidRec = $InvalidRec + 1 continue }
Free Windows Admin Tool Kit Click here and download it now
June 2nd, 2010 9:25pm

That's probably the best approach. FWIW, the "-ne $null" in if ($NewMember."Email Address" -ne $null) isn't necessary. Whatever is in the test clause of an IF (between the parens) gets evaluated as a boolean true/false, and any non-null string will always evaluate as $True. This can lead to some unexpected results like: PS C:\> $a = "False" PS C:\> [bool]$a True PS C:\>[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
June 2nd, 2010 9:38pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics