Назад | Перейти на главную страницу

Расширенная функция - получение членов локальной группы безопасности компьютерных объектов

Я пытаюсь составить список групп, которые имеют доступ к набору компьютеров / серверов в нашей организации, что касается отчетов о лицензиях MSDN ..: - /

основываю свою работу на записи блога Hey Scripting Guy о членстве в локальной группе: http://blogs.technet.com/b/heyscriptingguy/archive/2013/10/27/the-admin-s-first-steps-local-group-membership.aspx

Однако мне нужно проверить участников более чем в одной группе на каждом сервере. И вот неловкость, которую я не могу вспомнить раньше: при добавлении дополнительных параметров в раздел параметров функции невозможно получить ни одного из членов группы.

    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

    }

Вот несколько примеров использования, которое не работает (никакого результата не было):

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:\>

Однако это даже без НИЧЕГО не делая с переменной Group. Если я закомментирую эту часть:

        [parameter(
          ValueFromPipelineByPropertyName=$true)]

            [string[]]$Group
        )

Работает нормально .. Итак, может ли кто-нибудь мне объяснить, почему это происходит? У меня есть более обширная структура вокруг всей функции, но у меня такая же проблема, когда она изолирована, поэтому я делаю вывод, что либо я забываю что-то жизнеспособное о PowerShell, либо что-то происходит в проводном соединении ...

Ошибок нет, список пользователей просто пустой. У меня такая же проблема при запуске из PowerShell ISE, а также при прямой загрузке в оболочку напрямую (как получение точек, так и вставка функции в оболочку.

Альтернативный вариант - сделать это с двумя отдельными функциями, а ЗАТЕМ сравнить результаты в третьей функции. Но это действительно не лучшее решение, не так ли? :-p DRY FTW!

Имена переменных PowerShell: нечувствительный к регистру.

Другими словами: $Group.Equals($group)

В рамках PROCESS блок, когда вы назначаете GroupPrincipal Возражать $group, вы фактически пытаетесь перезаписать существующий $Group переменная параметра.

Просто измените имя встроенной переменной и добавьте еще один цикл для перебора каждого имени группы:

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