Reputation: 2616
I am able to get the members of a local group using the following script :
$CompStat = Get-WmiObject win32_computersystem;
$Localhst = $CompStat.Name;
$Computer = [ADSI]('WinNT://'+$localhst+',computer');
$group = [ADSI]('WinNT://'+$Localhst+'/groupname,group');
$Members = @($group.psbase.Invoke("Members"));
$Members | ForEach-Object {$MemberNames += $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null);
Write-Output $MemberNames;
}
Similarly how to get the groups of a particular user?
Upvotes: 2
Views: 9836
Reputation: 3620
At the risk of earning me another necromancer-badge I'd like to provide some more up to date and more idiomatic code to answer the question.
Get-LocalGroup |
Where-Object { (Get-LocalGroupMember $_).name -eq "$env:COMPUTERNAME\$env:USERNAME" }
$env:USERNAME
can of course be replaced by any other username.
Using operators like -eq
or -match
with arrays is what makes the not so obvious part in the above example since they return arrays which - if empty - are an equivalent of $false
in a boolean context and $true
otherwise (the operator is applied to each item and the item gets part of the resulting array if the operator returns $true
):
@(1;2;3) -eq 2 # => @(2)
@(1;2;3) -eq 4 # => @()
@(1;2;3) -ge 2 # => @(2;3)
Another example of Powershell-array-magic that happens here is that a method that is called on an array object that is not a member of the array object is called on each item of that object and the return value is an array of the respective return values that are not $null
. So for example (Get-LocalGroup).sid.value
returns an array of strings like:
S-1-5-32-544
S-1-5-32-545
S-1-5-32-546
...
I hope this explains the (Get-LocalGroupMember $_).name
part in a digestable way.
All users and their groups:
Get-LocalUser |
ForEach-Object {
$nm = $_.name
[pscustomobject]@{
Name = $nm
Groups = Get-LocalGroup |
Where-Object { (Get-LocalGroupMember $_).name -contains "$env:COMPUTERNAME\$nm" } |
ForEach-Object name
}
}
Upvotes: 3
Reputation: 11
While writing some automation came up with this piece - getting explicit local groups for given user without traversing all groups available:
Get-GroupMembershipLocal([string] $UserName)
{
$strComputer = $Env:ComputerName
$User = [ADSI]("WinNT://$strComputer/$UserName,user")
$Groups = @()
$User.psbase.Invoke("groups") |foreach `
{
$groupname = [string] $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
$Groups += $groupname
}
return ,$Groups
}
$Groups = Get-GroupMembershipLocal "SomeUserName"
Write-Host ($Groups | Out-String)
It gets groups collection from user SomeUserName via ADSI WinNT (local), see the line: $User.psbase.Invoke("groups") in the middle. Last two lines provide example of getting & printing out results
Upvotes: 1
Reputation: 141
To get a list of global groups that a user is a member of you can use "net user username /dom". I don't know a direct way to display a given user's local group membership, but you could use the script that you already wrote to do it.
For user membership in local groups, I butchered a script found here: Users and Local Groups Report using Powershell?
$user = "insert test username"
$server="."
$computer = [ADSI]"WinNT://$server,computer"
$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
$groupname = $_.name
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") |
foreach {
$member = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
if ($member -eq $user)
{
write-host $groupname
}
}
}
It is not a good practice to directly put users into local groups. You should put users into global groups, then global groups into local or domain local groups, and then assign permissions to those local or domain local groups.
See for instance: http://en.wikipedia.org/wiki/AGDLP
Upvotes: 0