获取本地组每个成员的 SID

获取本地组每个成员的 SID

在运行 Windows 7 的 Active Directory 域成员上,我有一个本地组。它有用户和其他组作为成员:

在此处输入图片描述

我如何才能获取此本地组每个成员的 SID? 我知道 Sysinternals 实用程序获取Sid但似乎无法列举群组成员。

答案1

这是您应该能够使用的 Powershell 函数。我只在 Windows 10 上测试过它,但我认为它没有使用 Windows 7 中没有的任何东西。

Function Get-LocalGroupMembers  {

[Cmdletbinding()] 
Param( 
    [Parameter(Mandatory=$true)]
    [string]$GroupName
)

[adsi]$adsiGroup = "WinNT://$($env:COMPUTERNAME)/$GroupName,group"

$adsiGroup.Invoke('Members') | %{

    $username = $_.GetType().InvokeMember('Name','GetProperty',$null,$_,$null)
    $path = $_.GetType().InvokeMember('AdsPath','GetProperty',$null,$_,$null).Replace('WinNT://','')
    $class = $_.GetType().InvokeMember('Class','GetProperty',$null,$_,$null)
    $userObj = New-Object System.Security.Principal.NTAccount($username)
    $sid = $userObj.Translate([System.Security.Principal.SecurityIdentifier])

    [pscustomobject]@{
        Username = $username
        Type = $class
        SID = $sid
        Path = $path
    }

}

}

答案2

@Ryan Bolger 的解决方案基本有效,但是有一个问题,如果有两个帐户同名但域不同,则 SID 会重复,因为转换仅适用于用户名本身。下面是他们解决这个问题的函数的修改版本。

Function Get-LocalGroupMembers  {

[Cmdletbinding()] 
Param( 
    [Parameter(Mandatory=$true)]
    [string]$GroupName
)

[adsi]$adsiGroup = "WinNT://$($env:COMPUTERNAME)/$GroupName,group"

$Members = @()

$adsiGroup.Invoke('Members') | ForEach-Object{

    $username = $_.GetType().InvokeMember('Name','GetProperty',$null,$_,$null)
    $path = $_.GetType().InvokeMember('AdsPath','GetProperty',$null,$_,$null).Replace('WinNT://','')
    $class = $_.GetType().InvokeMember('Class','GetProperty',$null,$_,$null)
    $userObj = $null
    
    if ($path -notlike "*S-1-5*"){ #If the path does not contain a SID, then AD is reachable and we can translate successfully
        $Parts = $path.Split("/") 
        <#
            $Parts can look like:
            Local Account  - Domain, ComputerName, AccountName 
            Domain Account - Domain, AccountName 
        #>
        $Domain = $Parts[0]

        if ($Parts[1] -eq $env:COMPUTERNAME){ #Based on above comment, if arg 2 is the ComputerName, it's a local account
            $userObj = New-Object System.Security.Principal.NTAccount($username)

        }else{#Otherwise it's a domain account and we need to translate using the domain
            $userObj = New-Object System.Security.Principal.NTAccount($Domain, $username)
        }
        $sid = $userObj.Translate([System.Security.Principal.SecurityIdentifier])
    }else{ #Otherwise AD not reachable and the SID is just the username
        $sid = $username
    }

    $Members += [pscustomobject]@{
        Username = $username
        Type = $class
        SID = $sid
        Path = $path
    }
}   
return $Members
}

相关内容