使用标准用户帐户在提升的脚本中获取登录用户名

问题描述:

在我在 Windows 7 中运行的批处理脚本中,我有几个 IF 子句,例如:

In my batch script run within Windows 7, I have several IF clauses like:

IF "%USERNAME%"=="foo" GOTO bar

不幸的是,当我从上下文菜单中使用以管理员身份运行"运行此批处理脚本时,%USERNAME% 始终是管理员的用户名,而不是用户名当前活动登录用户的名称.

Unfortunately, when I run this batch script elevated with "Run as administrator" from the Context Menu, the %USERNAME% is always the administrator's username, not the username of the current active logon user.

这同样适用于提升的批处理脚本中的 whoami.

The same applies to whoami in an elevated batch script.

QUERY USER 为我提供了当前登录的所有用户的列表,而不仅仅是我要查找的用户.

QUERY USER gives me a list of all users currently logged on, not merely the one user I am looking for.

一个标准的用户账户,不同于管理员账户可以在保持相同用户环境的情况下从用户组令牌提升到管理员组令牌,当以管理员身份运行"时,实际上加载了管理员帐户环境已选中.

A standard user account, unlike an administrator account that can elevate from user group token to administrator group token while keeping the same user environment, actually loads the administrator account environment when "Run as administrator" is selected.

有没有办法获取当前活动登录用户名而不是管理员用户名?

Is there a way to get the current active logon username instead of the administrators username?

WMIC ComputerSystem Get UserName

@echo off
setlocal

rem Get logon username without the leading "computername\" string.
set "user="

for /f "skip=1 tokens=1,* delims=\" %%A in (
    'wmic computersystem get username ^|findstr /r /v "^$"'
) do for %%C in (%%~B) do if not defined user set "user=%%~C"

echo "%user%"
pause

使用 for/f 选项 skip=1,因为第一行是不需要的 UserName 标头.以 \ 分隔,因为值将类似于 computername\username 并在第二个令牌中获取余数.管道到 findstr 以忽略空行.第二个 for 循环将获得第一个没有空格字符的值.

Using the for /f option skip=1, as the 1st line is the UserName header that is not wanted. Delimit by \ as the value will be like computername\username and get the remainder in the 2nd token. Pipe to findstr to ignore empty lines. 2nd for loop will get the first value free of whitespace characters.

管道 wmic 输出到 powershell 以比管道到 findstr 更好地清理输出测试,并使用第二个 for 不需要循环.

Piping wmic output to powershell to cleanup the output tests better than piping to findstr, and the use of a 2nd for loop is not needed.

@echo off
setlocal

rem Get logon username without the leading "computername\" string.
set "user="

for /f "skip=1 tokens=1,* delims=\" %%A in ('
    wmic computersystem get username ^|
    powershell -noprofile -command "$input.trim()"
') do set "user=%%~B"

echo "%user%"
pause

使用 command/? 获得更多帮助.代码中的大多数命令将在命令提示符处显示带有 /? 参数的帮助.

Use command /? for more help. Most commands in the code will display help with the /? argument at a Command Prompt.

@echo off
setlocal

rem Get logon username.
set "user="

for /f %%A in ('quser^|findstr /b /c:">"') do set "user=%%~A"

if defined user if "%user:~0,1%" == ">" set "user=%user:~1%"

echo "%user%"
pause

quser(别名 query user)中的前导>表示当前登录的用户名,不是管理员的用户名.

The leading > in quser (an alias for query user) indicates the currently logged on username, not the administrator's username.

在需要时使用 %user% 而不是 %username%.

Use %user% instead of %username% where needed.

注意事项:

  • 由于 for/f 循环从 token=1 的默认选项中获取用户名,如果用户名包含空格或制表符,则只会获取空格或制表符之前的字符.

  • Due to for /f loop getting username from the default option of token=1, if username contains a space or tab, then this will get only the characters that precede the space or tab.

在 64 位操作系统上,quser.exe 存在于 System32 中,而不存在于 SysWOW64 中.64 位操作系统上的 32 位 cmd.exe 可能无法识别为命令.

On a 64 bit OS, quser.exe exists in System32, not in SysWOW64. A 32 bit cmd.exe on a 64 bit OS may not be recognized as a command.

参考文献: