Função avançada - Obtendo membros do grupo de segurança local de objetos de computador

1

Estou tentando compilar uma lista de grupos que têm acesso a um conjunto de computadores / servidores em nossa organização, com relação ao relatório de licença do MSDN.: - /

baseando meu trabalho na postagem do blog do Hey Scripting Guy sobre a associação ao grupo local: link

No entanto, preciso validar os membros em mais de um grupo em cada servidor. E aí vem a coisa estranha, que não me lembro de ver antes: ao adicionar parâmetros adicionais à seção de parâmetros da função, ela não consegue obter nenhum dos membros do grupo.

    function Test-LocalSecurityGroups {

        [CmdletBinding()]

        param(

        [parameter(
          ValueFromPipeline=$true,
          ValueFromPipelineByPropertyName=$true)]

            [string[]]$ComputerName = $env:COMPUTERNAME,

        [parameter(
          ValueFromPipelineByPropertyName=$true)]

            [string[]]$Group
        )

        BEGIN {

        Add-Type -AssemblyName System.DirectoryServices.AccountManagement

        $ctype = [System.DirectoryServices.AccountManagement.ContextType]::Machine

        }



        PROCESS{

            foreach ($Computer in $ComputerName) {
                Write-Verbose "Connecting to $Computer"
                $context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $Computer

                $idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName

                $group = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, 'Administrators')

                $group.Members | select @{N='Server'; E={$computer}}, @{N='Group Name'; E={$group.Name}}, @{N='Domain'; E={$_.Context.Name}}, samaccountName

            } # end foreach

        } # end PROCESS

    }

Aqui estão alguns exemplos de uso que não funcionam (nenhum resultado retornou).

PS D:\> Test-LocalSecurityGroups -ComputerName $env:COMPUTERNAME -Group "Administrator"
PS D:\> 

PS D:\> $env:COMPUTERNAME, "Computer1" | Test-LocalSecurityGroups
PS D:\>

PS D:\> $env:COMPUTERNAME, "Computer1" | Test-LocalSecurityGroups -Group "Administrators"
PS D:\>

No entanto, isso é mesmo sem fazer nada com a variável Group. Se eu comentar esta parte:

        [parameter(
          ValueFromPipelineByPropertyName=$true)]

            [string[]]$Group
        )

Funciona bem .. Então, alguém pode me explicar, por que isso está acontecendo? Eu tenho uma estrutura maior em torno de toda a função também, mas eu tenho o mesmo problema quando está isolado, então a minha conclusão é que ou eu estou esquecendo algo viável sobre powershell ou há algo conectado acontecendo ...

Não há erros, a lista de usuários está vazia. Eu recebo o mesmo problema ao executá-lo a partir do ISE do PowerShell, além de carregá-lo diretamente no shell diretamente (ambos os pontos de origem e colando a função no shell.

A alternativa é fazer isso com duas funções separadas e, em seguida, comparar os resultados em uma terceira função. Mas isso não é uma boa solução, agora é? :-p DRY FTW!

    
por mdavidsen 08.09.2014 / 11:15

1 resposta

2

Os nomes das variáveis do PowerShell não são sensíveis a maiúsculas e minúsculas .

Em outras palavras: $Group.Equals($group)

Dentro do bloco PROCESS , quando você atribui o objeto GroupPrincipal a $group , você está efetivamente tentando sobrescrever a variável de parâmetro $Group existente.

Basta alterar o nome da variável em linha e adicionar outro loop para iterar o nome de cada grupo:

foreach ($Computer in $ComputerName) {
    Write-Verbose "Connecting to $Computer"
    $context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $Computer

    $idtype = [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName

    foreach($groupName in $Group)
    {
        $groupPrincipal = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($context, $idtype, $groupName)

        $groupPrincipal.Members | select @{N='Server'; E={$computer}}, @{N='Group Name'; E={$groupPrincipal.Name}}, @{N='Domain'; E={$_.Context.Name}}, samaccountName
    }
} # end foreach
    
por 08.09.2014 / 13:54