Adding members to local groups by SID in multiple languages

Kārlis Bergmanis picture Kārlis Bergmanis · Dec 4, 2014 · Viewed 10.4k times · Source

I'm new to powershell/scripting/life in general, but finally I got a problem that is worthy of asking for help: I've various Windows localizations in environment - English, Finnish and Russian in current environment, but with possibilities to have other Scandinavian/European localizations. I need to add Authenticated users to Administrators group. I can script it in English:

NET LOCALGROUP Administrators "Authenticated Users" /add,

but I won't know all localized names. For example, in Russian it would be "Administratori" and "Proshedshie Proverku." In cyrilic, that I'm not that strong with anyway. Of course, I know SIDs - S-1-5-32-544 for Administrators and S-1-5-11 for Authenticated users. However, running

NET LOCALGROUP S-1-5-32-544 S-1-5-11 /add returns error that group doesn't exist. Ok, so I found a script to check it -

$objUser = New-Object System.Security.Principal.NTAccount("kenmyer")

$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])

$strSID.Value

This returns expected value, so far so good. Then I tried to double check it -by running line to get name from SID -

$Admin = (Get-WMIObject -Class Win32_Group -Filter "LocalAccount=True and SID='S-1-5-32-544'").Name

$Auth = (Get-WMIObject -Class Win32_Group -Filter "LocalAccount=True and SID='S-1-5-11'").Name

And $Admin = Administratori (as it should be), while $Auth = nothing. There is no name. And that's where I stopped. I tried this in English environment as well - still got "no such group" message. Running first command I wrote, with both names in English - Works perfectly Ok.

Any ideas?

Upd: Perhaps I can't explain properly what I'm trying to do, so let the script do the talking:

#Task: to add "Authenticated users" to "Administrators" group in any languange OS.
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-544")
$objgroup = $objSID.Translate( [System.Security.Principal.NTAccount])
$objgroupnameAdm = ($objgroup.Value).Split("\")[1]

$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-11")
$objgroup = $objSID.Translate( [System.Security.Principal.NTAccount])
$objgroupnameAuth = ($objgroup.Value).Split("\")[1]

#Administratörer
#Autentiserade användare

net localgroup $objgroupnameAdm $objgroupnameAuth /add

I try this on Swedish Win7 right now. So result is:

net.exe : Syntaxen för kommandot är:
At line:13 char:4
+ net <<<<  localgroup $objgroupnameAdm $objgroupnameAuth /add
    + CategoryInfo          : NotSpecified: (Syntaxen för kommandot är::String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

I've tried also putting $objgroupnameAuth in quotes, as it contains two words, but that gives same result. Definig variables as string - no changes, and replacing $objGroupNameAdm with actual value - no changes.

If I couldn't do it in English Windows, I would assume that it's just functionally impossible.

Answer

Koen van der Eijken picture Koen van der Eijken · Feb 14, 2018

I use this method to translate from SID to localized name:

.SYNOPSIS Adds the "NT AUTHORITY\Interactive security principal to the local computer Administrators group"

.DESCRIPTION THis script uses a SID translation to receive the localized name for the Interactive principal and the Administrators group, then adds the principal to the group using the localized names.

# Translate the S-1-5-32-544 (.\Administrators) SID to a group name, the name varies depending on the language version of Windows.
$sid2 = 'S-1-5-32-544'
$objSID2 = New-Object System.Security.Principal.SecurityIdentifier($sid2)
$localadminsgroup = (( $objSID2.Translate([System.Security.Principal.NTAccount]) ).Value).Split("\")[1]

# Translate the S-1-5-4 (NT AUTHORITY\Interactive) SID to an account name, the name varies depending on the language version of Windows.
$sid1 = 'S-1-5-4'
$objSID1 = New-Object System.Security.Principal.SecurityIdentifier($sid1)
$interactive = (( $objSID1.Translate([System.Security.Principal.NTAccount]) ).Value).Split("\")[1]

# Add the security principal name to the local administrators group. (used old style of adding group members due to compatibility reasons)

try {
    Write-Host "Adding security principal: $interactive to the $localadminsgroup group..."

    $group = [ADSI]"WinNT://$env:computername/$localadminsgroup,group"
    $ismember = "False"

    @($group.Invoke("Members")) | ForEach-Object {
        If ($interactive -match $_.GetType.Invoke().InvokeMember("Name", 'GetProperty', $null, $_, $null)) {
            $ismember = "True"
        }
    }

    If ($ismember -eq "True") {
        write-host "user $interactive is already a member of $localadminsgroup"
    }
    Else {
        $result = $group.Add("WinNT://NT AUTHORITY/$interactive,user")
        write-host "user $interactive is added to $localadminsgroup"
    }
}
Catch {
    write-host $_.Exception.Message
}

It's not entirely tailored towards what you need but I'm sure you can make it work.

Regards,

Koen.