I want to be able to retrieve my devices direct and nested group tokens, this can easily be achieved with the ActiveDirectory module installed but not all my devices have this and I do not want it installed.
Below is using the ActiveDirectory module which works.
$computer = Get-ADComputer -Identity "machinename"
$tokenGroups = (Get-ADObject -Identity $computer.DistinguishedName -Properties "tokenGroups").tokenGroups
$groupNames = $tokenGroups | ForEach-Object {
$sid = New-Object System.Security.Principal.SecurityIdentifier $_
$group = $sid.Translate([System.Security.Principal.NTAccount])
$group.Value
}
$groupNames
This is an example of doing it without the ActiveDirectory module but for a user:
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$groups = $currentUser.Groups
$groupNames = $groups | ForEach-Object {
$_.Translate([System.Security.Principal.NTAccount])
}
$groupNames
How do I do this for a machine for both direct and nested group membership? I have thought of importing the .dll that ActiveDirectory module uses rather then installing but I wanted to see if there is a cleaner way of doing this.
>Solution :
You can use a DirectorySearcher instance (type accessible via the PowerShell type accelerator [adsisearcher]) – this API is included with .NET Framework, so it’ll work even on machines with no RSAT tools installed.
# Create a searcher that specifically searches for its own account object
$searcher = [adsisearcher]"(&(objectCategory=computer)(sAMAccountName=${Env:COMPUTERNAME}$))"
# Find computer account object
if ($null -ne ($computer = $searcher.FindOne())) {
# re-bind and fetch the computed token groups from the server
$directoryEntry = $computer.GetDirectoryEntry()
$directoryEntry.RefreshCache(@('tokenGroups'))
# now we can access and parse the values
foreach ($tokenGroupBuffer in $directoryEntry.Properties['tokenGroups']) {
$SID = [System.Security.Principal.SecurityIdentifier]::new($tokenGroupBuffer,0)
$SID.Translate([System.Security.Principal.NTAccount])
}
}