Do not perform with expected behavior in batch - batch-file

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?

Related

How to ask for admin permission in a batch?

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.

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

Zip separately each folder using 7-zip

I wrote this batch file to zip files each day separately.
However, I wanted to do it for folders.
the problem is that for each day I have a different name for the folder. like:
20170530.daily
20170529.daily
and on...
I've attached the batch I already wrote, can you look into this?
`#echo off
:: BatchGotAdmin (Run as Admin code starts)
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"
:: BatchGotAdmin (Run as Admin code ends)
:: Your codes should start from the following line
#echo off
for %%A in ("E:\Logs\SmartLogger\*") do (if /I not "%%~xA" == ".zip" 7za.exe
a -tzip -mx5 -y -- "%%~dpnA.zip" "%%~A" >nul && del /Q /F "%%~A")`

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.

Writing 2 batch files into 1

I've got 2 separate batch files, the first one checks whether UAC is enabled or disabled. If enabled it calls "uac.bat".
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA | FIND "0x1" >NUL && ( call uac.bat ) || ( echo Good day sir )
"uac.bat" that is located in the same folder as the previous batch file, pops-up the UAC prompt:
#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"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
pushd "%CD%"
CD /D "%~dp0"
:--------------------------------------
I've tried using "call" command, but I'm doing something wrong because even if my UAC is disabled it still pop's up the UAC prompt as if my UAC were enabled. How to fix this?
Thanks in forward :)
This should merge the two into one.
#echo off
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA | FIND "0x1" >NUL && ( goto :PROMPTUAC )
exit >nul
:PROMPTUAC
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
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"

Resources