我有一个共享邮箱,需要将其部署到我们某个部门的 Exchange 2010 SP2 环境中,该部门有 Outlook 2010 客户端。我试图依靠Exchange 2010 SP1 引入的自动映射功能,原因很明显,但它不起作用。
仔细观察,这是因为它不适用于团体,巧妙地阻止它成为任何需要管理大量邮件用户的人的有用功能。
上面的链接包含一个解决方法 PowerShell 脚本,用于读取组的成员身份并直接添加这些成员以拥有完全访问权限,但这不提供在人员加入或离开部门时更新自动映射的功能。
当使用组授予用户对邮箱的完全访问权限时,是否有人知道使此功能正常运行的方法?(或者甚至对如何解决这个问题有任何想法?现在,我正在考虑一个定期更新相关 AD 属性的 Powershell 脚本,但是...一定有更好的方法。)
答案1
当我们遇到同样的问题时,我创建了这个脚本。也许这不是世界上最漂亮的东西,但它能完成工作。我OU
为访问组创建了一个单独的文件夹,然后为资源邮箱创建了另一个。组和资源邮箱使用相同的名称,只是A-
组前面有一个。
例如 A-RESMBX1
组名和REXMBX1
资源邮箱。
该脚本枚举组中的组OU
,然后枚举其中的资源邮箱OU
。然后循环遍历每个组并查找匹配的资源邮箱。找到匹配项后,它会枚举组的用户,然后将其添加到msExchDelegateListLink
资源邮箱的属性中。
它还将从msExchDelegateListLink
属性中删除不再是相关访问组成员的用户。我在 DC 上的计划任务中运行了此操作。
我们的需求是由于实习生的流动率很高,他们需要访问大量的资源邮箱。
您需要更新 LDAP 路径到 OU$Groups
以及$ResMBXs
您的 DC 名称$DomainController
Import-Module ActiveDirectory
$DomainController = "MYDOMAINCONTROLLER"
$Groups = Get-ADGroup -Filter * -SearchBase 'OU=Groups,OU=Resource Mailboxes,DC=mydomain,DC=com' -Server $DomainController | Sort-Object Name
$ResMBXs = Get-ADUser -Filter * -SearchBase 'OU=Resource Mailboxes,DC=mydomain,DC=com' -Server $DomainController -properties msExchDelegateListLink | Sort-Object Name
Write-Host "Enumerating Groups and Resource Mailboxes..."
Write-Host ""
# IsMember function is borrowed from : http://gallery.technet.microsoft.com/scriptcenter/5adf9ad0-1abf-4557-85cd-657da1cc7df4
# Hash table of security principals and their security group memberships.
$GroupList = @{}
Function IsMember ($ADObject, $GroupName)
{
# Function to check if $ADObject is a member of security group $GroupName.
# Check if security group memberships for this principal have been determined.
If ($GroupList.ContainsKey($ADObject.sAMAccountName.ToString() + "\") -eq $False)
{
# Memberships need to be determined for this principal. Add "pre-Windows 2000"
# name to the hash table.
$GroupList.Add($ADObject.sAMAccountName.ToString() + "\", $True)
# Retrieve tokenGroups attribute of principal, which is operational.
$ADObject.psbase.RefreshCache("tokenGroups")
$SIDs = $ADObject.psbase.Properties.Item("tokenGroups")
# Populate hash table with security group memberships.
ForEach ($Value In $SIDs)
{
$SID = New-Object System.Security.Principal.SecurityIdentifier $Value, 0
# Translate into "pre-Windows 2000" name.
$Group = $SID.Translate([System.Security.Principal.NTAccount])
$GroupList.Add($ADObject.sAMAccountName.ToString() + "\" + $Group.Value.Split("\")[1], $True)
}
}
# Check if $ADObject is a member of $GroupName.
If ($GroupList.ContainsKey($ADObject.sAMAccountName.ToString() + "\" + $GroupName))
{
Return $True
}
Else
{
Return $False
}
}
Foreach ($gr in $Groups) {
Foreach ($mbx in $ResMBXs) {
$MBXName = "A-" + $mbx.Name
$LDAPUser=[ADSI]"LDAP://$($DomainController)/$($mbx.distinguishedName)"
if ($gr.Name -eq $MBXName)
{
#Build an Array of DNs from each Group
$Members = Get-ADGroupMember $gr -Server $DomainController
if ($Members -ne $Null)
{
Foreach ($mbr in $Members){
if($mbr.distinguishedName -ne $Null)
{
$LDAPUser.msExchDelegateListLink.Add($mbr.distinguishedName)
$LDAPUser.SetInfo()
}
$AddedUsers += $mbr.Name
}
}
Else {Write-Host -foregroundcolor darkyellow "Group contains no members..."; Write-Host ""}
if($mbx.msExchDelegateListLink -ne $Null) {
$ACLUsers = $mbx.msExchDelegateListLink
Foreach ($ACLUser in $ACLUsers)
{
#Check if user is a member of the current group
#If not, remove from attribute
$user = [ADSI]"LDAP://$($DomainController)/$($ACLUser)"
$userDN = Get-ADUser $ACLUser -Server $DomainController
$mem = IsMember $user $gr.Name
If ($mem -eq $False)
{
$LDAPUser.msExchDelegateListLink.Remove($userDN.distinguishedName)
$LDAPUser.SetInfo()
Write-Host "The Following User was removed from: " -nonewline; Write-Host -foregroundcolor yellow $mbx.Name
Write-Host -nonewline -foregroundcolor darkyellow " " $UserDN.Name
Write-Host ""
}
}
}
$Members = ""
Write-Host "The Following Users were added to: " -nonewline; Write-Host -foregroundcolor yellow $mbx.Name
Write-Host ""
Write-Host -foregroundcolor darkyellow $AddedUsers
Write-Host ""
$AddedUsers = ""
}
}
}