3

Sometimes in Windows 10 I want to temporarily grant administrator privileges to a Standard user, like when I'm logged in as that user and want to work without having to enter an admin user's password repeately.

In the past I would hardcode the batch file with the standard user's name. Today, in a pandemic-induced lapse the notion of using %username% came to mind:

@echo
net localgroup administrators %username% /add
echo %username% set to Administrator
echo See next report to verify
echo.
net user %username%
pause

When I run that batch file "as administrator" the variable %username% contains the administrator username instead of the current user.

Continuing my delusional thinking, I figured I could save %username% to a variable, run a widely cited self-elevation routine, and then do the work.

@echo off
set un=%username%

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"=""
    echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------

net localgroup administrators %un% /add
echo %un% set to Administrator
echo See next report to verify
echo.
net user %un%
pause

Same result as before. I should've remembered that batch files don't execute line by line.

Before I go deeper into the weeds and learn how to write the %username% value to a file or try other uneducated guesses (pushing/popping doesn't appear to exist), I'm hoping someone here can point me in the right direction.


@DavidPostill suggested I try setlocal and endlocal. The example at ss64.com is:

@Echo off
SETLOCAL
::Standard commission
Set _Commission=20
Echo Standard commission %_Commission%

::Premium commission
SETLOCAL
Set _Commission=30
Echo Premium commission %_Commission%

::back to Standard commission
ENDLOCAL
Echo %_Commission%

Emulating the placement of the two SETLOCAL's and the one ENDLOCAL in the example, my script now becomes:

:: REM --add the following to the top of your bat file--
@echo off
SETLOCAL
set un=%username%
echo At this point the variable un should contain the standard username
echo.
echo Currrent user name: %un%
echo.
pause
SETLOCAL

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params = %*:"=""
    echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------

echo Elevation complete. 
echo.
echo After elevation the current username is %un%
echo.
echo Press Enter to see if ENDLOCAL restores the original un value
pause
ENDLOCAL
echo Current user name: %un%
:: net user %un%
echo.
pause

After running the batch file this is the initial command window that appears. So far the variable %un% has the standard user's username in it.

initial command window

After pressing Enter I'm prompted to input an admin user's password, which I do.

Now the following command window appears, partly repeating the code that displayed the standard user's username and then executing the rest. Even after ENDLOCAL the variable %un% is the admin user's username.

enter image description here

Thank you.

user428697
  • 119
  • 1
  • 11
  • Use `setlocal` and `endlocal` to change the scope of variables. See [setlocal](http://ss64.com/nt/setlocal.html) - Set options to control the visibility of environment variables in a batch file. – DavidPostill Jul 14 '20 at 18:04
  • Thank you @DavidPostill. I modified my post now to include my use of setlocal and endlocal, which did not work for me as you'll see. – user428697 Jul 14 '20 at 20:11
  • I haven't messed with batch files for a while, but is this a case where `EnableDelayedExpansion` would be helpful? – Yorik Jul 14 '20 at 21:13

1 Answers1

0

I ended up saving the username using an unelevated batch file that then spawned a new elevated batch file that read in the username and used it. Works.

user428697
  • 119
  • 1
  • 11