Back in the old days (read: until about two years ago) my favorite scripting language was VBS.
With VBS it’s possible to query the Active Directory for group membership of the current user, for example very useful with logon scripts when creating mappings to file shares and/or printers.
But, as most people write logon scripts, you query the AD for every single thing… with a logon script this would mean that, for example, 500 users logon in one hour and the script queries the AD for group membership about 10 times per user. That accumulates to 5000 queries!
With PowerShell it is also possible to query the AD, like so:
function Get-MemberList($_groups)
{
$grp = [ADSI](“LDAP://” + $_groups)
Write-Output $grp.Name
if($_groups.memberof -ne $null)
{
foreach($member in $_groups.memberof)
{
Get_MemberList $member
}
}
}
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$root = $domain.GetDirectoryEntry()
$search = [System.DirectoryServices.DirectorySearcher]$root
$search.filter = “(samaccountname=$env:username)”
$result = $search.FindOne()
$groupList = @()
if($result -ne $null)
{
foreach($group in $result.Properties.memberof)
{
$groupList += Get-MemberList $group
}
}
else
{
Write-Host “The following username was not found: ” $env:Username
}if($groupList -contains “.NL.XS.Administration”)
{
# Insert your code here…
}if($groupList -contains “NL.XS.Support”)
{
# Insert your code here…
}
The larger you make the script, the heavier the attack on your domain controller will be.
For me, this is not something I want to happen. So, would there be a more elegant way of doing this?
Sure there is. You could query the AD and put the feedback in a variable.
Although this only happens one time, the script would still query the AD. Let’s go one step further…
When a user logs on, the client operating system queries the AD and gets a token back. In this token a lot of information is stored, among others the group membership. So, all the information requiered in the logon script is already available on the local system! Using that would be very domain controller friendly indeed…
So, let’s have a go, shall we?
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$WindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($CurrentUser)if($WindowsPrincipal.IsInRole(“NL.XS.Administration”))
{
\\FS01\groups\install\mappings\guimap.exe b: \\FS01\Administration
Get-Process guimap | ForEach-Object { $_.WaitForExit() }
}
if($WindowsPrincipal.IsInRole(“NL.XS.Support”))
{
\\FS01\groups\install\mappings\guimap.exe t: \\FS01\Support
}
This script will use the information available in the token on the local device, instead of sending a (or multiple) query to the Active Directory… so no attack on the domain controller