When writing PowerShell scripts it is sometimes necessary to know whether the user account running the script has local administrator privileges. A piece of code often used for this is:
([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
However, this code only returns true when run in an elevated context, so it is not really a test of whether the user has local administrator privilege, but whether the code is running in an elevated context.


The reason for this is that since Windows Vista and the introduction of User Account Control (UAC), an account that is a member of the local administrator group will get a split user access token. For most tasks, the account will use a filtered access token, which has the same rights as a standard user token. When a task is performed that requires elevation of privilege, the full access token will be used instead. Hence we get different results from the above command depending on which access token is being used.
Another way of ensuring that code is run elevated (since PowerShell 4) is to use the requires statement
#requires –runasadministrator
But I want to know if the user is a member of the local administrator group. One way to do that is simply get the username of the logged-on user from WMI, then use net localgroup:
$LoggedOnUsername = (Get-WmiObject -Class Win32_ComputerSystem -Property Username | Select -ExpandProperty Username).Split('\')[1] Net localgroup administrators | Select-String $LoggedOnUsername
And here is another method using WMI:
$userToFind = (Get-WmiObject -Class Win32_ComputerSystem -Property Username | Select -ExpandProperty Username).Split('\')[1] $administratorsAccount = Get-WmiObject Win32_Group -filter "LocalAccount=True AND SID='S-1-5-32-544'" $administratorQuery = "GroupComponent = `"Win32_Group.Domain='" + $administratorsAccount.Domain + "',NAME='" + $administratorsAccount.Name + "'`"" $user = Get-WmiObject Win32_GroupUser -filter $administratorQuery | select PartComponent |where {$_ -match $userToFind} $user
The problem with both of these methods is that they wont work with nested groups. So if a user is a member of a group that is a member of the local administrators group, rather than a direct member, I can’t use these methods.
It can be done, however.
If we go back to our original code we can see that we are creating a Windows Identity object for the current user. This object has a Claims property, that lists the rights that the user has, mostly in the form of local or domain users or groups. In the Value property of Claims, we can see the SIDs of those users and groups. This will include nested groups, because even though the user may not be a direct member of the group, they still have the rights of that group.

SIDs are not too friendly by themselves, so lets create a custom object and translate the SIDs to group names:
$Claims = @() [Security.Principal.WindowsIdentity]::GetCurrent().Claims | foreach { $Claim = New-Object psobject try { $SID = New-Object Security.Principal.SecurityIdentifier -ArgumentList $_.Value $SID = $SID.Translate([System.Security.Principal.NTAccount]) Add-Member -InputObject $Claim -MemberType NoteProperty -Name Claim -Value $SID Add-Member -InputObject $Claim -MemberType NoteProperty -Name SID -Value $_.Value Add-Member -InputObject $Claim -MemberType NoteProperty -Name Type -Value $_.Type.Split('/')[8] Add-Member -InputObject $Claim -MemberType NoteProperty -Name Properties -Value $_.Properties.Values $Claims += $Claim } Catch {} } $Claims | sort Claim

You’ll notice that the “BUILTIN\Administrators” group is listed in the Claims. This is the local Administrators group. Since the SID for this group is the same on all systems, we can search the Claims of the User Identity for this SID, and thereby determine if he or she is a member of the local Administrators group, either directly or indirectly.
We can either use the HasClaim() method:
$LoggedOnUsername = (Get-WmiObject -Class Win32_ComputerSystem -Property Username | Select -ExpandProperty Username).Split('\')[1] $ID = New-Object Security.Principal.WindowsIdentity -ArgumentList $LoggedOnUsername $ID.HasClaim('http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid','S-1-5-32-544')
This will return True or False based on whether the Identity has the claim of that group.
Or we can also simply do a text search on the Value property:
$LoggedOnUsername = (Get-WmiObject -Class Win32_ComputerSystem -Property Username | Select -ExpandProperty Username).Split('\')[1] $ID = New-Object Security.Principal.WindowsIdentity -ArgumentList $LoggedOnUsername $ID.Claims.Value.Contains('S-1-5-32-544')
To make it even simpler, we can do a one-liner using the GetCurrent() method:
[Security.Principal.WindowsIdentity]::GetCurrent().Claims.Value.Contains('S-1-5-32-544')
Now I can use this in a script:
if ([Security.Principal.WindowsIdentity]::GetCurrent().Claims.Value.Contains('S-1-5-32-544')) { "You got the power!" } Else { "You don't got the power :(" }
Have I got the power? Oh yeah 🙂