Once in a while, you may find yourself in need of identifying and/or interacting with well-known and well-defined security principals, like the builtin Administrator account, the SYSTEM account or a generic principal group like Everyone - let's explore safe ways to do this with PowerShell!
Originally published on December 31, 2014

### Assumptions and Expectations

There are numerous shortcuts to getting to the Administrator account on a Windows machine. First thing that comes to mind is using a DirectoryEntry with the WinNT provider, like so:

$Administrator = [ADSI]"WinNT://$($env:COMPUTERNAME)/Administrator,user"  Now, this is all fine and dandy if you're on an English-language, Out-of-the-Box Windows installation. But what if the builtin Administrator is not called Administrator? What if the local account had been renamed? ### LocaleID and ümlaüts You might be using Finnish-language Windows, in which case the Administrator account is localized as "Järjestelmänvalvoja" - not kidding! Now our script will have to take that into account: $AdminName = switch((Get-Culture).LCID){
# LCID = local administrator name
# Finnish
11    {"Järjestelmänvalvoja"}
1035  {"Järjestelmänvalvoja"}
# French
# Hungarian
14    {"Rendszergazda"}
1038  {"Rendszergazda"}
# Portuguese
# Russian
25    {"Администратор"}
1049  {"Администратор"}
# Spanish
# Swedish
}

$Administrator = [ADSI]"WinNT://$($env:COMPUTERNAME)/$AdminName,user"


Gosh, that's horrible - another snowflake we now need to maintain (who knows, these localizations might not persist in Windows forever).

### SIDs to the rescue!

Now, the SAM Account Name is not the only identifier by which we can get to the Administrator account (or any account for that matter). A much more interesting (and distinct) identifier would be the account Security Identifier, often abbreviated "SID".
Working with SIDs offers a few interesting characteristics:

1. A SID is unique!
2. A SID is persistent and won't change for the lifetime of the principal!
3. A SID contains information about the Principal AND the LogonDomain*!
4. Internally, a SID is just a variable-length byte array!

Now, in Windows-land, a number of SIDs are pre-defined, either universally, like "Everyone" (S-1-1-0), or domain specific, like the builtin "Administrator" account (S-1-5-21-500). These Security Identifiers are called "Well-Known" SIDs, and consistently identifies builtin principals like the examples above.

The constructor for the .NET implementation of the Security Identifier type has an overload that takes a so-called WellKnownSidType object and a Domain SID as it's arguments, meaning that we can simply target a "well-known" principal using the WellKnownSidType enum, without caring about the name of the account/group! Yay!

$LogonDomainSID = "S-1-5-21-1682721775-3705583687-167823271"$WellKnownUser  = [System.Security.Principal.WellKnownSidType]::AccountAdministratorSid
$Administrator = New-Object System.Security.Principal.SecurityIdentifier -ArgumentList$WellKnownUser,$LogonDomainSID  Much better - no need to take the Locale into account anymore! Now we just need a way to identify the LogonDomain SID, and we can reference the builtin Administrator account on any system or in any domain! ### Figuring out the LogonDomain SID For local users, the LogonDomain is the Machine SID, that is - the SID of the local SAM database - not the SID of the computer account object, should the machine happen to be a member of a domain. Windows keeps this piece of information in the not-very-accessible HKLM:\SECURITY hive of the registry. There are other ways to deduce this without obtaining access to said hive though. One of my favorites, but a somewhat hacky approach is to retrieve a local user account using WMI, and then removing the last portion (the "relative identifier") of the account SID, resulting the Domain SID. I've thrown together a simple sample below: function Get-MachineSID { param( [switch]$DomainSID
)

$WmiComputerSystem = Get-WmiObject -Class Win32_ComputerSystem$IsDomainController = $WmiComputerSystem.DomainRole -ge 4 if($DomainSID -or $IsDomainController) {$Domain    = $WmiComputerSystem.Domain$SIDBytes = ([ADSI]"LDAP://$Domain").objectSid |%{$_}
$ByteOffset = 0 New-Object System.Security.Principal.SecurityIdentifier -ArgumentList ([Byte[]]$SIDBytes),$ByteOffset } else {$LocalAccountSID = Get-WmiObject -Query "SELECT SID FROM Win32_UserAccount WHERE LocalAccount = 'True'" |Select-Object -First 1 -ExpandProperty SID
$MachineSID = ($p = $LocalAccountSID -split "-")[0..($p.Length-2)]-join"-"
New-Object System.Security.Principal.SecurityIdentifier -ArgumentList $MachineSID } }  Great! Now we can simply do: $WellKnownSid = [System.Security.Principal.WellKnownSidType]::AccountAdministratorSid
$MachineSID = Get-MachineSID$AdminAccount = New-Object System.Security.Principal.SecurityIdentifier -ArgumentList $WellKnownSid,$MachineSID


And that's it! .NET <3