Search This Blog

Monday, August 14, 2023

How to check if powershell is running as administrator with elevated privileges

How to check if powershell is running as administrator with elevated privileges

In case it's not clear from the title, I am referring to the following method of launching PowerShell under elevated security privileges, by  a user with administrative rights.  This allows you to run commands that otherwise wouldn't be allowed even if you are a member of administrators group.











And if you are running  a non-interactive PowerShell script through a Windows or SQL Server scheduled job, or even from a batch file, you can use the PowerShell "Start-Process -Verb RunAs" or the old PsExec utility to start an elevated session.

What I want to show here though is how inside your PowerShell script, you can programmatically determine whether it is launched with "Run as administrator" option.

Here is the code, that I put in the beginning whenever I need to check before going any further inside a script if it has the elevated permissions to perform tasks and/or make whatever configuration changes I wrote the script for:

if(-Not (([System.Security.Principal.WindowsIdentity]::GetCurrent()).Owner -eq "S-1-5-32-544"))
{
    Throw 'Error: Powershell must be launched in elevated privileges mode'
}


Now if you are curious for explanation:

What is "S-1-5-32-544"?

It is known as one of the well-known, universal SIDs in Windows world.  It belongs to the BUILTIN\Administrators group and this SID value is same on every Windows computer.  May be it would have made more sense to check for the name BUILTIN\Administrators instead of the binary SID value, however well-know and universal. And to achieve that I could go through trouble of writing additional lines of code to translate the SID into BUILTIN\Administrators but per Microsoft's documentation that I have seen, that's not necessary as it is always same. 

This SID value (S-1-5-32-544) has four components:

  • A revision level (1)
  • An identifier authority value (5, NT Authority)
  • A domain identifier (32, Builtin)
  • A relative identifier (544, Administrators)


I get it, but why it matters?

When you run a process in Windows, your SID is the owner of that process. But when you run that same process with elevated privileges, Windows sets it's owner SID to S-1-5-32-544.


What happens to my SID?

Your SID is still stored and tracked by Windows, under User property:


PS C:\Users> $current_principal = ([System.Security.Principal.WindowsIdentity]::GetCurrent())
PS C:\Users> $current_principal | Format-List -Property Owner, User
 

# Results
 
Owner : S-1-5-32-544
User    : S-1-5-21-0000000000-000000000-0000000000-000000 


If the PowerShell is not running under elevated privileges, the Owner and User SID values will  be same. Try it and check it out for yourself.


What is this [System.Security.Principal]....?

It is a .Net namespace or more accurately part of a hierarchy of namespace. It contains WindowsIdentity  class, among other classes. It exposes and allows us to interact with the current user, through methods and properties:

PS C:\Users> $current_principal = ([System.Security.Principal.WindowsIdentity]::GetCurrent()) 

PS C:\Users> $current_principal | Get-Member -MemberType All | `
                                  Select-Object -Property Name, MemberType

Name               MemberType
----               ----------
AddClaim               Method
AddClaims              Method
Clone                  Method
Dispose                Method
Equals                 Method
FindAll                Method
FindFirst              Method
GetHashCode            Method
GetObjectData          Method
GetType                Method
HasClaim               Method
Impersonate            Method
OnDeserialization      Method
RemoveClaim            Method
ToString               Method
TryRemoveClaim         Method
WriteTo                Method
AccessToken          Property
Actor                Property
AuthenticationType   Property
BootstrapContext     Property
Claims               Property
DeviceClaims         Property
Groups               Property
ImpersonationLevel   Property
IsAnonymous          Property
IsAuthenticated      Property
IsGuest              Property
IsSystem             Property
Label                Property
Name                 Property
NameClaimType        Property
Owner                Property
RoleClaimType        Property
Token                Property
User                 Property
UserClaims           Property
 



Is there a built-in function in PowerShell Core I can use instead?

Not that I am aware of so far.  It sure would be a welcome addition to it and I think it could be included in the future releases though.

Please feel free to ask any questions or leave feedback in the comments section.