PowerShell导出AD用户时合并多memberOf值至同一列的实现方法
需求说明
需要使用PowerShell导出包含以下字段的AD用户CSV文件:objectGUID、sAMAccountName、givenName、SN、Description、mail、memberOf、preferredLanguage、manager、title、company、distinguishedName
现有问题
当同一AD用户归属多个AD组时,现有导出逻辑会为该用户生成多条仅memberOf字段取值不同的重复行。需要调整逻辑,将同一用户的所有归属AD组合并到同一行的memberOf列输出,不拆分到多行。
现有实现代码
Import-Module ActiveDirectory $Groups = import-csv CGroups.csv Foreach ($Group in $Groups) { $Arrayofmembers = Get-ADGroupMember -identity $Group.identity | select name,samaccountname foreach ($Member in $Arrayofmembers) { $user = Get-ADUser $member.samaccountname -properties mail,physicalDeliveryOfficeName,objectGuid,DisplayName,manager $guid = $user.objectGuid $immutableId = [System.Convert]::ToBase64String($guid.ToByteArray()) $OBJNEW=IID2GUID $immutableId $objatt15 = $OBJNEW.att15 $ADObj = Get-ADUser -Filter "extensionattribute15 -eq '$objatt15'" -Server dc.contoso.com:3268 -SearchBase 'dc=contoso,dc=net' -Properties msRTCSIP-PrimaryUserAddress,extensionattribute8,mail,DisplayName,manager,title,company $obj = New-Object -TypeName psobject $obj | Add-Member -MemberType NoteProperty -Name objectGUID -Value $ADObj.objectGUID $obj | Add-Member -MemberType NoteProperty -Name sAMAccountName -Value $ADObj.sAMAccountName $obj | Add-Member -MemberType NoteProperty -Name givenName -Value $ADObj.givenName $obj | Add-Member -MemberType NoteProperty -Name SN -Value $ADObj.Surname $obj | Add-Member -MemberType NoteProperty -Name Description -Value $ADObj.Description $obj | Add-Member -MemberType NoteProperty -Name mail -Value $ADObj.mail $obj | Add-Member -MemberType NoteProperty -Name memberOf -Value $Group.identity $obj | Add-Member -MemberType NoteProperty -Name preferredLanguage -Value $ADObj.preferredLanguage $obj | Add-Member -MemberType NoteProperty -Name manager -Value $ADObj.manager $obj | Add-Member -MemberType NoteProperty -Name title -Value $ADObj.title $obj | Add-Member -MemberType NoteProperty -Name company -Value $ADObj.company $obj | Add-Member -MemberType NoteProperty -Name distinguishedName -Value $ADObj.distinguishedName $obj | export-csv -Append -NoTypeInformation CGroupExport.csv } }
解决方案
核心思路是用哈希表存储已处理的用户,以用户唯一标识objectGUID作为键,遍历组时仅追加用户的所属组信息,所有组处理完成后统一导出。
修改后的完整代码如下:
Import-Module ActiveDirectory $Groups = Import-Csv CGroups.csv # 初始化哈希表存储用户,避免重复生成行 $userDictionary = @{} Foreach ($Group in $Groups) { $Arrayofmembers = Get-ADGroupMember -identity $Group.identity | select name,samaccountname foreach ($Member in $Arrayofmembers) { $user = Get-ADUser $member.samaccountname -properties mail,physicalDeliveryOfficeName,objectGuid,DisplayName,manager $guid = $user.objectGuid $immutableId = [System.Convert]::ToBase64String($guid.ToByteArray()) $OBJNEW = IID2GUID $immutableId $objatt15 = $OBJNEW.att15 # 补充查询缺失的字段属性 $ADObj = Get-ADUser -Filter "extensionattribute15 -eq '$objatt15'" -Server dc.contoso.com:3268 -SearchBase 'dc=contoso,dc=net' -Properties msRTCSIP-PrimaryUserAddress,extensionattribute8,mail,DisplayName,manager,title,company,Surname,Description,preferredLanguage,distinguishedName $userKey = $ADObj.objectGUID.ToString() if (-not $userDictionary.ContainsKey($userKey)) { # 首次处理该用户,初始化用户对象和所属组数组 $userObj = [PSCustomObject]@{ objectGUID = $ADObj.objectGUID sAMAccountName = $ADObj.sAMAccountName givenName = $ADObj.givenName SN = $ADObj.Surname Description = $ADObj.Description mail = $ADObj.mail memberOf = @($Group.identity) preferredLanguage = $ADObj.preferredLanguage manager = $ADObj.manager title = $ADObj.title company = $ADObj.company distinguishedName = $ADObj.distinguishedName } $userDictionary[$userKey] = $userObj } else { # 已处理过的用户,追加当前组到所属组数组 $userDictionary[$userKey].memberOf += $Group.identity } } } # 把所属组数组拼接为分号分隔的字符串,统一导出CSV $userDictionary.Values | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name memberOf -Value ($_.memberOf -join ';') -Force $_ } | Export-Csv -NoTypeInformation -Encoding UTF8 CGroupExport.csv
调整说明
- 新增哈希表做用户去重,避免重复生成用户行
- 同一用户多组归属时仅追加组信息到
memberOf数组,不重复创建用户对象 - 补充
Get-ADUser的查询属性,确保所有需要导出的字段都能正确获取 - 所有组遍历完成后统一导出,避免边遍历边追加导出产生重复行
- 新增UTF8编码配置,避免导出CSV中文乱码
内容的提问来源于stack exchange,提问作者Cristi
相关产品推荐
相关产品推荐

