Background:
In an attempt to change language settings for a Windows-11 Home
edition, from ES to US.
I managed to get most changes done, but there are still several other items* returning in Spanish.
One Example returning Spanish groups:
Get-LocalGroup
Name Description
---- -----------
Administradores Los administradores tienen acceso completo y sin
Device Owners Los miembros de este grupo pueden cambiar la …
Hyper-V Administrators Members of this group have complete and unrestricted …
IIS_IUSRS Grupo integrado usado por Internet Information Services.
Invitados De forma predeterminada, los invitados tienen el mismo…
...
Looking further how/why these groups are in Spanish, I ran whoami /groups
and net localgroup
. There I got the following output showing that some groups are listed as Alias
under the Type
column.
# whoami /groups
Group Name Type SID Attributes
============================================================= ================ ============ ===============================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114 Mandatory group, Enabled by default, Enabled group
BUILTIN\Administradores Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner
BUILTIN\Usuarios Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level Label S-1-16-12288
# net localgroup
Aliases for \\LAPTOP-xxxx
------------------------------------------
*Administradores
*Device Owners
*Hyper-V Administrators
*IIS_IUSRS
*Invitados
*Lectores del registro de eventos
*System Managed Accounts Group
*Usuarios
*Usuarios COM distribuidos
*Usuarios de administración remota
*Usuarios del monitor de sistema
*Usuarios del registro de rendimiento
The command completed successfully.
Q: How to remove these group aliases and see the original group names?
Bonus Question
:
Would it remove the ES language from those same items?
Related Question:
The term alias in the output from net localgroup
is somewhat misleading, as it simply refers to the name of a local group - see the bottom section for details.
It seems that the following pieces of information are statically assigned based on the Windows display (user-interface) language that the OS was set up with:
The names of built-in local user and group accounts, such as Administrators
(in English) / Administradores
(in Spanish).
Their descriptions.
Therefore, changing the Windows display language later (by installing a language pack, as discussed in this answer to your linked question) does not change this information, so your only option is to do it yourself - see next section.
In addition to renaming such accounts and updating their descriptions being possible interactively via lusrmgr.msc
, you can also do so programmatically:
Caveat:
Renaming user and group accounts can break existing scripts (unless they happen to use SIDs instead of names).
It was an unfortunate design decision on the part of Windows to begin with to localize such names, precisely because it hampers portability of code between machines that shipped with different display languages or, as in your case, switching to a different display language.
# Establish a mapping by SID for all built-in *groups*
# to their English names and descriptions.
# See below for how to create this hashtable programmatically.
$sidMap_Groups =
[ordered] @{
'S-1-5-32-544' = [ordered] @{
Name = 'Administrators'
Description = 'Administrators have complete and unrestricted access to the computer/domain'
}
# ...
}
# Ditto for built-in *users*, but with keys based on the
# *last SID component* only.
# See below for how to create this hashtable programmatically.
$sidMap_Users =
[ordered] @{
'500' = [ordered] @{
Name = 'Administrator'
Description = 'Built-in account for administering the computer/domain'
}
# ...
}
# Rename and update built-in *groups*
Get-LocalGroup |
ForEach-Object {
if ($entry = $sidMap_Groups[$_.SID.Value]) {
# !! See below for why Set-LocalGroup is *not* an option.
net localgroup $_.Name /comment:$($entry.Description)
$_ | Rename-LocalGroup -NewName $entry.Name
}
}
# Rename and update built-in *users*
Get-LocalUser |
ForEach-Object {
if ($entry = $sidMap_Users[($_.SID.Value -split '-')[-1]]) {
# !! See below for why Set-LocalUser is *not* an option.
net user $_.Name /comment:$($entry.Description)
$_ | Rename-LocalUser -NewName $entry.Name
}
}
Note:
Inexplicably, Set-LocalUser
and Set-LocalGroup
, as of version 1.0.0.0 of their enclosing Microsoft.PowerShell.LocalAccounts
module, have a hard 48-character limit on the value passed to their -Description
parameter.
By contrast, net.exe
, via its localgroup
and user
subcommands, does not have this limitation with its /comment
parameter, which is why it is used above.
If you have access to a machine that was set up with English during installation and is currently set up for PowerShell remoting, you can create the $sidMap_Groups
and $sidMap_Users
hashtables as follows, assuming $computer
as that machine's name:
$sidMap_Groups, $sidMap_Users =
Invoke-Command -ComputerName $computer {
$sidMap_Groups = [ordered] @{}
Get-LocalGroup |
Where-Object {
# Infer whether an account is built-in from the number of SID components.
($_.SID.Value -split '-').Count -eq 5
} |
ForEach-Object {
$sidMap_Groups[$_.SID.Value] = [ordered] @{ Name = $_.Name; Description = $_.Description }
}
$sidMap_Users = [ordered] @{}
Get-LocalUser |
Where-Object {
# Infer whether an account is built-in from the last SID component.
[int] ($_.SID.Value -split '-')[-1] -lt 1000
} |
ForEach-Object {
$sidMap_Users[($_.SID.Value -split '-')[-1]] = [ordered] @{ Name = $_.Name; Description = $_.Description }
}
$sidMap_Groups, $sidMap_Users
}
Group-related terminology in net localgroup
and whoami /groups
output:
In effect, all local groups are categorized as aliases, irrespective of whether they are built-in groups (e.g. Adminstrators
) or not.
Not all built-in groups are represented as local groups, however, namely not those that are purely "virtual" groups whose membership is inferred from the membership of other groups (e.g. Everyone
) and whoami /groups
calls these well-known groups.
In a wider sense, both these subtypes of built-in groups are well-known, and they all have well-known, unchanging SIDs (Security Identifiers).
Since every concrete user and group account has a name that can be changed (including those of built-in groups, as happens implicitly during installation of Windows with a language other than English), the name of a user or group can be conceived of as a - changeable - alias of the user or group's SID, i.e. their - unchanging - identifier.
As for the label line in the output from whoami /groups
: This isn't actually related to user groups, but identifies the integrity level of the current process, in the context of Mandatory Integrity Control: High Mandatory Level
implies that you've run the command from an elevated session; a non-elevated session shows Medium Mandatory Level
.