I have made advances, but still there are things that are not working, so I still need some help.
Reading here and there, I have written the following script, which, at least, don't give any errors:
param([string]$Mailbox);
$Foldername="test"
function Create-Contact
{
[CmdletBinding()]
param([string]$MailboxName,
[string]$DisplayName,
[string]$FirstName,
[string]$LastName,
[string]$EmailAddress,
[string]$Company,
[string]$Department,
[string]$Office,
[string]$BusinssPhone,
[string]$MobilePhone,
[string]$Notes,
[string]$JobTitle)
Begin
{
$EwsUrl = ([array](Get-WebServicesVirtualDirectory))[0].InternalURL.AbsoluteURI
## Load Managed API dll
[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll");
## Create Exchange Service Object
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$service.UseDefaultCredentials = $true
$service.URL = New-Object Uri($EwsUrl);
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
# Bind to the Contacts Folder
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
$RootFolder.Load()
$FolderView = new-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$ContactsFolderSearch = $RootFolder.FindFolders($FolderView) | Where {$_.DisplayName -eq $Foldername}
$Contacts = [Microsoft.Exchange.WebServices.Data.ContactsFolder]::Bind($service,$ContactsFolderSearch.Id);
$type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
$type = $type.MakeGenericType("Microsoft.Exchange.WebServices.Data.FolderId" -as "Type")
$ParentFolderIds = [Activator]::CreateInstance($type)
$ParentFolderIds.Add($Contacts.Id)
$Error.Clear();
$ncCol = $service.ResolveName($EmailAddress,$ParentFolderIds,[Microsoft.Exchange.WebServices.Data.ResolveNameSearchLocation]::ContactsOnly,$true);
if($Error.Count -eq 0){
if ($ncCol.Count -eq 0) #If I write-host $ncCol.count, it always shows 0, so it always enters here, the ResolveName query doesn't find the contact.
{
$Contact = New-Object Microsoft.Exchange.WebServices.Data.Contact -ArgumentList $service
#Set the GivenName
$Contact.GivenName = $FirstName
#Set the LastName
$Contact.Surname = $LastName
#Set Subject
$Contact.Subject = $DisplayName
$Contact.FileAs = $DisplayName
$Contact.CompanyName = $Company
$Contact.DisplayName = $DisplayName
$Contact.Department = $Department
$Contact.OfficeLocation = $Office
$Contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone] = $BusinssPhone
$Contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::MobilePhone] = $MobilePhone
#Set the Location
$Contact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1] = $EmailAddress
#Set any Notes
$Contact.Body = $Notes
$Contact.JobTitle = $JobTitle
$Contact.Save($Contacts.Id)
}
else
{
#This is the code I want to execute if the contact is found in the folder
$itemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$findItemResults = $service.FindItems($ContactsFolderSearch.ID, $itemView)
foreach ($Contact in $findItemResults.Items)
{
if ($Contact.DisplayName -eq $DisplayName ) {
$Contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone] = $BusinssPhone
$Contact.Save($Contacts.Id)
}
}
}
}
}
}
$EwsUrl = ([array](Get-WebServicesVirtualDirectory))[0].InternalURL.AbsoluteURI
$UserMailbox = Get-Mailbox $Mailbox
if (!$UserMailbox)
{
throw "Mailbox $($Mailbox) not found";
exit;
}
$EmailAddress2 = $UserMailbox.PrimarySMTPAddress
# Load EWS Managed API
[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll");
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$service.UseDefaultCredentials = $true;
$service.URL = New-Object Uri($EwsUrl);
# Search for an existing copy of the Folder to store Org contacts
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress2);
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
$RootFolder.Load()
$FolderView = new-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$ContactsFolderSearch = $RootFolder.FindFolders($FolderView) | Where {$_.DisplayName -eq $FolderName}
if ($ContactsFolderSearch) #Check if the contactFolder exists
{
$Users = get-user -Filter {WindowsEmailAddress -ne $null -and MobilePhone -ne $null -and WindowsEmailAddress -ne $EmailAddress2}
$Users = $Users | select DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone
foreach ($ContactItem in $Users) {
Create-Contact $Mailbox $ContactItem.DisplayName $ContactItem.FirstName $ContactItem.LastName $ContactItem.WindowsEmailAddress $ContactItem.Company $ContactItem.Department $ContactItem.OfficeLocation $ContactItem.Phone $ContactItem.MobilePhone $ContactItem.Body $ContactItem.Tittle
}
}
else
{
# Create new contacts folder
$ContactsFolder = New-Object Microsoft.Exchange.WebServices.Data.ContactsFolder($service);
$ContactsFolder.DisplayName = $FolderName
$ContactsFolder.Save([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
# Search for the new folder instance
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
$RootFolder.Load()
$FolderView = new-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$ContactsFolderSearch = $RootFolder.FindFolders($FolderView) | Where {$_.DisplayName -eq $FolderName}
$ContactsFolder = [Microsoft.Exchange.WebServices.Data.ContactsFolder]::Bind($service,$ContactsFolderSearch.Id);
$Users = get-user -Filter {WindowsEmailAddress -ne $null -and MobilePhone -ne $null -and WindowsEmailAddress -ne $EmailAddress2}
$Users = $Users | select DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone
#Once created the folder, write the contacts in it
foreach ($ContactItem in $Users) {
Create-Contact $Mailbox $ContactItem.DisplayName $ContactItem.FirstName $ContactItem.LastName $ContactItem.WindowsEmailAddress $ContactItem.Company $ContactItem.Department $ContactItem.OfficeLocation $ContactItem.Phone $ContactItem.MobilePhone $ContactItem.Body $ContactItem.Tittle
}
}
I call the script passing as param the email address of the user to who I will create the contact folder "test", and copy the GAL contacts in it.
When I run it for the first time, it works well: creates the folder and copy the GAL contacts into it.
But the second time that runs, instead of copying new GAL contacts and leave the existing contacts without modification except by the Bussiness Phone number, as I want, it copies again all the contacts, resulting in all entries duplicated.
As I write in the code coments, the line
$ncCol = $service.ResolveName($EmailAddress,$ParentFolderIds,[Microsoft.Exchange.WebServices.Data.ResolveNameSearchLocation]::ContactsOnly,$true);
is not finding the contact in the contact folder, because a write-host $ncCol.count after the line, shows always 0.
And the problem is not in the code: if I pass the search parameter to $EmailAddress as a string like "test@test.com", the contact is found. The problem is something strange: if I do a loop through all the contacts and write-host this:
$Contact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1]
what I see is not email address as is suppossed to be (i.e "test@test.com"): what I get is something like this:
/o=Persan Central/ou=Primer grupo administrativo/cn=Recipients/cn=fjfonseca
But in Outlook, the contact shows a correct email address.
Any clue?