Получить членов локальной группы: версия agnostic - PullRequest
0 голосов
/ 17 сентября 2018

Я нашел эту ветку , которая предлагает два основных подхода к получению членов локальной группы.

Это работает для меня во всех версиях powershell, но зависит от использования старой утилиты командной строки NET.

function Get-LocalGroupMembers() {
  param ([string]$groupName = $(throw "Need a name") )
  $lines = net localgroup $groupName
  $found = $false
  for ($i = 0; $i -lt $lines.Length; $i++ ) {
    if ( $found ) {
      if ( -not $lines[$i].StartsWith("The command completed")) {
        $lines[$i]
      }
    } elseif ( $lines[$i] -match "^----" ) {
      $found = $true;
    }
  }
}

Это работает для меня в PowerShell 2.0, но barfs в PS5.0 с Error while invoking GetType. Could not find member. Это только раздражает некоторые группы, включая Администраторов, что заставляет меня думать, что это какая-то функция безопасности, например, требовать повышенных привилегий, чтобы ДЕЙСТВИТЕЛЬНО иметь права администратора в сценарии.

Function Get-LocalGroupMembers
{
    Param(
        [string]
        $server = "."
    )
    Try
    {
        $computer = [ADSI]"WinNT://$( $Server ),computer"
        $computer.psbase.children | 
            where { 
                $_.psbase.schemaClassName -eq 'group' 
            } |
                ForEach {
                    $GroupName = $_.Name.ToString()
                    $group =[ADSI]$_.psbase.Path
                    $group.psbase.Invoke("Members") |
                        foreach {
                            $memberName = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) -replace "WinNT:", ""

                            $props = @{
                                "LocalGroup" = $GroupName
                                "MemberName" = $memberName
                            }

                            $obj = New-Object -TypeName psobject -Property $props
                            Write-Output $obj
                        } # foreach members
                } # foreach group
    }
    Catch
    {
        Throw
    }
}

Мне кажется, я где-то читал, что в PS5.1 наконец-то есть собственный CMDlet. Но я не могу зависеть от конкретной версии PS, мне нужно поддерживать все, от PS2.0 в Win7 и выше. Тем не менее, существует ли единственное решение, не зависящее от версии, которое не зависит от утилиты командной строки kludge? Или мне нужен код, который использует старый хак или новый CMDlet в зависимости от версии PS, на которой я работаю?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Вместо этого:

$memberName = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) -replace "WinNT:", ""

Вы можете попробовать это:

$memberName = ([ADSI]$_).InvokeGet("Name")
0 голосов
/ 17 сентября 2018

Итак, мне повезло с этим решением.

$hostname = (Get-WmiObject -computerName:'.' -class:Win32_ComputerSystem).name 
$wmiQuery = Get-WmiObject -computerName:'.' -query:"SELECT * FROM Win32_GroupUser WHERE GroupComponent=`"Win32_Group.Domain='$Hostname',Name='$group'`"" 
if ($wmiQuery -ne $null) {  
    :searchLoop foreach ($item in $wmiQuery) {  
       if (((($item.PartComponent -split "\,")[1] -split "=")[1]).trim('"') -eq $user) {
           $localGroup = $true
           break :searchLoop
        }
    }  
 }

Я еще не уверен, нравится ли мне этот слишком сложный IF против некоторых переменных, но функциональность есть и работает во всех версиях PS, не прибегая к командной строке, что и было целью. Обратите внимание, что это просто возвращает true, если пользователь является членом группы, и это все, что мне нужно. Другой код, который я разместил, предоставит список участников, который является основой для проверки, и я просто не модифицировал его, чтобы показать реальную конечную цель, поскольку проблема проявлялась без этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...