none
Descobrir membros de um subgrupo do AD RRS feed

  • Pergunta

  • Boa tarde

    Eu utilizo o scrip a seguir para descobrir os membros do grupo Administrator de uma lista de servidores. Minha duvida é, existe uma maneira desse script me mostrar os membros dos grupos encontrados dentro do grupo Administrator

    $servers=Get-Content c:\Groups\servers.txt
    $1=@()
    foreach($server in $servers){
    
            $group=[ADSI]"WinNT://$server/Administrators,group"
            $group.psbase.invoke('Members') | 
                ForEach-Object{
                                    
                       $props=@{    Server=$server
                                    Group=$group.Name[0] 
                                    Member=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                                    
                                                                    }
    
                       $1+=New-Object PsObject -Property $props 
                       $1 | Export-Csv  C:\Groups\Administrators.txt -encoding ascii
                                write-host "Ended at $(get-date)"                   
                                 }
    
          } invoke-item C:\Groups\Administrators.txt


     Grato


    • Editado Fábio JrModerator terça-feira, 25 de março de 2014 12:49 Formatação do código
    segunda-feira, 24 de março de 2014 17:20

Respostas

  • Boa tarde Fabio

    Segue alteração no Script que solucionou o problema:

    $servers=Get-Content c:\Groups\servers.txt
    $saida = "C:\Groups\Power Users.txt"
    $GrupoaserConsultado = "Power Users"
    
    "Servidor;Grupo Checado;Membros do Grupo;Tipo;Membros do Subgrupo" | Set-Content $saida
    
    function Get-Members($server, [string]$Grupo){
        $group=[ADSI]"WinNT://$server/$Grupo,group"
        $group.psbase.invoke('Members') | 
            ForEach-Object{
                $Nome=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                $Tipo=$_.GetType().InvokeMember('Class', 'GetProperty', $null,$_, $null)
                $Nome
                if ($Tipo -eq "Group"){
    
                "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                 $a="$server;$Grupo;$Nome;$Tipo"
                 get-adgroupmember $Nome | `
                 select-object @{e={$a}}, SamAccountName | add-content  $saida 
    
                 }else{
                   "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                    }
            }
    }
    
    foreach($server in $servers){
        Get-Members $server $GrupoaserConsultado
    } 
    invoke-item $saida

    At, Julio Castro

    • Marcado como Resposta JulioCastroSilva sexta-feira, 28 de março de 2014 18:21
    sexta-feira, 28 de março de 2014 15:52
  • Peguei o seu script e o transformei em uma função recursiva.

    $servers=Get-Content c:\Groups\servers.txt
    $saida = "C:\Groups\Administrators.txt"
    
    #$1=@()
    
    "Servidor;Nome;Membrode;Tipo" | Set-Content $saida
    
    function Get-Members($server, [string]$Grupo){
        $group=[ADSI]"WinNT://$server/$Grupo,group"
    
        $group.psbase.invoke('Members') | 
            ForEach-Object{
                $Nome=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                $Tipo=$_.GetType().InvokeMember('Class', 'GetProperty', $null,$_, $null)
                $Nome
                #é um grupo?
                if ($Tipo -eq "Group"){
                    #Se for grupo faz chamada recursiva
                    "$server;$Nome;$Grupo;$Tipo" | add-content $saida
                    Get-Members $server $Nome
                 }else{
                    #é um usuario, então adiciona na lista
                    
                    <# $props=@{    Server=$server
                            Group=$group.Name[0] 
                            Member=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                            Tipo=$Tipo 
                            }
                    $1+=New-Object PsObject -Property $props 
                    
                    #>
                    
                    "$server;$Nome;$Grupo;$Tipo" | add-content $saida
                    
                 }
    
            }
            
            #Return $1
    }
    
    
    
    foreach($server in $servers){
        Get-Members $server "Administradores"
    } 
    
    invoke-item C:\Groups\Administrators.txt

    Obs.: Não testei em mais de um servidor.


    Fábio de Paula Junior

    • Sugerido como Resposta Edinaldo Junior terça-feira, 25 de março de 2014 16:17
    • Marcado como Resposta JulioCastroSilva terça-feira, 25 de março de 2014 19:31
    terça-feira, 25 de março de 2014 15:20
    Moderador

Todas as Respostas

  • Peguei o seu script e o transformei em uma função recursiva.

    $servers=Get-Content c:\Groups\servers.txt
    $saida = "C:\Groups\Administrators.txt"
    
    #$1=@()
    
    "Servidor;Nome;Membrode;Tipo" | Set-Content $saida
    
    function Get-Members($server, [string]$Grupo){
        $group=[ADSI]"WinNT://$server/$Grupo,group"
    
        $group.psbase.invoke('Members') | 
            ForEach-Object{
                $Nome=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                $Tipo=$_.GetType().InvokeMember('Class', 'GetProperty', $null,$_, $null)
                $Nome
                #é um grupo?
                if ($Tipo -eq "Group"){
                    #Se for grupo faz chamada recursiva
                    "$server;$Nome;$Grupo;$Tipo" | add-content $saida
                    Get-Members $server $Nome
                 }else{
                    #é um usuario, então adiciona na lista
                    
                    <# $props=@{    Server=$server
                            Group=$group.Name[0] 
                            Member=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                            Tipo=$Tipo 
                            }
                    $1+=New-Object PsObject -Property $props 
                    
                    #>
                    
                    "$server;$Nome;$Grupo;$Tipo" | add-content $saida
                    
                 }
    
            }
            
            #Return $1
    }
    
    
    
    foreach($server in $servers){
        Get-Members $server "Administradores"
    } 
    
    invoke-item C:\Groups\Administrators.txt

    Obs.: Não testei em mais de um servidor.


    Fábio de Paula Junior

    • Sugerido como Resposta Edinaldo Junior terça-feira, 25 de março de 2014 16:17
    • Marcado como Resposta JulioCastroSilva terça-feira, 25 de março de 2014 19:31
    terça-feira, 25 de março de 2014 15:20
    Moderador
  • Boa tarde Fábio

    Obrigado por responder.

    Toda vez que o powershell tenta verificar os membros de um grupo encontrado dentro do grupo administrator ele me dá essa resposta:

    "Exception calling "Invoke" with "2" argument(s): "The group name could not be found.

    At C:\Groups\Administrators Groups\Descobrir membros do grupo Administrators dos servidores 2.ps1:9 char:5
    +     $group.psbase.invoke('Members') |
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : DotNetMethodException"

    O problema aqui é que o grupo existe. Porque será que ele não está achando ?

    terça-feira, 25 de março de 2014 16:44
  • Julio,

    Só consegui reproduzir o erro quando coloquei um nome de grupo que não existe. Verifique o idioma dos servidores onde o erro ocorre. Será que não estão em português e a pesquisa deveria ser feita por Administradores ao invés de Administrators? ou vice-versa?


    Fábio de Paula Junior

    terça-feira, 25 de março de 2014 18:21
    Moderador
  • Fabio,

    Toda minha estrutura de servidores é inglês.

    Eu acredito que encontrei o problema. Quando o script acha um grupo dentro do grupo Administrators, ele ao invés de "perguntar" para o AD quais são os membros desse grupo, ele está tentando obter essa informação da estação que está sendo consultada.

    Quando eu apontei o script para consultar o AD ele funcionou sem problemas. Você tem alguma ideia do que eu posso fazer agora?

    Grato


    terça-feira, 25 de março de 2014 18:42
  • Eu não tenho ambiente pra testar mas acredito que este link pode ser útil.

    Enumerate Local Group

    http://www.rlmueller.net/Enumerate%20Local%20Group.htm


    Fábio de Paula Junior

    terça-feira, 25 de março de 2014 19:19
    Moderador
  • Obrigado Fabio,

    O link que você me mandou é para VB. Eu preciso continuar em PowerShell.

    Vou pesquisar mais um pouco, eu acredito que se eu conseguir que quando o power shell achar um grupo dentro de outro grupo ele executar "Get-ADGroupMember", isolar o nome do objeto e listar no TXT, irei obter o resultado sem erros.

    Agradeço pelo seu script, com certeza ele será de grande ajuda.

    Grato.


    terça-feira, 25 de março de 2014 19:30
  • Julio,

    No mesmo link tem lá no final o script para PowerShell. Procure a linha abaixo.

    PSEnumLocalGroup.txt <<-- Click here to view or download the program


    Fábio de Paula Junior

    terça-feira, 25 de março de 2014 19:38
    Moderador
  • Boa tarde Fabio,

    Eu editei o codigo até o ponto que ele consegue mostrar os membros do subgrupo. Porem eu não estou conseguindo transportar a informação para o TXT. Você pode me ajudar?

     

    $servers=Get-Content c:\Groups\servers.txt
    $saida = "C:\Groups\Administrators.txt"
    
    "Servidor;Membrode;Nome;Tipo" | Set-Content $saida
    
    function Get-Members($server, [string]$Grupo){
        $group=[ADSI]"WinNT://$server/$Grupo,group"
        $group.psbase.invoke('Members') | 
            ForEach-Object{
                $Nome=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                $Tipo=$_.GetType().InvokeMember('Class', 'GetProperty', $null,$_, $null)
                $Nome
                if ($Tipo -eq "Group"){
    
    
                    #Se for grupo faz chamada recursiva
                    Get-ADGroupMember $Grupo -Recursive | select-object saMAccountName
    
                    "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                    
                    
                 }else{
                   "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                    }
            } 
    }
    
    foreach($server in $servers){
        Get-Members $server "ADministrators"
    } 
    invoke-item C:\Groups\Administrators.txt

     
    quarta-feira, 26 de março de 2014 19:42
  • Você tem que colocar o add-content $saida na frente do comando que te dá o resultado, não esqueça do pipeline "|".

    Tenta aí, qualquer coisa posta o código de novo.


    Fábio de Paula Junior


    quinta-feira, 27 de março de 2014 01:05
    Moderador
  • Boa tarde Fabio

    A linha de codigo fica assim:

    Get-ADGroupMember$Nome-Recursive|select-objectsaMAccountName|add-content  $saida

    Ela me lista os usários assim:

    Maquina;Administrators;Domain Admins;Group
    @{saMAccountName=User1}

    @{saMAccountName=User2}

    Duvida, tem como ele listar os usuário assim?

    Maquina;Administrators;Domain Admins;Group; @{saMAccountName=User1}

    Maquina;Administrators;Domain Admins;Group; @{saMAccountName=User2}

    Grato pela ajuda.

     
    quinta-feira, 27 de março de 2014 14:18
  • Utilizando o Get-ADGroupMember com a opção -Recursive ele já traz a lista de usuários que estão diretamente no grupo ou dentro de outro grupo, mas ele perde a informação de qual é o grupo a que pertence este usuário.

    Fábio de Paula Junior

    quinta-feira, 27 de março de 2014 16:26
    Moderador
  • Boa tarde Fabio

    Segue alteração no Script que solucionou o problema:

    $servers=Get-Content c:\Groups\servers.txt
    $saida = "C:\Groups\Power Users.txt"
    $GrupoaserConsultado = "Power Users"
    
    "Servidor;Grupo Checado;Membros do Grupo;Tipo;Membros do Subgrupo" | Set-Content $saida
    
    function Get-Members($server, [string]$Grupo){
        $group=[ADSI]"WinNT://$server/$Grupo,group"
        $group.psbase.invoke('Members') | 
            ForEach-Object{
                $Nome=$_.GetType().InvokeMember('Name', 'GetProperty', $null,$_, $null)
                $Tipo=$_.GetType().InvokeMember('Class', 'GetProperty', $null,$_, $null)
                $Nome
                if ($Tipo -eq "Group"){
    
                "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                 $a="$server;$Grupo;$Nome;$Tipo"
                 get-adgroupmember $Nome | `
                 select-object @{e={$a}}, SamAccountName | add-content  $saida 
    
                 }else{
                   "$server;$Grupo;$Nome;$Tipo" | add-content $saida
                    }
            }
    }
    
    foreach($server in $servers){
        Get-Members $server $GrupoaserConsultado
    } 
    invoke-item $saida

    At, Julio Castro

    • Marcado como Resposta JulioCastroSilva sexta-feira, 28 de março de 2014 18:21
    sexta-feira, 28 de março de 2014 15:52