How to ask for admin permission in a batch? - batch-file

Since a few weeks, my scripts for modifying my IP address don't work anymore. I suspect an update of Windows 10.
Up to now, I was using the script given in this thread :
#echo on
:: BatchGotAdmin
:-------------------------------------
REM --> Check for permissions
IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
) ELSE (
>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"
:--------------------------------------
<YOUR BATCH SCRIPT HERE>
But now, I got this error:
Failed to load script: C:\Users\me\AppData\Local\Temp\getadmin.vbs: access denied
The strange thing is, getadmin.vbs is indeed created in the Temp directory.
Here is the exact output :
C:\Users\arc\Desktop\ConfigLAN>REM --> Check for permissions
C:\Users\arc\Desktop\ConfigLAN>IF "AMD64" EQU "amd64" ("C:\WINDOWS\SysWOW64\cacls.exe" "C:\WINDOWS\SysWOW64\config\system" 1>nul 2>&1 ) ELSE ("C:\WINDOWS\system32\cacls.exe" "C:\WINDOWS\system32\config\system" 1>nul 2>&1 )
C:\Users\arc\Desktop\ConfigLAN>REM --> If error flag set, we do not have admin.
C:\Users\arc\Desktop\ConfigLAN>if '5' NEQ '0' ( echo Requesting administrative privileges... goto UACPrompt ) else (goto gotAdmin ) Requesting administrative privileges...
C:\Users\arc\Desktop\ConfigLAN>echo Set UAC = CreateObject("Shell.Application") 1>"C:\Users\arc\AppData\Local\Temp\getadmin.vbs"
C:\Users\arc\Desktop\ConfigLAN>set params=
C:\Users\arc\Desktop\ConfigLAN>echo UAC.ShellExecute "cmd.exe", "/c ""C:\Users\arc\Desktop\CONFIG~1\newBatch.bat"" ", "", "runas", 1 1>>"C:\Users\arc\AppData\Local\Temp\getadmin.vbs"
C:\Users\arc\Desktop\ConfigLAN>"C:\Users\arc\AppData\Local\Temp\getadmin.vbs"
(error is triggered here)
C:\Users\arc\Desktop\ConfigLAN>del "C:\Users\arc\AppData\Local\Temp\getadmin.vbs"
C:\Users\arc\Desktop\ConfigLAN>exit /B

You can use the following sequence that works perfectly fine for me.
#echo off
::::::::::::::::::::::::::::::::::::::::::::
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' (goto gotPrivileges) else (goto getPrivileges)
:getPrivileges
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo For Each strArg in WScript.Arguments >> "%temp%\getadmin.vbs"
echo If strArg = WScript.Arguments.Item^(0^) Then d = Left^(strArg, InStrRev^(strArg,"\"^) - 1^) >> "%temp%\getadmin.vbs"
echo args = args ^& " " ^& strArg >> "%temp%\getadmin.vbs"
echo Next >> "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd.exe", ^("/c start /D """ ^& d ^& """ /B" ^& args ^& " ^& exit"^), , "runas", 4 >> "%temp%\getadmin.vbs"
cscript "%temp%\getadmin.vbs" ""%~s0"" %*
del /q "%temp%\getadmin.vbs"
exit /b
:gotPrivileges
:: Your code here
This VBS script uses perfectly the UAC.ShellExecute, you can point by yourself the changes. You used a lot of tricks and the VBS code doesn't even call UAC in the correct way, which is why it gives permission denied. I believe that the use of cacls and this script was very useful in the past, used by Malware to obtain administrative access without the user's permission, there are many programs that use icacls for this, I will not even point out, but that may have made using icacls difficult.
You can also use Powershell previously to do it.
Powershell -Command "Start-Process cmd -Verb RunAs -ArgumentList '/c C:\YourPath\yourprogram.bat'"
Both of the scripts works perfectly fine for me. I can see a lot of errors in your .vbs, but there is no point in pointing them out because the script is not yours.
I recommend that you use the Powershell, it is much more useful and simple, to integrate:
NET FILE >NUL 1>NUL 2>NUL
if %errorlevel% equ 0 (goto gotprivileges) else (start Powershell -Command "Start-Process cmd -Verb RunAs -ArgumentList '/c C:\YourPath\yourprogram.bat'" & exit)
Hope this helps,
K.

Related

Do not perform with expected behavior in batch

I've tried so many times, but I can't find the cause.
Command code for obtaining administrative privileges that you are using first.
#echo off
:: 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.
bcdedit >>nul
if %errorlevel% == 1 goto noadmin
goto gotAdmin
exit
:noadmin
if '%errorlevel%' NEQ '0' (
echo Requesting Admin Permissions ...
goto UACPrompt
) else ( goto gotAdmin )
exit
: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"
:-------------------------------------
I modified it from this code, so it's as follows.
#echo off
Set curdir="%cd%"
echo %curdir%
pause
:-------------------------------------
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.
bcdedit >>nul
if %errorlevel% == 1 goto noadmin
goto gotAdmin
:noadmin
if '%errorlevel%' NEQ '0' (
echo Requesting Admin Permissions ...
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"
:-------------------------------------
pause
The result is...
Print out the current directory and pause
After entering any key, check the administrative authority and perform the action of obtaining it.
Print out the current directory and pause
Confirm administrative authority and move on.
Pause
End
I want to the expected move is...
Print out the current directory and pause
After entering any key, check the administrative authority and perform the action of obtaining it.
Pause
End
What I want is an expected action. How do I modify it to follow this behavior?

Batch calls admin batch, vabiable doesn't cross over

I am trying to send a variable from one batch file to another after elevating privileges. Test2.bat doesn't echo test123, it just echos that ECHO is on.
test1.bat
set "test=test123"
call "%cd%\test2.bat"
pause
test2.bat
:: 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"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
:--------------------------------------
echo %test%
pause
You are setting a variable, then you are elevating and creating a new process and you expect the variable to exist. instead call test2.bat from test1.bat but let it set the variable after it got the privileges, but returning to call test1.bat..
#echo off
set "test=test123"
if not "%~1" == "haveAdmin" call "%~dp0\test2.bat"
then test2.bat some minor changes, see if you can spot them:
#echo off
:: 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"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%~dp0"
call test1.bat haveAdmin
:--------------------------------------
echo %test%
pause
Your code fails because the VBScript is creating a new separate process when prompting UAC.
If you only want to pass one single variable with very simple content (without embedded ', ", CRLF...), the easiest way is to pass as it as a parameter.
test-call.bat
#echo off
set "test=test_123!" only works for simple content
call "%__CD__%admin.bat" %test%
admin.bat
#echo off
if "%~1" == "" exit /b 1
("%__APPDIR__%net.exe" session||(
"%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -NonInteractive -Command "Start-Process -FilePath '%~f0' -ArgumentList '%~1' -Verb Runas"
exit /b
))>nul 2>&1
set "var=%~1"
====SETLOCAL EnableDelayedExpansion
echo(!var!
pause
If your code involves parsing multiple (all) variables or tricky content, the best way is to let Start-Process return to the caller itself.
How about passing the batch file as parameter?
Test1.bat
set "test=test123"
"%cd%\test2.bat" "%test%"
pause
Test2.bat
#echo off
set "test=%~1"
:: 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"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
:--------------------------------------
echo %test%
pause

Editing hosts with batch file windows 10

Hello i've been looking for a batch file that is able to edit my hosts file in windows 10 but apparently none is working. I've been trying to use these two codes combined found in this forum.
REM --add the following to the top of your bat file--
#echo off
:: 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"
SET NEWLINE=^& echo.
FIND /C /I "ns1.intranet.de" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^62.116.159.4 ns1.intranet.de>>%WINDIR%\System32\drivers\etc\hosts
FIND /C /I "ns2.intranet.de" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^217.160.113.37 ns2.intranet.de>>%WINDIR%\System32\drivers\etc\hosts
FIND /C /I "ns3.intranet.de" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^89.146.248.4 ns3.intranet.de>>%WINDIR%\System32\drivers\etc\hosts
FIND /C /I "ns4.intranet.de" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^74.208.254.4 ns4.intranet.de>>%WINDIR%\System32\drivers\etc\hosts
What i get when i try to run is that windows defender blocked the file because of the security reasons. How to make it work?
It's painful to change hosts file manually two days a week in normal way.
Download the hostsfileeditor it makes it a snap to change.

Error 53 - Network Path was not found

first post of mine on this website, used to lurk but I've recently had a bit of a pickle with a batch-file
I've been working as a small little simple auto connect batch-command which auto-connects my laptop to my schools shared network server but for some odd reason I am unable to connect as the command prompt prints "System Error 53 has occurred The network path was not found."
If anyone could shed some light as to what I'm doing wrong would be much appreciated.
#echo off
:: BatchGotAdmin
:-------------------------------------
REM --> Check for permissions
IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
) ELSE (
>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"
:--------------------------------------
setlocal
:PROMPT
SET /P AREYOUSURE="Are you sure you want to add School's shared documents? (Y/[N]):"
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END
echo Please enter the Username you use to login to school computers
set /p username=Enter your Username(SCHOOL USERNAME):
echo Please enter the Password you use to login to school computers
set /p password=Enter your Password(SCHOOL PASSWORD):
net use Z: "\\server1\shared_documents$\" "%password%" /user:\Students\"%username%" /persistent:yes
TIMEOUT /T 5 /NOBREAK
:END
endlocal

batch file for copying files with admin rights

im new to batch files and im trying to write a file which gets admin rights and copies a file.
This is the code I found for getting admin rights, but it seems that it is not working for Windows 8;
#echo off
:: 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"
:--------------------------------------
<my code>
Then i´ve tried to write code for copying the files which didnt work neither:
xcopy "%1" "%2"
xcopy "%3" "%4"
echo "succesfull"
Try getting rid of "%temp%" throughout the script, I tried the same code under windows 8, but I keep getting access denied errors until I edit every line that accesses the systems temp folder.

Resources