Como obter todos os grupos dos quais um usuário é membro?

135

O Get-ADGroupMembercmdlet do PowerShell retorna membros de um grupo específico. Existe um cmdlet ou propriedade para obter todos os grupos dos quais um usuário específico é membro?


Corrigi o meu erro: Get-Memberdeveria ser Get-ADGroupMember.

Primoz
fonte
A questão não está clara. Você pode reformulá-lo ou adicionar um exemplo?
Mohit Chakraborty
1
Consulte stackoverflow.com/questions/668321/… e technet.microsoft.com/en-us/library/dd315351.aspx . Tem certeza de que o Get-Member faz o que acha que faz?
Tiago2014
@Mohit Chakraborty Agora ficou mais claro?
Primoz
1
rapidamente você pode usar net user /domain username, verifique também outros métodos em Obter grupos nos quais um usuário é membro Usando o PowerShell
Mohamed

Respostas:

282

Get-ADPrincipalGroupMembership fará isso.

Get-ADPrincipalGroupMembership username | select name

name
----
Domain Users
Domain Computers
Workstation Admins
Company Users
Company Developers
AutomatedProcessingTeam
kstrauss
fonte
1
Isso me salvou de usar o método mais complicado e demorado de encontrar isso. Sabia que o PowerShell teria algo assim, mas não o encontraria em lugar nenhum. +1
Tim Alexander
7
Observe que isso depende do módulo ActiveDirectory estar disponível. Isso não necessariamente funcionará em uma máquina cliente em que você esteja executando um script do PowerShell ou em clientes de nível inferior. Se você quiser fazer isso, use esta solução .
Daniel.S
5
O erro acima estava causando erros ("O servidor não conseguiu processar a solicitação devido a um erro interno" - presumivelmente a funcionalidade não está disponível no servidor). get-aduser $username -Properties memberof | select -expand memberoffuncionou bem embora.
JohnLBevan
5
Se você estiver em uma estação de trabalho Windows 10 em vez de em um servidor, instale o RSAT a partir daqui e digite import-module activedirectoryna linha de comando do powershell; isso deve ser executado.
precisa
3
Se o módulo não estiver instalado: Install-WindowsFeature RSAT-AD-PowerShell
Preben Huybrechts
81

Linha única, sem necessidade de módulos, usa o usuário logado atual:

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

Parabéns a este artigo do vbs / powershell: http://technet.microsoft.com/en-us/library/ff730963.aspx

Canoas
fonte
5
Obrigado, eu aprecio esta versão sem módulos. Simplesmente alterei a variável de $env:usernamepara $usernamee configurei com $username = "testuser"para fazer facilmente a substituição de variáveis ​​por outras pesquisas de usuários.
projectdp
Apenas pesquisei meu caminho de volta aqui de novo! Ainda é útil em situações aleatórias em que as ferramentas do AD não estão disponíveis.
22417 Nathan
43

Uma alternativa mais concisa à postada por Canoas, para obter associação ao grupo para o usuário conectado no momento.

Me deparei com esse método nesta postagem do blog: http://www.travisrunyard.com/2013/03/26/auto-create-outlook-mapi-user-profiles/

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

Uma versão ainda melhor, que usa um regex para remover o guff do LDAP e deixa apenas os nomes dos grupos:

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

Mais detalhes sobre o uso do acelerador de tipo [ADSISEARCHER] podem ser encontrados no blog do cara do script: http://blogs.technet.com/b/heyscriptingguy/archive/2010/08/24/use-the-powershell-adsisearcher-type -accelerator-to-search-active-directory.aspx

Daniel.S
fonte
1
Ambos me dão o erro: Exceção ao chamar "FindOne" com "0" argumento (s): "O filtro samaccountname = pesquisa é inválido."
Dallas
Estranho .... Acabei de testar novamente, mas no Windows 7, em um ambiente completamente diferente, e funciona bem aqui também.
Daniel.S
Tentei novamente agora, ainda no Win 7, e funciona bem. Talvez eu tenha cometido um erro de digitação ao tentar isso pela primeira vez. Obrigado por adicionar a substituição para remover a floresta "bobo".
Dallas
2
Funciona muito bem, acrescente | Sort-Objectpara torná-lo ainda mais legível.
Martin Hollingsworth
31

À moda antiga do CMD:

net user mst999 /domain 
user4511672
fonte
1
ele também funciona em máquinas clientes sem ferramentas ad extra
Rast
4
Infelizmente - se os seus nomes grupos são longos (ou seja,> 21 caracteres), então ele irá truncar-los ...
kiltannen
aquele bate em todos os sentidos! Bravo
StayCool 15/05/19
24
(GET-ADUSER Identity USERNAME Properties MemberOf | Select-Object MemberOf).MemberOf
schmeckendeugler
fonte
Obrigado! isso funcionou. única desvantagem é o valor retornado é uma sequência.
shaiss
3
| O get-adgroup produzirá os objetos do grupo. Brilhante!
8DH
1
ou, use $ env: USERNAME, em vez de pegar o nome de usuário do usuário conectado no momento
Dave Lucre
6

Se você não conseguir que Get-ADPrincipalGroupMembership funcione, tente fazer logon como esse usuário e use.

$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$groups = $id.Groups | foreach-object {$_.Translate([Security.Principal.NTAccount])}
$groups | select *
andrew pate
fonte
Você não precisa fazer login como usuário se usar algo como$id = [Security.Principal.WindowsIdentity]("username")
Bitcoin Murderous Maniac
1
Isso reduz muito bem o one-liner [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | % {$_.Translate([Security.Principal.NTAccount])}.
alx9r 7/01
5

Obter associação ao grupo para um usuário:

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

Consulte Obter associação ao grupo para um usuário

Mas também veja os comandos gratuitos do PowerShell da Quest para o Active Directory .

[ Editar : O comando Get-ADPrincipalGroupMembership está incluído no Powershell desde a v2 com o Windows 2008 R2. Veja a resposta do kstrauss abaixo.]

tiago2014
fonte
2
Na verdade, há uma maneira mais fácil com cmdlets da Quest: Get-QADGroup -Contém Primoz
fenster
18
Isto já não é a melhor resposta, como Get-ADPrincipalGroupMembership agora está embutido no PowerShell
Rob canhão
1
Votado como negativo porque seria muito melhor usar Get-ADPrincipalGroupMembership. Eu gostaria de desfazer este voto negativo, mas não posso. Vou editar a resposta para apontar que a opção incorporada agora existe.
Abraham
4

Get-Memberé um cmdlet para listar os membros de um .NET object. Isso não tem nada a ver com a associação de usuário / grupo. Você pode obter a associação ao grupo do usuário atual da seguinte forma:

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
...

Se você precisar acessar as informações do grupo de usuários arbitrários, a sugestão @tiagoinu de usar os cmdlets do Quest AD é o melhor caminho a percorrer.

Keith Hill
fonte
4

Primeiro, importe o módulo activeedirectory:

import-module activedirectory

Em seguida, emita este comando:

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

Isso exibirá os membros do grupo especificado.

Jonathan Rioux
fonte
O OP pede o contrário. Obter todos os grupos dos quais um usuário especificado é membro.
8DH
4

Não há necessidade de scripts longos quando é um liner simples.

Comando QUEST

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

Comando do MS AD

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

Acho que o cmd do MS AD é mais rápido, mas algumas pessoas gostam mais do Quest.

Steve

Steve Adkin
fonte
4

Get-Member não é para obter associação ao grupo de usuários. Se você deseja obter uma lista de grupos aos quais um usuário pertence no sistema local, é possível:

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

Get-WMIObject -Query $query | Select Name

Na consulta acima, substitua DemoUser1 pelo nome de usuário desejado e o DomainName pelo nome do computador local ou nome de domínio.

Ravikanth
fonte
Esta consulta é muito demorado e responde muito lento quando há vários usuários e grupos no ambiente
randeepsp
Quem está editando a resposta, certifique-se de editá-la da maneira certa. Eu estava sugerindo que o OP substituísse DemoUser1 pelo nome de usuário que ele quisesse. E você mudou completamente esse significado.
ravikanth
4

Usar:

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

Isso canaliza a saída do comando em um arquivo CSV .

Dee
fonte
4

Isso deve fornecer os detalhes para o usuário atual. PowerShell não é necessário.

whoami /groups

Nayan
fonte
3

É apenas uma linha:

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

fim do :)

user4931356
fonte
A canalização para a select -expandproperty memberoftornará a saída um pouco mais legível / útil.
Ben Thul
2

Eu escrevi uma função do PowerShell chamada Get-ADPrincipalGroupMembershipRecursive. Ele aceita o DSN de uma conta de usuário, computador, grupo ou serviço. Ele recupera uma lista inicial de grupos do atributo memberOf da conta e verifica recursivamente as associações desses grupos. Código abreviado está abaixo. O código fonte completo com comentários pode ser encontrado aqui .

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
Brian Reich
fonte
2

O abaixo funciona bem:

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

Se você possui uma lista de usuários:

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

Get-QADUser -SamAccountName LoginID | % {$ _. MemberOf} | Get-QADGroup | selecione o nome

Sathish
fonte
1

Não foi possível fazer o seguinte funcionar para um usuário específico:

Get-ADPrincipalGroupMembership username

Ele gerou um erro que eu não estava disposto a solucionar.

No entanto, criei uma solução diferente usando o Get-ADUser. Eu gosto um pouco melhor porque se você não souber o nome da conta, poderá obtê-lo com base em um curinga no nome real do usuário. Basta preencher PartOfUsersName e ele desaparece.

#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
    }

Adereços enormes para o schmeckendeugler e o 8DH por me levarem a esta solução. +1 para vocês dois.

Adão
fonte
1

Embora existam muitas respostas excelentes aqui, há uma que eu estava procurando pessoalmente que estava faltando. Depois que eu descobri - pensei em publicá-lo caso queira encontrá-lo mais tarde ou, na verdade, ele consegue ajudar outra pessoa em algum momento:

Get-ADPrincipalGroupMembership username | Format-Table -auto

Uma segunda abordagem para apresentar isso é especificar as colunas individuais nas quais você está interessado, por exemplo:

Get-ADPrincipalGroupMembership username | select name, GroupScope, GroupCategory

Isso fornece a todos os grupos do AD aos quais o nome de usuário pertence - mas também apresenta todas as propriedades padrão de cada grupo formatadas como uma tabela.

O principal benefício que isso oferece é que você pode ver rapidamente quais são as listas de distribuição e quais são os grupos de segurança. Você pode ver rapidamente que são universais, que são DomainLocal e que são globais.
Por que você se importaria com este último pedaço?

  • O grupo universal é um grupo de segurança ou distribuição que contém usuários, grupos e computadores de qualquer domínio em sua floresta como membros. Você pode conceder direitos e permissões a grupos de segurança universal sobre recursos em qualquer domínio da floresta.
  • Grupo global é um grupo que pode ser usado em seu próprio domínio, em servidores membros e em estações de trabalho do domínio e em domínios confiáveis. Em todos esses locais, você pode conceder direitos e permissões a um grupo global e o grupo global pode se tornar um membro de grupos locais. No entanto, um grupo global pode conter contas de usuário que são apenas de seu próprio domínio.
  • Grupo local de domínio é um grupo de segurança ou distribuição que pode conter grupos universais, grupos globais, outros grupos locais de domínio de seu próprio domínio e contas de qualquer domínio da floresta. Você pode conceder direitos e permissões a grupos de segurança local do domínio em recursos que residem apenas no mesmo domínio em que o grupo local do domínio está localizado.
kiltannen
fonte
0
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
    }
}

Altere o valor de -SearchBase para refletir a UO da qual você precisa listar os usuários :)

Isso listará todos os usuários nessa UO e mostrará em quais grupos eles são membros.

Stephen Galvin
fonte
0

Get-ADPrincipalGroupMembership USERLOGON | selecione o nome

Jacob Fischlein
fonte
0
   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. 
Sunil Aher
fonte
0

Esta é a maneira mais simples de obter apenas os nomes:

Get-ADPrincipalGroupMembership "YourUserName"

# Returns distinguishedName : CN=users,OU=test,DC=SomeWhere GroupCategory : Security GroupScope : Global name : testGroup objectClass : group objectGUID : 2130ed49-24c4-4a17-88e6-dd4477d15a4c SamAccountName : testGroup SID : S-1-5-21-2114067515-1964795913-1973001494-71628

Adicione uma instrução select para aparar a resposta ou obter todos os usuários em uma UO em todos os grupos dos quais são usuários:

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

Stuart
fonte
0

Para obtê-lo recursivo, você pode usar:

<# 
    .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
DarkLite1
fonte
0

Quase todas as soluções acima usaram o ActiveDirecotrymódulo, que pode não estar disponível por padrão na maioria dos casos.

Eu usei o método abaixo. Um pouco indireto, mas serviu ao meu propósito.

Listar todos os grupos disponíveis

Get-WmiObject -Class Win32_Group

E, em seguida, liste os grupos aos quais o usuário pertence

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

A comparação pode ser feita através da verificação através do SIDs. Isso funciona para o usuário conectado. Por favor corrija-me se eu estiver errado. Completamente novo no PowerShell, mas precisava fazer isso por um compromisso de trabalho.

Ruifeng Ma
fonte
Se você estiver verificando um usuário que já é membro do grupo Administrador, inicie o PowerShell em "Executar como Administrador"; caso contrário, os grupos não serão listados corretamente para o segundo comando ... demorou um pouco para descobrir isso ... windows ...
Ruifeng Ma
0

Com entrada do usuário e formatação de saída sofisticada:

[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 
    } 
}
coinbird
fonte
0

Colocando isso aqui para referência futura. Estou no meio de uma migração de email. Preciso conhecer cada conta de usuário e seus respectivos membros do grupo, e também preciso conhecer cada grupo e seus respectivos membros.

Estou usando o bloco de código abaixo para gerar um CSV para a associação ao grupo de cada usuário.

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 ; `
  }

O processo de exportação para os grupos e seus respectivos membros foi um pouco complicado, mas o abaixo funciona. Os nomes dos arquivos de saída incluem o tipo de grupo. Portanto, os grupos de distribuição de e-mail necessários são / devem ser os grupos Universal e Global Distribution. Eu devo ser capaz de excluir ou mover os arquivos TXT resultantes de que não preciso.

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=""; `
  }
user208145
fonte
0

Estudar todos os comentários apresentados me deu um ponto de partida (obrigado por isso), mas me deixou com várias questões não resolvidas. Como resultado, aqui está a minha resposta. O snippet de código fornecido faz um pouco mais do que o solicitado, mas fornece informações úteis sobre depuração.

[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
ES44AC SD70MAC
fonte
Desculpe, esqueci de esclarecer. Faça isso primeiro: $ aduserDistinguishedName = "CN = nome, OU = ..." $ aduser = Get-ADUser -Identity $ aduserDistinguishedName -Properties *
ES44AC SD70MAC
0

Quando você não tem privilégios para consultar outros grupos de membros, mas tem o privilégio de consultar os membros do grupo, pode fazer o seguinte para criar um mapa de qual usuário tem acesso a quais grupos.

$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)
    }
}
Nadzzz
fonte