Hi all. I'm tryng to create a scheduled task that runs daily, where it will create new users, update (modify) exisiting users and delete users based on a comparison between users in a csv file and exchange contacts.
I set up a test environsment purely consisting of a basic Windows Server 2008 R2 domain controller and an Exchange 2010 SP1 server.
I run this powershell script from the Exchange server as a domain admin.
I can see the script correctly gets values from the csv file from the Host-Write command with the various variables. However it seems like line 77 to 83 doesn't work, where it tries to create a New-MailContact. I can't see the contact in either Exchange or the AD and when the script tries to run Set-Contact to further modify the contact from line 86 it states the operation couldn't be performed because object 'user e-mail address' couldn't be found on 'DomainController.domain.local'.
Please note that I've used this site for inspiration: [Link removed due to: Body text cannot contain images or links until we are able to verify your account]
Please can anyone tell me why the script is failing to create the exchange contact? Here's an anonymized version of the script:
# Enable Exchange Shell Commands
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
# Set the file location
$rawfile = “.\contacts.csv”
# Ignore Error Messages and continue on. Comment this out with a # symbol if you need verbose errors
# trap [Microsoft.Exchange.Configuration.Tasks.ManagementObjectNotFoundException] { continue; }
$contactfile = Import-CSV $rawfile -delimiter ";"
# ---------------------------
# Read contacts and make the magic happen
ForEach ($contact in $contactfile) {
# Read all attributes provided by the file
$sourceEmail=$contact.mail_xml
$sourceFirstName=$contact.givenName_xml -replace ” “,”-”
$sourceLastName=$contact.sn_xml -replace ” “,”-”
$sourceBranchCode=$contact.department_xml
$sourceBranchLegalName=$contact.company_xml
$sourcePhoneNumber=$contact.telephoneNumber_xml
$company=$contact.company_xml
$targetFirstName = $sourceFirstName
# Assign the Display Name using the correct First Name, Last Name and a suffix of COMPANY. We trim this field because of leading spaces that show up regularly
$sourceDisplayName = “$targetFirstName $sourceLastName $company”
$targetDisplayName = $sourceDisplayName.Trim()
# Assign the Distinguished Name attribute using the correct First Name, Last Name and OU structure
$targetDistinguishedName = “CN=$targetFirstName $sourceLastName,OU=ExternalContacts,DC=domain,DC=local”
# Assign the name attribute for new contacts
$targetCommonName = “$sourceFirstName $sourceLastName”
# Assign the Alias using COMPANY as a prefix so that we can identify them easily
$targetAlias = “$company $targetFirstName $sourceLastName”
# --------------------------------
###################################################
# Search for the contact to see if it is existing #
###################################################
if (Get-Contact -Identity $sourceEmail)
{
# Output to screen so we can track the process. Comment the following line when it is running as a batch process
Write-Host $sourceEmail Exists so $targetDisplayName will be MODIFIED -foregroundcolor green
Set-MailContact -Identity $sourceEmail -Alias $targetAlias -ForceUpgrade
Set-Contact -Identity $sourceEmail `
-Company $sourceBranchLegalName `
-Department $sourceBranchCode `
-DisplayName $targetDisplayName `
-SimpleDisplayName $targetDisplayName `
-Name “$targetCommonName” `
-FirstName $targetFirstName `
-LastName $sourceLastName `
-Phone $targetPhoneNumber `
-WindowsEmailAddress $sourceEmail -WhatIf
}
# ---------------------------------------
###################################################
# If it is not existing, create a new contact #
###################################################
else
{
# Output to screen so we can track the process. Comment the following line when it is running as a batch process
Write-Host $sourceEmail Does Not Exist so $targetDisplayName will be CREATED -foregroundcolor yellow
# First we create the contact with the required properties
New-MailContact -ExternalEmailAddress "$sourceEmail" `
-Name "$targetCommonName" `
-OrganizationalUnit “OU=ExternalContacts,DC=domain,DC=local” `
-DisplayName $targetDisplayName `
-FirstName $targetFirstName `
-LastName $sourceLastName `
-PrimarySmtpAddress $sourceEmail -WhatIf
# Now we set the additional properties that aren’t accessible by the New-MailContact cmdlet
Set-Contact -Identity $sourceEmail `
-Company $sourceBranchLegalName `
-Department $sourceBranchCode `
-DisplayName $targetDisplayName `
-SimpleDisplayName $targetDisplayName `
-FirstName $targetFirstName `
-LastName $sourceLastName `
-Phone $targetPhoneNumber `
-WindowsEmailAddress $sourceEmail -WhatIf
}
# Clean up after your pet – this does some memory cleanup
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
}
# -------------------------------------------------------
##################################################################
# Now we reverse the process and remove contacts no longer valid #
# If contact is not in the file, delete it #
##################################################################
$CurrentContacts = Get-MailContact -OrganizationalUnit ‘OU=ExternalContacts,DC=domain,DC=local’ -ResultSize Unlimited | Select-Object PrimarySMTPAddress,name
ForEach ($contact in $currentContacts) {
$sourceEmail = $Contact.PrimarySMTPAddress
if ( Get-Content $rawFile | Select-String -pattern $sourceEmail )
{
# Output to screen so we can track the process. Comment the following line when it is running as a batch process
Write-Host This contact $sourceEmail Exists in the file -foregroundcolor green
}
else
{
# Output to screen so we can track the process. Comment the following line when it is running as a batch process
Write-Host “DELETE THIS CONTACT $sourceEmail” -backgroundcolor yellow
Remove-MailContact -Identity “$sourceEmail” -Confirm:$Y -WhatIf
}
}
$CurrentContacts = $null
# Clean up after your pet – this does some memory cleanup
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()