Im trying to create 2 batch files that will silently install app on remote PCs and facing problems with main file (second one - silent.bat - placed in ./Installation with .exe file and exist to pass parameters to that .exe install file, tested 100 times, have no issues, so it will not be considered here).
Main file take 7 parameters in cmd line:
- Computer name
- Username
- Password
- Name of an app
- Directory
- as well as 7 just inside-app parameters. Up to 9 total, but i have 7.
First 3 are for main batch, others should be passed futher.
Main file - Remote_install.bat - consist of 2 parts:
- Elevation
First part is lightly changed Matt's answer that helps me elevate my batch and avoid UAC attention:
@pushd %~dp0
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
if %1.==. set res_pcname=F
if "%~1"=="None" set res_pcname=F
if "%~1"=="ELEV" set res_pcname=F
if "%res_pcname%"=="F" (
set PcName=%COMPUTERNAME%
) else (
set PcName=%1
)
type NUL > %~dp0log_%PcName%.txt
ECHO ===================================================================== >> %~dp0log_%PcName%.txt
ECHO "Installation started" >> %~dp0log_%PcName%.txt
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
set winSysFolder=System32
set "batchPath=%~dpnx0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' (
echo "Got privileges" >> %~dp0log_%PcName%.txt
goto gotPrivileges
) else (
echo "Getting privileges" >> %~dp0log_%PcName%.txt
goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (shift /1 & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
if '%cmdInvoke%'=='1' goto InvokeCmd
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
echo "Got privileges" >> %~dp0log_%PcName%.txt
goto ExecElevation
:InvokeCmd
ECHO args = "/c " + "!batchPath!" + " " + args >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"
ECHO "Invoked" >> %~dp0log_%PcName%.txt
:ExecElevation
"%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
Changes are all about logs.
- Copy and schedule
Second part check parameters that passed onto batch file, connect to remote pc (xcopy make the job done even without net run tho), copy files to c:/temp and scedule an installation (and runns it). Main idea from here.
set __compat_layer=runasinvoker
set res_pcname=T
if %1.==. set res_pcname=F
if "%~1"=="None" set res_pcname=F
if "%res_pcname%"=="F" (
set PcName=%COMPUTERNAME%
) else (
set PcName=%1
)
echo %PcName% >> %~dp0log_%PcName%.txt
if %2. NEQ . set res_login=%2
if "%~2"=="None" set res_login=""
if %3. NEQ . set res_pw=%3
if "%~3"=="None" set res_pw=""
echo %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 >> %~dp0log_%PcName%.txt
net use "%PcName%" %res_pw% /user:%res_login% >> %~dp0log_%PcName%.txt
XCOPY %~dp0 "\\%PcName%\C$\temp\appName" /y /i /s /e >> %~dp0log_%PcName%.txt
for %%a in ("\\%PcName%\C:\temp\appName\Installation\*.bat") do (
set "bat_file=%%a "%4" "%5" "%6" "%7""
)
if %res_login% NEQ "" (
if %res_pw% NEQ "" (
schtasks.exe /create /S %PcName% /RU %2 /RP %3 /SC Once /TN InstallApp /TR "%bat_file%" /ST 18:30 >> %~dp0log_%PcName%.txt)
) else (
schtasks.exe /create /S %PcName% /SC Once /TN InstallApp/TR "%bat_file%" /ST 18:30 >> %~dp0log_%PcName%.txt
)
schtasks.exe /run /S %PcName% /TN InstallVISIM >> %~dp0log_%PcName%.txt
schtasks.exe /delete /S %PcName% /TN InstallVISIM /F >> %~dp0log_%PcName%.txt
@popd
echo.
echo...Script Complete....
echo.
I set invoker just in case and re-check pc name, user login, and pass.
Parameters can be passed manually from another batch, command prompt, or, in my case, set in PyQt-made gui and send through popen.cmd2line
Batch files runs for every group box with computer info. Also, gui is used to show logs from every computer im installing app on, have some saved configs, and helps me check if instalation is finnished with winreg.openkey.
PROBLEMS ARE:
I meet a 67 error while trying to connect to remote pc, no futher explanation from cmd prompt. Tried to reinstall net drivers and changed net fisibility. No use. Do i even need that?
Batch files just DO NOT run on net drivers. Even if i have mapped 'em. Just pop window and close immediately.
Batch breakes right after copying files. I have catch that moment with pauses in different places, may xcopy close programm after completion? is it cause syntaxis is screwed?
Running with empty parameters create error from task scheduler : '' - is invalid argument. I replace '' with None and back when press run button in qt, but if anyone will try to run batch naked in cmd prompt it will cause errors. While i have some sort of check for empty ones. Still, getting here requires to pass through xcopy, and batch usually breakes there.
I have unstable performance in python: a. i cant read registry (probably because script runs way faster that installment). Registry is created with innosetup as uninstall info, so i know for sure that registry is there in some point. b. i set up sleep(1) while cycle with count up to 30 to check every second on registry (winreg.open key) and app literally dies while asleep. It should be, its normal. Is there any pattern that will ease that moment?
try: ConnectRegistry(f"{comps.findChildren(QLineEdit)[0].text()}", HKEY_LOCAL_MACHINE) except OSError: self.tb_log.append(f"Error: computer with {comps.findChildren(QLineEdit)[0].text()} doesnt exist") success = False while True and success: try: reg = OpenKey(HKEY_LOCAL_MACHINE, keypath) CloseKey(reg) except OSError: cnt += 1 if cnt == 31: self.tb_log.append("Error during installation: no registry files") break sleep(1) else: self.tb_log.append("Finished successfully") break
I'll be glad to recieve any help with that problems, fellas and ladies! Psexec, wmic, powershell are out of my liege, but im a little bit skilled in python.., so, any ideas, really.
Sorry for any mistakes and wierd writings, if any explanation is needed - im here. If full python project is needed - give me a sign, i'll give you git link, but there is nothing noticeable - just main window transfer and some btn.connect functions.