You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何保留对象格式同时筛选Get-ADUser的属性子集?

解决AD用户对象筛选后兼容AD Cmdlet的问题

我完全懂你的痛点——处理数十万AD用户时,性能和对象兼容性简直是两难。问题的核心在于:Select-Object会把原生的ADUser对象转换成自定义的PSObject,而Get-ADPrincipalGroupMembership这类AD cmdlet只认原生AD主体对象(比如ADUser、ADGroup)或者能解析为主体标识符的字符串(比如SamAccountName)。

给你两个最实用的解决方案,既能保留所需属性,又能维持对象兼容性,还能保证性能:

方案1:从源头控制Get-ADUser返回的属性(最优解)

这是最根本的解决办法——直接让Get-ADUser只返回你需要的属性,而不是先拉取全量属性再用Select-Object筛选。这样返回的仍然是原生的ADUser对象,完全兼容所有AD相关cmdlet,同时因为从AD服务器拉取的数据更少,性能会比你之前的方法还要好。

示例代码:

# 只获取你需要的属性(比如SamAccountName、DisplayName、EmailAddress)
# 注意:SamAccountName是默认返回的属性,也可以省略,但写出来更清晰
$users = Get-ADUser -Filter * -Properties SamAccountName, DisplayName, EmailAddress

# 直接遍历原生ADUser对象,完美兼容Get-ADPrincipalGroupMembership
$users | ForEach-Object {
    Write-Host "正在处理用户: $($_.DisplayName)"
    # 直接传入$_(ADUser对象)即可,无需额外提取属性
    $userGroups = Get-ADPrincipalGroupMembership $_
    
    # 其他需要用到多属性的操作也能直接用
    Write-Host "$($_.SamAccountName) 的邮箱是: $($_.EmailAddress)"
}

这个方法的优势:

  • 原生ADUser对象,支持所有AD cmdlet的直接调用
  • 从AD服务器拉取的数据量最小,内存占用更低,性能最优
  • 无需额外转换对象格式,代码更简洁

方案2:如果必须用Select-Object(特殊场景)

如果你因为某些原因必须用Select-Object筛选(比如从其他非AD来源获取的对象),可以给自定义对象添加AD主体类型标识,让AD cmdlet能识别它:

# 先获取全量或部分属性,再用Select-Object保留所需属性,同时指定类型名称
$users = Get-ADUser -Filter * | Select-Object SamAccountName, DisplayName, EmailAddress -TypeName Microsoft.ActiveDirectory.Management.ADUser

# 此时传入Get-ADPrincipalGroupMembership即可正常工作
$users | ForEach-Object {
    $groups = Get-ADPrincipalGroupMembership $_
}

不过这个方法不如方案1可靠,因为自定义对象的方法和原生ADUser对象可能存在差异,建议优先用方案1。

为什么ExpandProperty不行?

-ExpandProperty SamAccountName会把属性值提取成纯字符串数组,丢失了所有其他属性和对象结构,只能用于只需要SamAccountName的场景,完全不符合你需要多属性+对象格式的需求。

关键提醒

你提到$users要用于多个命令,那保持原生ADUser类型是重中之重——所有AD cmdlet都是围绕这个类型设计的,用原生对象能避免后续所有兼容性问题,同时性能拉满,不用再频繁调用Get-ADUser重新获取数据。

内容的提问来源于stack exchange,提问作者James T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:49:35