如何获取用户所属的所有组?

PowerShell 的 Get-ADGroupMembercmdlet 返回特定组的成员。是否有一个 cmdlet 或属性来获取特定用户所属的所有组?


我修正了我的错误: Get-Member应该是 Get-ADGroupMember

1340939 次浏览

获取用户的组成员资格:

$strUserName = "Primoz"
$strUser = get-qaduser -SamAccountName $strUserName
$strUser.memberof

参见 获取用户的组成员资格

还可以看探索的 用于 ActiveDirectory 的免费 PowerShell 命令

[ 剪辑: 自从 Windows 2008 r 2版本以来,Powershell 就包含了 校长小组成员命令。请参阅下面 kstrauss 的回答。]

Get-Member是一个 cmdlet,用于列出。NET object.这与用户/组成员资格无关。您可以像下面这样获得当前用户的组成员资格:

PS> [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups |
Format-Table -auto


BinaryLength AccountDomainSid    Value
------------ ----------------    -----
28 S-1-5-21-...        S-1-5-21-2229937839-1383249143-3977914998-513
12                     S-1-1-0
28 S-1-5-21-...        S-1-5-21-2229937839-1383249143-3977914998-1010
28 S-1-5-21-...        S-1-5-21-2229937839-1383249143-3977914998-1003
16                     S-1-5-32-545
...

如果您需要访问任意用户的组信息,那么@tiagoinu 建议使用 Quest AD cmdlet 是更好的方法。

Get-Member 不是用来获取用户的组成员资格的。如果希望获取用户在本地系统上所属组的列表,可以通过以下方式实现:

$query = "ASSOCIATORS OF {Win32_Account.Name='DemoUser1',Domain='DomainName'} WHERE ResultRole=GroupComponent ResultClass=Win32_Account"


Get-WMIObject -Query $query | Select Name

在上面的查询中,将 DemoUser1替换为所需的用户名,将 DomainName 替换为本地计算机名或域名。

(GET-ADUSER –Identity USERNAME –Properties MemberOf | Select-Object MemberOf).MemberOf

首先,导入 ActiveDirectory 模块:

Import-Module ActiveDirectory

然后下达这个命令:

Get-ADGroupMember -Identity $group | foreach-object {
Write-Host $_.SamAccountName
}

这将显示指定组的成员。

Get-ADPrincipalGroupMembership 将执行此操作。

Get-ADPrincipalGroupMembership username | select name


name
----
Domain Users
Domain Computers
Workstation Admins
Company Users
Company Developers
AutomatedProcessingTeam
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=Users,DC=domain,DC=local" -Filter * | foreach-object {
write-host "User:" $_.Name -foreground green
Get-ADPrincipalGroupMembership $_.SamAccountName | foreach-object {
write-host "Member Of:" $_.name
}
}

更改 -SearchBase 的值以反映您需要列出来自:)的用户的 OU

这将列出该 OU 中的所有用户,并向您显示他们是哪些组的成员。

我编写了一个名为 Get-ADPrincipalGroupMembershipRecursive 的 PowerShell 函数。它接受用户、计算机、组或服务帐户的 DSN。它从帐户的 memOf 属性中检索组的初始列表,然后递归地检查这些组的成员关系。缩写代码如下。完全 带注释的源代码可以在这里找到

function Get-ADPrincipalGroupMembershipRecursive( ) {


Param(
[string] $dsn,
[array]$groups = @()
)


$obj = Get-ADObject $dsn -Properties memberOf


foreach( $groupDsn in $obj.memberOf ) {


$tmpGrp = Get-ADObject $groupDsn -Properties memberOf


if( ($groups | where { $_.DistinguishedName -eq $groupDsn }).Count -eq 0 ) {
$groups +=  $tmpGrp
$groups = Get-ADPrincipalGroupMembershipRecursive $groupDsn $groups
}
}


return $groups
}


# Simple Example of how to use the function
$username = Read-Host -Prompt "Enter a username"
$groups   = Get-ADPrincipalGroupMembershipRecursive (Get-ADUser $username).DistinguishedName
$groups | Sort-Object -Property name | Format-Table

Get-QADUser-SamAccountName LoginID |% { $_. MemberOf } | Get-QADGroup | select name

Get-ADPrincipalGroupMembership USERLOGON | select name

单行,不需要模块,使用当前登录用户:

(New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf

这篇 vbs/powershell 文章值得称赞: http://technet.microsoft.com/en-us/library/ff730963.aspx

与 Canoas 发布的方法相比,这种方法更简洁,可以为当前登录的用户获得组成员资格。

我在这篇博客文章 http://www.travisrunyard.com/2013/03/26/auto-create-outlook-mapi-user-profiles/中发现了这个方法

([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().Properties.memberof

更好的版本使用正则表达式去掉 LDAP 的废话,只留下组名:

([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().Properties.memberof -replace '^CN=([^,]+).+$','$1'

关于使用[ ADSISEARCHER ]类型加速器的更多细节可以在脚本人的 blog: http://blogs.technet.com/b/heyscriptingguy/archive/2010/08/24/use-the-powershell-adsisearcher-type-accelerator-to-search-active-directory.aspx上找到

   Get-ADUser -Filter { memberOf -RecursiveMatch "CN=Administrators,CN=Builtin,DC=Fabrikam,DC=com" } -SearchBase "CN=Administrator,CN=Users,DC=Fabrikam,DC=com"  -SearchScope Base
## NOTE: The above command will return the user object (Administrator in this case) if it finds a match recursively in memberOf attribute.

这是获取名字最简单的方法:

Get-ADPrincipalGroupMembership "YourUserName"

# 归来 名称: CN = 用户,OU = 测试,DC = 某处 群组类别: 安全性 GroupScope: Global 群组范围: 全球 名称: testGroup ObjectClass: group ObjectGUID: 2130ed49-24c4-4a17-88e6-dd4477d15a4c SamAccountName: testGroup SID: S-1-5-21-2114067515-1964795913-1973001494-71628

添加一个 select 语句来修剪响应,或者为 OU 中的每个用户获取他们所属的每个组:

Foreach ($user in (get-aduser-SearchScope Subtree-SearchBase $oupath-filter *-Properties samAccountName,MemberOf | select samAccountName)){ Get-ADPrincipalGroupMembership $user.samAccountName | select name }

不需要长脚本时,它是一个简单的一行程序. 。

任务指挥部

(Get-QADUser -Identity john -IncludedProperties MemberOf | Select-Object MemberOf).MemberOf

司令部

(GET-ADUSER –Identity john –Properties MemberOf | Select-Object MemberOf).MemberOf

我发现 MS AD cmd 更快,但是有些人更喜欢 Quest。

史蒂夫

来自 CMD 的老派说法:

net user mst999 /domain

下面的方法很有效:

get-aduser $username -Properties memberof | select -expand memberof

如果你有一个用户列表:

$list = 'administrator','testuser1','testuser2'
$list | `
%{
$user = $_;
get-aduser $user -Properties memberof | `
select -expand memberof | `
%{new-object PSObject -property @{User=$user;Group=$_;}} `
}

我无法让下面的内容为特定用户工作:

Get-ADPrincipalGroupMembership username

它抛出了一个我不愿意解决的错误。

然而,我想出了一个不同的解决方案使用 Get-ADUser。我更喜欢它一点,因为如果你不知道帐户名称,然后你可以得到它的基础上对用户的实际名称通配符。只要填写 PartOfUsersName就可以了。

#Get the groups that list of users are the member of using a wildcard search


[string]$UserNameLike = "*PartOfUsersName*" #Use * for wildcards here
[array]$AccountNames = $(Get-ADUser -Filter {Name -like $UserNameLike}).SamAccountName


ForEach ($AccountName In $AccountNames) {
Write-Host "`nGETTING GROUPS FOR" $AccountName.ToUpper() ":"
(Get-ADUser -Identity $AccountName -Properties MemberOf|select MemberOf).MemberOf|
Get-ADGroup|select Name|sort name
}

非常感谢 Schmeckendeugler 和8DH 帮我找到了这个解决方案,你们两个 + 1。

只有一句话:

(get-aduser joe.bloggs -properties *).memberof

结束:)

用途:

Get-ADPrincipalGroupMembership username | select name | export-CSV username.csv

这将命令的输出传送到一个 CSV文件中。

要使其递归,可以使用:

<#
.SYNOPSIS
Get all the groups that a user is MemberOf.


.DESCRIPTION
This script retrieves all the groups that a user is MemberOf in a recursive way.


.PARAMETER SamAccountName
The name of the user you want to check #>


Param (
[String]$SamAccountName = 'test',
$DomainUsersGroup = 'CN=Domain Users,CN=Users,DC=domain,DC=net'
)




Function Get-ADMemberOf {
Param (
[Parameter(ValueFromPipeline)]
[PSObject[]]$Group,
[String]$DomainUsersGroup = 'CN=Domain Users,CN=Users,DC=grouphc,DC=net'
)
Process {
foreach ($G in $Group) {
$G | Get-ADGroup | Select -ExpandProperty Name
Get-ADGroup $G -Properties MemberOf| Select-Object Memberof | ForEach-Object {
Get-ADMemberOf $_.Memberof
}
}
}
}




$Groups = Get-ADUser $SamAccountName -Properties MemberOf | Select-Object -ExpandProperty MemberOf
$Groups += $DomainUsersGroup
$Groups | Get-ADMemberOf | Select -Unique | Sort-Object

几乎上述所有解决方案都使用 ActiveDirecotry模块,在大多数情况下,这个模块在默认情况下可能不可用。

我使用了下面的方法。有点间接,但达到了我的目的。

列出所有可用的组

Get-WmiObject -Class Win32_Group

然后列出用户所属的组

[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups

然后可以通过 SIDs检查进行比较。这适用于登录用户。如果我说错了,请纠正我。对 PowerShell 来说完全是新的,但是为了工作承诺必须完成这个任务。

具有用户输入和奇特的输出格式:

[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[Parameter(Mandatory = $True)]
[String]$UserName
)
Import-Module ActiveDirectory
If ($UserName) {
$UserName = $UserName.ToUpper().Trim()
$Res = (Get-ADPrincipalGroupMembership $UserName | Measure-Object).Count
If ($Res -GT 0) {
Write-Output "`n"
Write-Output "$UserName AD Group Membership:"
Write-Output "==========================================================="
Get-ADPrincipalGroupMembership $UserName | Select-Object -Property Name, GroupScope, GroupCategory | Sort-Object -Property Name | FT -A
}
}

如果您没有查询其他成员组的权限,但是您确实有查询组成员的权限,则可以执行下列操作来构建哪个用户可以访问哪些组的映射。

$groups = get-adgroup -Filter * | sort name | select Name
$users = @{}
foreach($group in $groups) {
$groupUsers = @()
$groupUsers = Get-ADGroupMember -Identity $group.Name | Select-Object SamAccountName
$groupUsers | % {
if(!$users.ContainsKey($_.SamAccountName)){
$users[$_.SamAccountName] = @()
}
($users[$_.SamAccountName]) += ($group.Name)
}
}

把这个放在这里,以备将来参考。我正在处理电子邮件迁移。我需要知道每个用户帐户及其各自的组成员,也需要知道每个组及其各自的成员。

我使用下面的代码块为每个用户的组成员输出一个 CSV。

Get-ADUser -Filter * |`
ForEach-Object { `
$FileName = $_.SamAccountName + ".csv" ; `
$FileName ; `
Get-ADPrincipalGroupMembership $_ | `
Select-Object -Property SamAccountName, name, GroupScope, GroupCategory | `
Sort-Object -Property SamAccountName | `
Export-Csv -Path $FileName -Encoding ASCII ; `
}

这些组及其各自成员的导出过程有点复杂,但下面的方法是可行的。输出文件名包括组的类型。因此,我需要的电子邮件分发组是/应该是通用分发组和全球分发组。我应该能够只删除或移动结果的 TXT 文件,我不需要。

Get-ADGroup -Filter * | `
Select-Object -Property Name, DistinguishedName, GroupScope, GroupCategory | `
Sort-Object -Property GroupScope, GroupCategory, Name | `
Export-Csv -Path ADGroupsNew.csv -Encoding ASCII


$MyCSV = Import-Csv -Path .\ADGroupsNew.csv -Encoding ASCII


$MyCSV | `
ForEach-Object { `
$FN = $_.GroupScope + ", " + $_.GroupCategory + ", " + $_.Name + ".txt" ; `
$FN ; `
Get-ADGroupMember -Identity $_.DistinguishedName | `
Out-File -FilePath $FN -Encoding ASCII ; $FN=""; `
}

如果您不能让 Get-ADPrincipalGroupMembership 为您工作,您可以尝试以该用户的身份登录,然后使用。

$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$groups = $id.Groups | foreach-object {$_.Translate([Security.Principal.NTAccount])}
$groups | select *

研究所有提出的意见给了我一个起点(谢谢这样) ,但留给我几个未解决的问题。因此,这里是我的答案。提供的代码片段比要求的要多一点,但它提供了有用的调试信息。

[array] $script:groupsdns = @()
function Get-ADPrincipalGroupMembershipRecursive()
{
Param( [string] $dn, [int] $level = 0, [array] $groups = @() )


#if(($groupsdns | where { $_.DistinguishedName -eq $dn }).Count -ne 0 ) { return $groups } # dependency on next statement
#$groupsdns += (Get-ADObject $dn -Properties MemberOf) # Get-ADObject cannot find an object with identity
if ($script:groupsdns.Contains($dn)) { return $groups }
$script:groupsdns += $dn
$mo = $Null
$mo = Get-ADObject $dn -Properties MemberOf # Get-ADObject cannot find an object with identity
$group = ($dn + " (" + $level.ToString())
if ($mo -eq $Null) { $group += "!" }
$group += ")"
$groups += $group
foreach( $groupdn in $mo.MemberOf )
{
$groups = Get-ADPrincipalGroupMembershipRecursive -dn $groupdn -level ($level+1) -groups $groups
}
if ($level -le 0)
{
$primarygroupdn = (Get-ADUser -Identity $dn -Properties PrimaryGroup).PrimaryGroup
$groups = Get-ADPrincipalGroupMembershipRecursive -dn $primarygroupdn -level ($level+1) -groups $groups
}
return $groups
}
$adusergroups = Get-ADPrincipalGroupMembershipRecursive -dn $aduser.DistinguishedName
$adusergroups | ft -AutoSize | `
Out-File -Width 512 Get-ADPrincipalGroupMembershipRecursive.txt #-Append #-Wrap # | Sort-Object -Property Name

虽然这里有很多很好的答案,但是有一个我个人一直在寻找的答案却不见了。一旦我弄明白了——我想我应该把它贴出来,以防我以后想找到它,或者它在某些时候确实帮助了其他人:

Get-ADPrincipalGroupMembership username | Format-Table -auto

第二种方法是指定您感兴趣的单个列,例如:

Get-ADPrincipalGroupMembership username | select name, GroupScope, GroupCategory

这给出了用户名所属的所有 AD 组,但也显示了每个组的所有默认属性,这些属性被很好地格式化为一个表。

这样做的主要好处是,您可以一目了然地看到哪些是通讯组列表,哪些是安全组。您可以进一步一目了然地看到哪些是 Universal,哪些是 DomainLocal,哪些是 Global。
你为什么关心这最后一点?

  • 通用组是一个安全或通讯组,其中包含 来自其林中的任何域的用户、组和计算机,作为 成员。您可以给予全球安全组织权利和 对林中任何域中的资源的权限。
  • 全局组是一个可以在其自己的域中以成员身份使用的组 服务器和域的工作站中,以及在信任域中。 在所有这些位置中,您可以赋予全局组权限和 权限和全局组可以成为本地组的成员。 但是,全局组可以包含仅来自 它自己的领域。
  • 域本地组是一个安全或通讯组,它可以 包含泛群、全局群、其他域局部群 从其自己的域,并从森林中的任何域帐户。您 可以赋予域本地安全组对 只驻留在本地域的同一域中的资源 小组的位置。

这将为您提供当前用户的详细信息。不需要 Powershell。

whoami /groups

我使用这个简单的 oneliner 递归地搜索用户所属的所有组:

Get-ADPrincipalGroupMembership $UserName | foreach-object { Get-ADPrincipalGroupMembership $_.SamAccountName | select SamAccountName }

为了筛选这些组,以确定 user 是否是某个特定组的成员,我使用以下方法:

if ( Get-ADPrincipalGroupMembership $UserName | foreach-object { Get-ADPrincipalGroupMembership $_.SamAccountName | select SamAccountName } | where-object {$_.SamAccountName -like "*$Groupname*"} ) { write-host "Found" } else { write-host "not a member of group $Groupname" }

对于本地用户和组(即不在活动目录) ,如果你不想,或不允许,或不能安装 RSAT 和/或 Install-WindowsFeature RSAT-AD-PowerShell和/或 import-module activedirectory,那么这里有一个纯粹的,预安装 Powershell (5.1 +)的方式来做到这一点。

(注意: 下面使用的 Get-LocalGroup*只提供 Powershell v5.1及以上版本。)... v5.1与2016年8月2日的 Windows 10周年更新一起在 Windows Server 2016中发布。或 Windows 7、 Windows 服务器2008、 Windows Server 2008 R2、 Windows 服务器2012和 Windows 服务器2012 r2于2017年1月19日发布。”(维基百科)

$username = "user002"
Get-LocalGroup | ForEach-Object {
# the usernames are returned in the string form "computername\username"
if (Get-LocalGroupMember -Group $_ | Where-Object name -like "*\$username") {
$_.name
}
}

输出示例:

Administrators
Users
(Get-ADUser $env:username -Properties MemberOf).MemberOf | % {$_.split(",")[0].replace("CN=","")}


Domain Users
Domain Computers
Workstation Admins
Company Users
Company Developers
AutomatedProcessingTeam