如何读取Exchange邮箱的ms-Exch-Mailbox-Security-Descriptor及优化文件夹权限采集
优化Exchange邮箱文件夹权限采集(SDDL方式)及读取邮箱安全描述符
一、批量获取邮箱文件夹的SDDL安全描述符
针对大型环境下Get-MailboxFolderPermission因逐个解析ACE显示名导致的性能问题,可直接获取文件夹权限的SDDL格式安全描述符,后续批量解析SID到显示名,大幅减少LDAP查询次数。以下是原生Exchange PowerShell实现:
优化后的采集函数
Function Pull-MBXFolderSDDL { Param ([string]$MBXName) Start-Sleep -Milliseconds 600 $mailbox = $MBXName $folders = Get-MailboxFolderStatistics $mailbox | ForEach-Object { $_.FolderPath.Replace("/", "\") } Write-Host "Processing folders on mailbox $mailbox" $folderSDDLList = @() foreach ($fold in $folders) { $folderKey = "$mailbox`:$fold" try { # 获取文件夹权限对象,提取安全描述符 $folderPerms = Get-MailboxFolderPermission -Identity $folderKey -ErrorAction Stop $securityDescriptor = $folderPerms | Select-Object -ExpandProperty SecurityDescriptor # 转换为Access部分的SDDL格式 $sddl = $securityDescriptor.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::Access) # 过滤掉Default/Anonymous用户、无权限/Owner权限,以及继承的ACE(和原逻辑对齐) $filteredACEs = $sddl -split "\(" | Where-Object { $_ -notmatch "Default|Anonymous" -and $_ -notmatch "None|Owner" -and !$_.Contains("ID") } | ForEach-Object { $_.TrimEnd(")") } $filteredSDDL = "D:" + ($filteredACEs -join "(") $folderSDDLList += [PSCustomObject]@{ Mailbox = $mailbox FolderName = $fold AccessSDDL = $filteredSDDL } } catch { Write-Warning "Failed to process $folderKey : $_" continue } } return $folderSDDLList }
后续批量解析SID
收集所有SDDL中的SID后,可一次性查询AD转换为显示名:
# 假设$allSDDLData是所有文件夹的SDDL数据 $sids = $allSDDLData.AccessSDDL | Select-String -Pattern "S-1-5-[\d-]+" -AllMatches | ForEach-Object { $_.Matches.Value } | Select-Object -Unique # 批量查询AD获取SID对应的显示名 $sidToName = @{} Get-ADObject -Filter {SID -in $sids} -Properties Name | ForEach-Object { $sidToName[$_.SID.Value] = $_.Name } # 替换SDDL中的SID为显示名(可选) $allSDDLData | ForEach-Object { foreach ($sid in $sidToName.Keys) { $_.AccessSDDL = $_.AccessSDDL.Replace($sid, $sidToName[$sid]) } }
二、读取邮箱的ms-Exch-Mailbox-Security-Descriptor
该属性存储在AD的邮箱对象中,可通过Active Directory模块直接读取并转换为SDDL格式:
单个邮箱查询
$mailboxUPN = "user@domain.com" # 获取AD对象并提取安全描述符属性 $adMailbox = Get-ADUser -Filter {UserPrincipalName -eq $mailboxUPN} -Properties ms-Exch-Mailbox-Security-Descriptor # 转换为RawSecurityDescriptor对象并生成SDDL $securityDescriptor = [System.Security.AccessControl.RawSecurityDescriptor]::new($adMailbox.'ms-Exch-Mailbox-Security-Descriptor', 0) $mailboxSDDL = $securityDescriptor.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::Access) Write-Host "Mailbox Security SDDL:`n$mailboxSDDL"
批量查询邮箱安全描述符
# 获取所有邮箱的AD标识 $mailboxes = Get-Mailbox -ResultSize Unlimited | Select-Object UserPrincipalName, SamAccountName $mailboxSecurityList = @() foreach ($mbx in $mailboxes) { try { $adObject = Get-ADObject -Filter {SamAccountName -eq $mbx.SamAccountName} -Properties ms-Exch-Mailbox-Security-Descriptor $sd = [System.Security.AccessControl.RawSecurityDescriptor]::new($adObject.'ms-Exch-Mailbox-Security-Descriptor', 0) $sddl = $sd.GetSecurityDescriptorSddlForm([System.Security.AccessControl.AccessControlSections]::Access) $mailboxSecurityList += [PSCustomObject]@{ MailboxUPN = $mbx.UserPrincipalName MailboxSamAccountName = $mbx.SamAccountName MailboxSecuritySDDL = $sddl } } catch { Write-Warning "Failed to retrieve security descriptor for $($mbx.UserPrincipalName) : $_" continue } } # 导出到CSV $mailboxSecurityList | Export-Csv -Path "MailboxSecuritySDDL.csv" -NoTypeInformation
关键说明
- 性能提升核心:避免
Get-MailboxFolderPermission自动逐个解析ACE显示名的LDAP请求,改为批量处理SID解析,大幅降低AD查询次数。 - 原生依赖:仅使用Exchange Management Shell和Active Directory模块的原生命令,无需MFCMAPI或第三方工具。
- 权限要求:需具备Exchange邮箱文件夹权限查看权限,以及AD对象读取权限。
内容的提问来源于stack exchange,提问作者PJBuckley
相关产品推荐
相关产品推荐

