Run Batch File as Administrator using RunOnce - windows

I have a program installed on various machines, which needs a manual update.
I have all of the updated files stored on a share on a server, and have written a batch file that will copy these into the correct local directory (Program Files (x86))
My plan is to deploy a group policy which will execute this batch file on RunOnce, updating the program when the users first log in.
The problem is to write to the directory, I have to run the batch file as Administrator.
How can I do this using RunOnce? Is there another way?
I've tried using RoboCopy, but just get "Access Denied" and the same problem.
Below is my batch file code.
IF EXIST "C:\Program Files (x86)\NetHelpDesk\\." (goto CopyNetHelp) else Goto ExitLoop
:CopyNetHelp
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\nethdclient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\NetHelpDeskClientUpdater.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\nhescalatorclient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
:ExitLoop
Exit

Try this:
#echo off
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (GOTO askAdmin)
GOTO gotAdmin
:askAdmin
>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"
:: batch is being ran as admin
:skipAdmin
IF EXIST "C:\Program Files (x86)\NetHelpDesk\\." (goto CopyNetHelp) else Goto ExitLoop
:CopyNetHelp
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\nethdclient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\NetHelpDeskClientUpdater.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\nhescalatorclient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
:ExitLoop
Exit

Just for future searches, this is how I got it to work.
I created a new batch file. This will be the one run from RunOnce.
This simply copies the "real" batch file into the users document folder if required. It then calls that batch file from the document folder, thus running it locally getting around the issue.
The "real" batch file as posted by Dennis then runs and once finished, deletes itself from the documents folder.
Copy Batch
IF EXIST "C:\Program Files (x86)\NetHelpDesk\\." (goto CopyNetHelp) else Goto ExitLoop
:CopyNetHelp
copy "\\server\data\pc_support\UpdateNetHelpAdmin.bat" "%USERPROFILE%\Documents" /y
"%USERPROFILE%\Documents\UpdateNetHelpAdmin.bat"
:ExitLoop
Exit
"Real" batch file
#echo off
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' NEQ '0' (GOTO askAdmin)
GOTO gotAdmin
:askAdmin
>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"
:: batch is being ran as admin
:skipAdmin
IF EXIST "C:\Program Files (x86)\NetHelpDesk\\." (goto CopyNetHelp) else Goto ExitLoop
:CopyNetHelp
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\nethdclient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\NetHelpDeskClientUpdater.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
COPY "\\server\programs\Nethelpdesk\NetHelpUpgrade\NhEscalatorClient.exe" "C:\Program Files (x86)\NetHelpDesk\" /y
del "%USERPROFILE%\Documents\UpdateNetHelpAdmin.bat" /q
:ExitLoop
del "%USERPROFILE%\Documents\UpdateNetHelpAdmin.bat" /q
Exit

Related

Batch file won't copy folder and files from batch directory

I have a batch file with three multiple choice options. If I select A, it is supposed to copy a folder called Files (located in the same root directory as the batch file) to the root of the C:\ drive. I can't seem to understand why the %SystemDrive% variable isn't working and wants to point to C:\Windows\system32.
Any ideas?
run.bat
#echo off
set /a _Debug=0
::==========================================
:: Get Administrator Rights
set _Args=%*
if "%~1" NEQ "" (
set _Args=%_Args:"=%
)
fltmc 1>nul 2>nul || (
cd /d "%~dp0"
cmd /u /c echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~dp0"" && ""%~dpnx0"" ""%_Args%""", "", "runas", 1 > "%temp%\GetAdmin.vbs"
"%temp%\GetAdmin.vbs"
del /f /q "%temp%\GetAdmin.vbs" 1>nul 2>nul
exit
)
#ECHO OFF
TITLE WINDOWS AUTOMATION UTILITY
COLOR 02
CLS
ECHO.
ECHO THIS UTILITY HELPS AUTOMATE WINDOWS 10
ECHO ======================================
ECHO.
:MENU
ECHO [A] Copy 'Files' directory from installation media to System Drive
ECHO [B] Set default Start menu for all users
ECHO [C] EXIT Remove bloatware apps from Windows 10
choice /C ABC /M "Select Mode:" /N
IF %ERRORLEVEL% EQU 3 goto End
IF %ERRORLEVEL% EQU 2 goto B
IF %ERRORLEVEL% EQU 1 goto A
::
:B
CLS
ECHO THIS IS B
TIMEOUT 2 >nul
CLS
GOTO MENU
::
:A
CLS
ECHO THIS IS A
TIMEOUT 2 >nul
CLS
ROBOCOPY "%~dp0Files" %SystemDrive% /MT
GOTO MENU
::
:End
CLS
ECHO You've reached the end
PAUSE
EXIT 0
Robocopy result
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : 23 March 2020 00:15:09
Source : D:\Users\Will\Documents\IT Projects\Windows\Windows 10 Image\Files\
Dest : C:\Windows\system32\
Files : *.*
Options : *.* /DCOPY:DA /COPY:DAT /MT:8 /R:1000000 /W:30
------------------------------------------------------------------------------
UPDATE
#Durry42
Typing Set into Command Prompt does return C:\
#aschipfl
I think I tried appending a backslash at the end of %SystemDrive% and it made no difference.

Batch to copy all files in subfolders to a destination without recreating the subfolders

I'm still pretty new to batch scripting, but I'm currently working on a batch file that when launched lets me select a source and destination folder from a menu. Now in my source folder, it has sub-directories with more directories in those. I'm trying to get the batch file to take any and all files in my source folder and copy them into a single folder[Destination] without recreating the folder structure so that all of the files in my sources sub-directories are nice compiled at destination.
I've tried xcopy, robocopy, and to an extent for loops. My guess is that it'll have to be done through for loops, however I'm not sure the appropriate code I should be using for this. I would like all file types to be workable with this program and not just: jpg, jpeg, png, and gif.
Thanks for the help.
#echo off
title File Copier
color 0a
:Menu
cls
echo Main Menu
echo ---------
echo Press 1 to copy files
echo.
echo Press 2 for information
echo.
echo Press 3 to exit
echo ---------------
set /p input=
if %input% == 1 goto 1
if %input% == 2 goto 2
if %input% == 3 goto 3
goto Menu
:1
rem Source
cls
echo Please select your source folder.
echo ---------------------------------
setlocal
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please select your source folder:',0,0).self.path""
for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder=%%I"
setlocal enabledelayedexpansion
cls
rem Destination
echo Please select your destination folder.
echo --------------------------------------
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please select your destination folder:',0,0).self.path""
for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder2=%%I"
setlocal enabledelayedexpansion
cls
rem Source/Destination Info
Set source=!folder!
Set target=!folder2!
Echo Source: %source%
Echo Destination: %target%
echo ---------------------------------------------------------------------
:Choice
set /P c=Would you like to proceed? [Y/N]
if /I "%c%" EQU "Y" goto Yes
if /I "%c%" EQU "N" goto No
goto Choice
:Yes
cls
rem echo D | xcopy %source% %target% /-y
rem robocopy "%source%" "%destination%" *.* /E
for /d %a in (%source%) do #copy %a\*.jpg %target%
for /d %a in (%source%) do #copy %a\*.png %target%
for /d %a in (%source%) do #copy %a\*.gif %target%
pause
goto Success
:No
goto 1
:Success
cls
echo The file(s) were successfully copied.
timeout /t 4 >nul
goto Menu

Copying a file from local folder to "C:\Windows\System32\" using batch file

I am writing an application which uses batch file to copy some files to another location. I am using 64-bit windows 7.
I have asked for admin privileges too using below code:
Code block to get ADMIN right:
#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
Code to copy a file to system32 folder:
copy /d /Y "D:\opt\optPath.txt" "C:\Windows\System32\"
There is no error in copy operation, but the file is copied to "C:\Windows\SysWOW64" location automatically. Need help.
Try using:
#echo off
:: Batch-Admin API
net file>nul 2>&1&&if "%~1"=="64" (goto:GotAdmin) else (if exist "%windir%\Sysnative\" (call start %windir%\Sysnative\cmd /c "%~0" 64&exit) else (goto:GotAdmin))
echo Requesting administrative privileges...
(echo Set UAC = CreateObject^("Shell.Application"^)
echo UAC.ShellExecute "%~s0", "ELEV","", "runas", 0 ) > "%temp%\admin.vbs"
cscript /Nologo "%temp%\admin.vbs"&exit
:GotAdmin
:: Place ADMIN tasks below
copy /d /Y "D:\opt\optPath.txt" "C:\Windows\System32\"
pause
exit
I modified rewrote your script to:
Use an alternative way to check for admin permissions net file && echo Admin || echo No-admin
Added 64-bit launcher VBScript launches everything as 32-bit (redirecting C:\Windows\System32 to C:\Windows\SysWOW64).
64-Bit launcher:
call start %WinDir%\SysNative\cmd /c %0 (This window is hidden)

Passing Unicode parameters to Windows .bat file when rerunning it

My .bat file looks like this:
#echo off
CD /D "%~dp0"
if [%2]==[] (
set user=%USERNAME%
) else (
set user=%2%
)
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
)
:: Check for admin permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' == '0' (
goto gotAdmin
)
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" ""%file%"" ""%user%""""", "%CD%", "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.
:eof
pause
exit /B
I have these two test files:
C:\Test\Folder\ファイル.txt
C:\Test\フォルダ\File.txt
When I run the batch file above and drag 1 onto the cmd window I get:
, which is good.
When I do the same for 2, I get:
When I call UAC.ShellExecute, %file% isn't passed correctly.
How can I get around this problem?
My preferred way of starting a batch file with administrator permissions is to create a shortcut, and then mark that shortcut as requiring administrator permissions.
First right-click foo.bat, then create a shortcut. Open the properties for that shortcut, click the Advanced… button and enable Run as administrator.
This has a downside: you can't drag file names onto the resulting command prompt window. But you can drag a file onto the shortcut.
But what if I don't want or can't use a shortcut?
You can avoid the need to write arbitrary Unicode characters to the file by passing your file name as an argument to your script. Even if the VBS file is in ANSI encoding, the script host always uses Unicode internally.
So here is how you write the VBS file and run it:
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" """ + Wscript.Arguments.Item(0) + """ ""%user%""""", "%CD%", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs" "%file%"
exit /B
Try adding a CHCP (CHange Code Page) command to start of you batch file, using the UTF-8 code page 65001, e.g:
#echo off
chcp 65001
.
.
.
See here for a bit more info on code page identifiers: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
EDIT: You MUST also use a unicode capable font such as Lucida Console for your command window. Without this the command processor chokes on the unicode characters, and will either not find the files, or may display a "system cannot write to the specified device" error.
Click the window icon at the top-left of the command window, choose Defaults on the menu, then on the Fonts tab choose Lucida Console.
UPDATE - Test batch file and output below.
Here's the batch file I'm using to test this:
#echo off
chcp 65001
CD /D "%~dp0"
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
) else (
echo Found file "%file%"
)
Here is the output from my test, when I drag firstly "C:\temp\test\ファイル.txt" into the window, then secondly "C:\temp\test\フォルダ\file2.txt".
My system is Win 7 Pro x64 SP1, with English UK settings.
Your problem is that the way you create your temporary VBS file means it is not a valid unicode file and so Windows doesn't know how to interpret the unicode name you have passed in.
Following beercohol's advice to use code page 65001, I still found that I could not access a file in a unicode directory. However, if I tried to create the file by hand with a unicode editor (e.g. using notepad and saving as a unicode encoding) and invoke that manual script instead of the autogenerated VBS file, it all just worked.
I've re-worked your script to use iconv to create a utf-16 file instead. Note that this script needs to be run with code page 65001 in order to work.
#echo off
CD /D "%~dp0"
if [%2]==[] (
set user=%USERNAME%
) else (
set user=%2
)
:getFile
if [%1]==[] (
set /p file=Enter file name :
) else (
set file=%~f1
echo File name: %~f1
)
:checkFile
for /f "useback tokens=*" %%a in ('%file%') do set file=%%~a
if not exist "%file%" (
echo Error: Could not find file: %file%
echo.
)
:: Check for admin permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
if '%errorlevel%' == '0' (
goto gotAdmin
)
:: Rerun this batch with admin rights
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
echo UAC.ShellExecute "cmd", "/c """"%~f0"" ""%file%"" ""%user%""""", "%CD%", "runas", 1 >> "%temp%\getadmin.vbs"
iconv.exe -f utf-8 -t utf-16le "%temp%\getadmin.vbs" > "%temp%\getadmin2.vbs"
"%temp%\getadmin2.vbs"
exit /B
:gotAdmin
if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
if exist "%temp%\getadmin2.vbs" ( del "%temp%\getadmin2.vbs" )
pushd "%CD%"
CD /D "%~dp0"
echo.
:eof
pause
exit /B

Using command prompt , How can I get the path where chrome exe is installed?

I am writing a batch file and I need to start chrome exe using that batch file . So for that I need to get the path of the directory where chrome is installed .
Usually it is installed in " C:\Program Files (x86)\Google\Chrome\Application" but some users change the path while they install chrome.
I will like to get the path of that chrome exe on run time using command prompt and start it from there.
The content of my batch file are : Where for the highlighted code I want to get on run time instead of hard coding it into my .bat file
(I took help of this to get admin rights.)
#echo
:: 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"
:----------------------https://stackoverflow.com/questions/1894967/how-to-request-administrator-access-inside-a-batch-file----------------
echo Closing all instances of chrome.....
taskkill /f /im chrome.exe
echo All instances of chrome closed. Now going to chrome exe location
cd **C:\Program Files (x86)\Google\Chrome\Application**
echo Reached to chrome exe location. Ready to start new chrome with web security off.
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Get the installed location of Google Chrome from the registry
"HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\Google Chrome\shell\open\command"
"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Clients\StartMenuInternet\Google Chrome\shell\open\command"
Example:
set "Command="
for /f "tokens=2,*" %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\Google Chrome\shell\open\command" /ve 2^>nul') do set "Command=%%~B"
if not defined Command for /f "tokens=2,*" %%A in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Clients\StartMenuInternet\Google Chrome\shell\open\command" /ve 2^>nul') do set "Command=%%~B"
if not defined Command echo Google Chrome was not found.
if defined Command start "Browser" "%Command%"

Resources