Batch - Reboot computer if a batch file ends - windows

Essentially we have 2 batch files, one which is the "wrapper" if you will, calling another batch file so it starts as /min (minimized). This batch file then ends once it has launched the 2nd batch file.
This contains a loop, which keeps spawning an RDP session after it is closed.
The problem is, if the user ALT-TABs and closes the batch, they are just left with an empty desktop (as we task kill explorer). Is there a way of force rebooting the machine if that batch loop ends?
Thanks!

There is a standard cmd command:
shutdown /r
Usage: shutdown [/i | /l | /s | /r | /g | /a | /p | /h | /e | /o] [/hybrid] [/f]
[/m \\computer][/t xxx][/d [p|u:]xx:yy [/c "comment"]]
No args Display help. This is the same as typing /?.
/? Display help. This is the same as not typing any options.
/i Display the graphical user interface (GUI).
This must be the first option.
/l Log off. This cannot be used with /m or /d options.
/s Shutdown the computer.
/r Full shutdown and restart the computer.
/g Full shutdown and restart the computer. After the system is
rebooted, restart any registered applications.
/a Abort a system shutdown.
This can only be used during the time-out period.
/p Turn off the local computer with no time-out or warning.
Can be used with /d and /f options.
/h Hibernate the local computer.
Can be used with the /f option.
/hybrid Performs a shutdown of the computer and prepares it for fast startup.
Must be used with /s option.
/e Document the reason for an unexpected shutdown of a computer.
/o Go to the advanced boot options menu and restart the computer.
Must be used with /r option.
/m \\computer Specify the target computer.
/t xxx Set the time-out period before shutdown to xxx seconds.
The valid range is 0-315360000 (10 years), with a default of 30.
If the timeout period is greater than 0, the /f parameter is
implied.
/c "comment" Comment on the reason for the restart or shutdown.
Maximum of 512 characters allowed.
/f Force running applications to close without forewarning users.
The /f parameter is implied when a value greater than 0 is
specified for the /t parameter.
/d [p|u:]xx:yy Provide the reason for the restart or shutdown.
p indicates that the restart or shutdown is planned.
u indicates that the reason is user defined.
If neither p nor u is specified the restart or shutdown is
unplanned.
xx is the major reason number (positive integer less than 256).
yy is the minor reason number (positive integer less than 65536).

My suggestions:
Do you really need batch to be visible (minimized) or can it be hidden?
If it can be hidden, just use VBScript to launch it hidden:
With CreateObject("W"&"Script.Shell")
.Run "LongRun.bat", 0
End With
If you really need batch to be shown, you could make a hidden script which will wait for batch to terminate and reboot.
Step 1: Launch script hidden (Start.vbs):
Set WsShell = CreateObject("W"&"Script.Shell")
WsShell.Run "Hidden.vbs", 0
Step 2: Hidden.vbs will launch batch and wait it to return:
'This script is supposed to start hidden!
Set WsShell = CreateObject("W"&"Script.Shell")
WsShell.Run "LongRun.bat", 7, True
'WsShell.Run "REBOOT.EXE ..." 'Must remove comment and complete command line
MsgBox "Rebooting..."
Now LongRun.bat is running, Hidden.vbs also (but not visible).
If somehow LongRun.bat is terminated, Hidden.vbs will continue its execution and reboot.
(WScript.Shell.Run documentation)
EDIT: Notice "W"&"Script.Shell" is same as "WScript.Shell" but StackOverflow doesn't allow me to write it!

Related

How to execute multiple programs in the same time with a .bat file

I made 2 bat files to start apps with examples below:
My expectation is to execute them simultaneously, meaning after double click bat file, then 3 programs will pop up.
With the 1st example, the behavior is to execute outlook first, then both Mircrosoft Edge and OneNote still not pop up, until I stop Outlook.
Example 1
#echo off
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Outlook.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OneNote.lnk"
exit
With the 2nd example, both Mrcrosoft Edge and OneNote were executed simultaneously, however Outlook not until I stop OneNote.
Example 2
#echo off
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\OneNote.lnk"
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Outlook.lnk"
exit
My questions is why it behaves like this way and how to make these 3 programs start up in the same time ?
Shown below is the Windows config:
Edition Windows 10 Enterprise
Version 21H2
Installed on ‎10/‎27/‎2021
OS build 19044.1826
Experience Windows Feature Experience Pack 120.2212.4180.0
1)Run the first program using the start command.
2)Check the task list in a loop to see if the program has appeared there.
3)Impose some time limitation to the said loop.
4)Run the next program in case of success, exit with notification otherwise.
#ECHO
OFF START program1.exe
FOR /L %%i IN (1,1,100) DO (
(TASKLIST | FIND /I "program.exe") && GOTO :startnext
:: you might add here some delaying
)
ECHO Timeout waiting for program1.exe to start
GOTO :EOF
:startnext
program2.exe
:: or START
program2.exe
Remember that the timing is not precise, especially if you are going to insert delays between the task list checks.
Normally to run tasks parallel, you should add start /b before the command to run.
The start command allows the command to be executed in another process, while /b prevents the opening of a new window.
In this specific case start /b does not work, for reasons unknown to me, but you can always use cmd /c.

Run .bat as administrator without manual confirmation

I want my .bat file to always run as administrator without me having to manually allow it to make changes to my device each time. It's part of a larger automated process and simply clears and resets the clipboard. Since it's automated I can't be there each time to hit yes.
wmic service where "name like '%%cbdhsvc_%%'" call stopservice
%windir%\System32\cmd.exe /c "echo off | clip"
wmic service where "name like '%%cbdhsvc_%%'" call startservice
Alternatively is there a way I could set it to run say every 5 seconds in the background with only a single confirmation until I tell it to stop or for a set period? Thanks
For only having to allow administrator once, you could use the timeout command.
:top
"code"
timeout /t 5 /NOBREAK > nul
goto :top
do timeout/? in cmd to see the usage.

CMD.exe closes immediately - unusual line in AutoRun registry entry

I've noticed that my command line didn't start anymore, it just immediately minimized and closed itself upon running. I suspect this is due to a virus or at least some kind of malicious program having been executed. I found the following code inside my registry. It seems legible but my knowledge of batch / the command line is limited. Can anyone tell me what it does?
#mode 20,5 & tasklist /FI "IMAGENAME eq SoundModule.exe" 2>NUL | find /I /N "SoundModule.exe">NUL && exit & if exist "C:\Users\Leon\AppData\Roaming\Microsoft\SoundModule\SoundModule.exe" ( start /MIN "" "C:\Users\Leon\AppData\Roaming\Microsoft\SoundModule\SoundModule.exe" & tasklist /FI "IMAGENAME eq explorer.exe" 2>NUL | find /I /N "explorer.exe">NUL && exit & explorer.exe & exit ) else ( tasklist /FI "IMAGENAME eq explorer.exe" 2>NUL | find /I /N "explorer.exe">NUL && exit & explorer.exe & exit )
According to this reddit thread, it's a "vmprotected cryptocurrency miner".
You most likely got it if you installed anything you downloaded from the torrent network, for example a popular game released in the past few weeks :^)
The following SO thread contains part of the solution: CMD.exe closes immediately after calling (Win7 64)
The malicious party added an AutoRun directive via registry to the Windows Command Processor (cmd.exe usually), which you need to remove from any of the following locations it's present in:
Computer\HKEY_CURRENT_USER\Software\Microsoft\Command Processor
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
What the directive does is to execute SoundModule.exe and then explorer.exe (if not already started).
According to the other reply in this thread, they set %comspec% to run at startup, via Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon.
So on startup, it's running %comspec% (instead of the default Windows Explorer), which itself on start first runs SoundModule.exe and then explorer.exe. Not sure why they did it this way, anyone who makes use of cmd.exe was bound to figure it out and spread the word.
There are at least two confirmed VirusTotal records for this file: [1], [2]
I had the same program on my computer, check Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon for the shell value which is most likely "%comspec%" (which makes sense why it was just cmd running on startup since %comspec% is cmd.exe) and change it to "explorer.exe"
Run regedit
Go to HKLM\Software\Microsoft\Command Processor\ or HKEY_CURRENT_USER\Software\Microsoft\Command Processor\ or HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\
For some reason there was AUTORUN key with "EXIT" inside.
Remove the AutoRun key and cmd will work fine.
Then check Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon for the shell value which is most likely "%comspec%" (which makes sense why it was just cmd running on startup since %comspec% is cmd.exe) and change it to "explorer.exe" as the user above said.
Edit: I also found that it was a cryptocurrency mining virus located at %appdata%\Microsoft\SoundModule or SoundMixer on my case.
You should probably delete this file too.
For reference, I will add that I was able to verify that my issue was the Autorun registry key by using Win-R to bring up the "Run" dialog, and typing cmd /d (which disables any autorun per the windows docs [https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd] . This successfully opened a command prompt window.
Inspecting the registry, my HKEY_CURRENT_USER\Software\Microsoft\Command Processor had Autorun as Type=REG_SZ and Data=if exist. I made a restore point, then renamed that key to AutorunOld ... and then I was able to open a command prompt without issue.

Batch file to close program after second program opens

I have a frontend program (a.exe) that I use to curate and launch other programs (in this example b.exe). Once the item in the frontend (a.exe) is selected from the list (b.exe) launches. Problem is the frontend (a.exe) stays open and to close it I have to manually exit out of the program it launched (b.exe) to the desktop to do so.
What I am trying to do is have the frontend (a.exe) close after an item within it is selected (b.exe). This would be trigged by a double click.
How would I go about creating a batch file to do this?
The frontend program (a.exe) has a GUI interface.
#echo off
cd "C:\Program Files\a.exe folder"
start a.exe
then what?
The best solution would be contacting the author of a.exe and asking for an option to automatically exit a.exe after starting application b.exe as separate and detached process.
The second best solution would be finding out which environment b.exe needs to run successfully and create with a batch file this environment and start b.exe.
However, if the best two solutions are not possible for whatever reason, then the following batch file code be helpful.
#echo off
start "" /D"C:\Program Files\a.exe folder" "a.exe"
set "LoopCount=0"
:Loop
%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK >nul
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\findstr.exe /B /C:"b.exe" /C:"c.exe" /C:"d.exe" >nul
if not errorlevel 1 (
%SystemRoot%\System32\taskkill.exe /IM "a.exe"
goto EndBatch
)
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\findstr.exe /B /C:"a.exe"
if errorlevel 1 goto EndBatch
set /A LoopCount+=1
if not %LoopCount% == 60 goto Loop
:EndBatch
set "LoopCount="
The batch file first starts a.exe with its program files directory set as current directory before starting it as separate process.
Windows command processor immediately continues execution of the batch file after starting a.exe and defines next the environment variable LoopCount with value 0.
Inside the loop the external command TIMEOUT available since Windows Vista by default is used to wait one second.
Then external command TASKLIST is executed to output all running processes without header. This output is redirected with | to external command FINDSTR which searches case-sensitive at beginning of all lines output by TASKLIST for one of the strings specified with the option /C:. For a case-insensitive search use additionally FINDSTR option /I if not knowing how the executables started by a.exe are in list output by TASKLIST.
FINDSTR exits with value 0 on having found at least one line starting with one of the searched strings and with value 1 if nothing matched. The output of FINDSTR is of no interest and therefore redirected to device NUL.
The terminate signal is sent with external command TASKKILL to the executable a.exe on having found one of the processes in the list. a.exe should terminate itself on receiving and processing this signal. In case of a.exe is ignoring this signal or it terminates, but before terminates also the started application, it would be necessary to use additionally the TASKKILL option /F to force a real kill of a.exe process by the Windows operating system. In general the option /F should not be used as it can result in corrupt files in case of application killed by the operating system has one or more files open for write operations.
But if after one second none of the processes started by a.exe is running, the batch file checks next if a.exe itself is still running. The batch file exits if this is not the case. Otherwise it increments the environment variable LoopCount and compares its value with 60 to exit batch file after having waited already 60 seconds with the checks to avoid a nearly endless running batch file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
findstr /?
goto /?
if /?
set /?
start /?
taskkill /?
tasklist /?
timeout /?
See also Microsoft article about Using command redirection operators.

TIMEOUT.EXE alternative for legacy Windows OSes?

I am trying to write a batch script that is as universal across Windows versions as possible (or at least from XP to 10). Everything is compatible so far (just some echoes and variable setting), except it uses the TIMEOUT.EXE command, which isn't available in XP or below.
I tried copying the exe over to no success. I was wondering if, through some clever coding, if this is possible. I basically need it to wait X amount of seconds before continuing, or allow a keypress to continue.
I tried using sleep.exe from the server 2003 utilities pack while piping it to set /p "=" and vice versa, but that didn't work either.
Any help is appreciated.
There is the choice command command that offers a default option together with a timeout.
For instance:
rem /* Wait for 10 seconds and take the default choice of `0`;
rem you can interrupt waiting with any of the keys `0` to `9` and `A` to `Z`;
rem you cannot use punctuation characters or white-spaces as choices: */
choice /C 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ /D 0 /T 10
rem // The `ErrorLevel` value is going to be set to a non-zero value.
Not the greatest of tools, but using choice with a custom message and a timeout of (5 seconds in this demo), with keystroke interrupt (any key, besides Enter esc etc.)
#echo off
choice /c qwertyuiopasdfghjklzxcvbnm1234567890 /cs /n /M "Timeout is 5 seconds.. press any key to Continue." /D c /T 5
echo 1 > null
there are a lot of ways. PING seems to be the most popular. You can try also
with w32tm
w32tm /stripchart /computer:localhost /period:5 /dataonly /samples:2 1>nul
or wtih typeperf:
typeperf "\System\Processor Queue Length" -si 5 -sc 1 >nul
with mshta:
start "" /w /b /min mshta "javascript:setTimeout(function(){close();},5000);"

Resources