5

I needed to check whether the currently logged on user is an administrator however found that just using 'net localgroup administrators' was insufficient when it came to AD groups being a member of the administrators group.

[Edit:] It is easy to confuse administrator privilege in general with elevated privileges of a specific instance and I just want to highlight that this question/answer does not deal with process elevation status checking. The requirement is to generally ascertain whether or not a logged on user is an administrators group member. Much more common is the need to determine whether or not your script is running with administrator privileges. If this is what you require then please look here instead: Administrative privileges

In this particular case, there is a policy disabling the admin shares (ruling out a previous technique I used with Windows XP of testing for the existence of the admin share using \127.0.0.1\admin$ to determine if the current user is an administrator). [/Edit]

Below is the code I gathered and wrote see if the logged on user is an administrator.

I hope this helps someone else who requires the same thing that I did.

If anyone can provide a more elegant solution it would be appreciated!

wonea
  • 4,783
  • 17
  • 86
  • 139
Shaun
  • 366
  • 1
  • 6
  • 15
  • Hope what helps? What's your question? – Bill_Stewart Mar 18 '15 at 18:23
  • Hi Shaun, we're a question and answer site, and people are encouraged to answer their own questions when they know them. Can you re-phrase your initial post as a question, then post an answer? – Collin Mar 18 '15 at 18:26
  • Of course, elevation != member of local Administrators group. That is obvious. The real question is: Why do you need to determine if a user is a member of the local Administrators group but not check for elevation? – Bill_Stewart Apr 02 '15 at 21:17
  • Then why did you see fit to provide that answer to my question 'Powershell - check if logged on user is an administrator'? Frustratingly my earlier reply to this has been edited out. I need my program to check whether the user is a local administrator and quit if so because the payload of the program is a forced logoff after a period of inactivity which must exclude administrators. – Shaun Apr 03 '15 at 08:09

6 Answers6

15

As noted, membership in the local Administrators group is not sufficient to determine if the current process is elevated. You can test for elevation in PowerShell like this:

$elevated = ([Security.Principal.WindowsPrincipal] `
 [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • As noted, user was trying to figure out if account is an administrator not if script is running elevated. – bbodenmiller Jun 17 '20 at 06:21
  • 1
    Understood, this answer addresses a different scenario, but it's good information for those who really do need to check for elevation (which is the actual question 99% of the time). – Bill_Stewart Aug 12 '20 at 16:31
7

If you want to determine if the current user is a member of the local Administrators group (even if not elevated), here are some options.

$null -ne (whoami /groups /fo csv |
  ConvertFrom-Csv |
  Where-Object { $_.SID -eq "S-1-5-32-544" })

You can also use isadmin.exe (https://westmesatech.com/?page_id=23) and check for an exit code of 2 (member of administrators, but not enabled, hence not elevated).

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • I tested it using this:[string] $me = whoami /groups /fo csv | convertfrom-csv | where-object { $_.SID -eq "S-1-5-32-544" } If ($me.ToString().Contains("BUILTIN\Administrator")) { Write-Host "True"} Else {Write-Host "False"} – Shaun Apr 05 '15 at 09:35
  • 2
    I don't understand why you think you need to cast to string or check for `BUILTIN\Administrator`. If that's the solution that "works," then it seems like you need to do a better job explaining the actual problem you're trying to solve. – Bill_Stewart Apr 05 '15 at 13:08
  • Here's what I'm doing and it works fantastic, thanks! `(whoami /groups /fo csv | convertfrom-csv | where-object SID -eq 'S-1-5-32-544' | select 'Group Name') -match 'admin'` (returns true/false) – Max Cascone Nov 11 '21 at 19:54
  • You don't need the initial `(` or trailing `| Select 'Group Name') | -match 'admin'` part (in fact, matching by string `admin` will fail when the local `Administrators` group doesn't contain that string, so I wouldn't recommend a string match). See my updated answer. – Bill_Stewart Nov 12 '21 at 20:53
1

Using the SID:

([Security.Principal.WindowsIdentity]::GetCurrent().Groups | Select-String 'S-1-5-32-544')

Or using a "Well-known" security identifier name:

([Security.Principal.WindowsIdentity]::GetCurrent().Groups.IsWellKnown('BuiltinAdministratorsSid') -eq $true)

if you want to get all the SIDs and their names, please check this page: https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems

Fabian Mendez
  • 512
  • 5
  • 15
1

By looking for BUILTIN\Administrators in whoami /all

$output = whoami /all
$IsAdministrator = $false

foreach($line in $output) {
  if ($line -like "*BUILTIN\Administrators*") {
      $IsAdministrator = $true
      break;
   } 
} 

if ($IsAdministrator)
{
    Write-Host "The Computer contains Adminstrator priveledges" -ForegroundColor Black -BackgroundColor Green
} else {
    Write-Host "The Computer does not have Adminstrator priveledges" -ForegroundColor -BackgroundColor Red
}
Whiz
  • 11
  • 3
  • This will fail when the group is not named `Administrators` (i.e., in non-English versions of Windows or if the group has been renamed). See my answer that uses the SID (S-1-5-32-544). – Bill_Stewart Nov 16 '21 at 16:45
0

According to code from this blog, you can use this code, too:

# Get who I am
$Me = whoami.exe

# Get members of administrators group
$Admins = Get-LocalGroupMember -Name Administrators | 
          Select-Object -ExpandProperty name

# Check to see if this user is an administrator and act accordingly
if ($Admins -Contains $Me) {
  "$Me is a local administrator"
} 
else {
  "$Me is NOT a local administrator"
}
NJT145
  • 3
  • 2
-2

Thanks for the heads-up Bill - apologies, it was very late and I'm working 7-days/wk since Christmas.

Function IsCurrentUserAdmin( [String] $UserName )
# Returns true if current user in in the administrators group (directly or nested group) and false if not.
{
    $group = [ADSI] "WinNT://./Administrators,group" # http://stackoverflow.com/questions/16617307/check-if-an-account-is-a-member-of-a-local-group-and-perform-an-if-else-in-power
    $members = @($group.psbase.Invoke("Members"))
    $AdminList = ($members | ForEach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)})
    If ($AdminList -contains $UserName) {
        Return $true
    } Else {
        # Adapted $LocalUsers from http://www.powertheshell.com/finding-local-user-accounts-in-powershell-3-0/
        $LocalUsers = net user | Select-Object -Skip 4 
        $LocalUsers = ($LocalUsers | Select-Object -First ($LocalUsers.Count - 2)).Trim()
        ForEach ($Item In $AdminList) {
            If (($LocalUsers.Contains($Item)) -eq $false) {
                # Lookup each AD group that is a member of the local administrators group and see if the current user is a member and return true if found
                If (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole($Item) -eq $true) { Return $true }
            }
        }
        Return $false
    }
}

# Check if logged on user is an administrators group member and quit this program if so (to enable admins to manually install long-running software etc without logoff risk / disruption)

$UserName = ${Env:UserName}
[Bool] $AdminTest = IsCurrentUserAdmin $UserName
If ($AdminTest -eq $True) { 
    # Do something
} Else {
    # Do something else
}
Shaun
  • 366
  • 1
  • 6
  • 15
  • 2
    That's an unnecessary amount of code to determine if the current user is elevated (see my answer). – Bill_Stewart Mar 21 '15 at 14:54
  • Indeed you are correct Bill - however you have missed the point. Please re-read the question. Determining whether or not the current user session is elevated is out of scope for this article. – Shaun Mar 22 '15 at 18:10
  • You do not need to enumerate the members of the Administrators group to determine if the current user is an administrator. Testing for elevation is all you need to do (see my answer). Aside from this, your code will fail anyway if the Administrators group is not named "Administrators". – Bill_Stewart Mar 31 '15 at 14:45
  • 'Testing for elevation is all you need to do (see my answer).' is incorrect I'm afraid. Let me explain my specific requirements as it will better help explain why I have now marked my successfully independently tested solution as the answer to the problem 'Powershell: check if logged on user is an administrator'; despite it being down-voted and accompanied by a non-working alternative solution. Let me explain why I cannot use your (process elevation status checking aspect of checking for administrator privileges) solution for my issue. It fails for the default use case in my scenario. – Shaun Apr 02 '15 at 22:56
  • The Powershell program is to run on a Windows 7 x64 computer that has User Account Control (UAC) enabled that will be used by both users and administrators. If you are wondering why I need this it is because the wider requirement is for the program to forcibly log users off after a period of keyboard and mouse inactivity but not affect administrators. – Shaun Apr 02 '15 at 22:57
  • It is frequently found that users "reserve" then leave a machine (that is against policy) by creating and running in Presentation Mode a Microsoft Powerpoint presentation with the message 'be right back or BRB' in a (usually successful until caught by staff) bid to prevent another users from making use of the machine. This technique also successfully prevents the GPO enforced screen-saver that forces logoff at 15 minutes of inactivity from running. The program needs to run after logon but quit if the user is an administrator. – Shaun Apr 02 '15 at 22:57
  • Each minute the program monitors the time elapsed since the keyboard or mouse was last operated. The administrators will mostly be using domain accounts that are members of the Administrators group by virtue of a nested group membership of the Administrators local group. As a managed platform this name is guaranteed so I can safely make assumptions. – Shaun Apr 02 '15 at 22:58
  • Nested group membership of the Administrators local group means that the administrators userID does not appear directly in the Administrators group. The program is running with UAC enabled but will not be running with elevated privileges. It is the process non-elevated privilege status that is reason why your proposed solution fails in my case and therefore cannot be marked as the correct answer to the question 'Powershell: check if logged on user is an administrator'. – Shaun Apr 02 '15 at 22:59
  • A policy setting disabling the administrative shares exists (ruling out a previous technique I used in XP of testing for the existence of the admin share to determine if the current user is an administrator) so I had to look for a new solution. I couldn't find anything on the internet that could reliably detect if the logged on user is an administrator in this situation so had to resort to writing my own solution. This question was created to share my solution because as I say, I couldn't find anything else to do it. – Shaun Apr 02 '15 at 22:59
  • I'm sure there are much more elegant solutions out there which is why I had intended to leave the question formally unanswered until now - but since you down-voted the only working proposed solution I felt the need to clarify the situation to make things right as they should be as mine is to date the only workable solution. – Shaun Apr 02 '15 at 23:00
  • On your computer, when UAC is enabled and you are logged in with a domain user account that is a member of the administrators group by in-direct membership, please tell me Bill, when you run your solution inside a non-elevated powershell window, does it return that the user is an administrator? I ask because this scenario is critical as it represents the actual use case here and is therefore absolutely why you need to either undo the down-vote or leave it standing but only if accompanied with an alternative solution that actually works to 'check if logged on user is an administrator' in PoSh. – Shaun Apr 02 '15 at 23:01
  • I cannot think of a more succint and accurate way to phrase the question. I have to make reference to the AD group side of things because this is the crux of the problem of checking if the logged on user is an administrator and I am confined to 150 characters in the title. – Shaun Apr 02 '15 at 23:01
  • I think the source of confusion may be coming from the words chosen to make the call ..."IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator" as it implies that the check is for whether the user a member of the built in role "administrator". The reality though is that your proposal is susceptible to failure as a method to check that the logged on user is an administrator when UAC is enabled and the process is not elevated and I need the code to work in all UAC modes. – Shaun Apr 02 '15 at 23:01
  • I appreciate the work you do for fellow users and don't want to appear ungrateful. I just need to set the record straight as I have failed to clarify from the outset that the code needs to work in all UAC modes for which I apologise for the inconvenience caused. – Shaun Apr 02 '15 at 23:02
  • As a parting note, I just had a brainwave and figured that I can query gpresult /R more easily as that expands nested AD groups in its output. That ought to be more elegant than my first proposed solution! Right, I have some work to do! – Shaun Apr 02 '15 at 23:03
  • 1
    If you are asking whether someone is a member (directly or indirectly) of the local Administrators group regardless of whether they're elevated, then rephrase and ask this specific question. – Bill_Stewart Apr 03 '15 at 14:57