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 BUILTINAdministrators group and this SID value is same on every Windows computer. May be it would have made more sense to check for the name BUILTINAdministrators 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 BUILTINAdministrators 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.