我的最终目标是让下面的代码找到并针对域中的所有用户运行,而无需手动输入每个用户,但我不知道如何。然后我会将脚本放入任务调度程序中。
以下是这背后的故事和信息,以防对其他人有所帮助。
我的首席运营官希望我们的全球通讯录能够离线显示在每个人的设备(即 Android、IOS、Windows 等)中。我找到了一种方法,在 Exchange Powershell 中使用 Steve Goodmans 方法/代码一次一个用户进行操作 --> http://www.stevieg.org/2012/02/importing-global-address-list-entries-into -a-users-contacts-文件夹。对我自己的用户名执行此操作后,我可以离线查看手机上的 GAL 信息。而且,如果有人用他们的电话给我打电话,它现在会通过从导入的 GAL 中拉出,在我的手机上显示他们的名字。
基本上,使用他的代码,我将全局地址簿作为单独的地址簿复制给每个人。如果您在 Outlook 中查看您的联系人,您将看到名为 OrgContacts 的新通讯簿(在本例中)。当您的设备下次同步进行交换时,此地址簿也会同步,您将拥有整个公司。我们有几百个用户,所以这没什么大不了的。
到目前为止,我使用的代码一次只有一个用户。我需要帮助使它找到所有用户名并执行。我在运行字符串中尝试了通配符,但没有奏效。如果有的话,我也愿意采用一种完全不同的方式来实现这一点。
非常感谢您的宝贵时间,
要为每个用户运行代码,我使用这个...
# example (Billy Smith network username is basmith)
.\Copy-OrgContactsToUserContacts.ps1 -Mailbox basmith -FolderName OrgContacts
这是 Exchange 电源外壳代码...
param([string]$Mailbox,[string]$FolderName="OrgContacts");
#
# Copy-OrgContactsToUserMailboxContacts.ps1
#
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
# RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#
# Parameters
# Mandatory:
# -MailboxFolder : Folder to "own" for these contacts.
#
# Creates s OrgContacts folder in the Mailbox and adds the contacts into it. Does not attempt to
$EwsUrl = ([array](Get-WebServicesVirtualDirectory))[0].InternalURL.AbsoluteURI
$ContactMapping=@{
"FirstName" = "GivenName";
"LastName" = "Surname";
"Company" = "CompanyName";
"Department" = "Department";
"Title" = "JobTitle";
"WindowsEmailAddress" = "Email:EmailAddress1";
"Phone" = "Phone:BusinessPhone";
"MobilePhone" = "Phone:MobilePhone";
}
$UserMailbox = Get-Mailbox $Mailbox
if (!$UserMailbox)
{
throw "Mailbox $($Mailbox) not found";
exit;
}
$EmailAddress = $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, $EmailAddress);
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
$RootFolder.Load()
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
$FolderView = new-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$ContactsFolderSearch = $RootFolder.FindFolders($FolderView) | Where {$_.DisplayName -eq $FolderName}
if ($ContactsFolderSearch)
{
# Empty if found
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
$ContactsFolder = [Microsoft.Exchange.WebServices.Data.ContactsFolder]::Bind($service,$ContactsFolderSearch.Id);
$ContactsFolder.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete, $true)
} else {
# Create new contacts folder
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
$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);
}
# Add contacts
$Users = get-user -Filter {WindowsEmailAddress -ne $null -and (MobilePhone -ne $null -or Phone -ne $null) -and WindowsEmailAddress -ne $EmailAddress}
$Users = $Users | select DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone
foreach ($ContactItem in $Users)
{
$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
$ExchangeContact = New-Object Microsoft.Exchange.WebServices.Data.Contact($service);
if ($ContactItem.FirstName -and $ContactItem.LastName)
{
$ExchangeContact.NickName = $ContactItem.FirstName + " " + $ContactItem.LastName;
}
elseif ($ContactItem.FirstName -and !$ContactItem.LastName)
{
$ExchangeContact.NickName = $ContactItem.FirstName;
}
elseif (!$ContactItem.FirstName -and $ContactItem.LastName)
{
$ExchangeContact.NickName = $ContactItem.LastName;
}
elseif (!$ContactItem.FirstName -and !$ContactItem.LastName)
{
$ExchangeContact.NickName = $ContactItem.DisplayName;
$ContactItem.FirstName = $ContactItem.DisplayName;
}
$ExchangeContact.DisplayName = $ExchangeContact.NickName;
$ExchangeContact.FileAs = $ExchangeContact.NickName;
# This uses the Contact Mapping above to save coding each and every field, one by one. Instead we look for a mapping and perform an action on
# what maps across. As some methods need more "code" a fake multi-dimensional array (seperated by :'s) is used where needed.
foreach ($Key in $ContactMapping.Keys)
{
# Only do something if the key exists
if ($ContactItem.$Key)
{
# Will this call a more complicated mapping?
if ($ContactMapping[$Key] -like "*:*")
{
# Make an array using the : to split items.
$MappingArray = $ContactMapping[$Key].Split(":")
# Do action
switch ($MappingArray[0])
{
"Email"
{
$ExchangeContact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::($MappingArray[1])] = $ContactItem.$Key.ToString();
}
"Phone"
{
$ExchangeContact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::($MappingArray[1])] = $ContactItem.$Key;
}
}
} else {
$ExchangeContact.($ContactMapping[$Key]) = $ContactItem.$Key;
}
}
}
# Save the contact
$ExchangeContact.Save($ContactsFolder.Id);
# Provide output that can be used on the pipeline
$Output_Object = New-Object Object;
$Output_Object | Add-Member NoteProperty FileAs $ExchangeContact.FileAs;
$Output_Object | Add-Member NoteProperty GivenName $ExchangeContact.GivenName;
$Output_Object | Add-Member NoteProperty Surname $ExchangeContact.Surname;
$Output_Object | Add-Member NoteProperty EmailAddress1 $ExchangeContact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1]
$Output_Object;
}