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.