VBScript - Pass shell command using conditional execution with "choice" command

375 Views Asked by At

Not sure this is doable but I'm trying to write the following batch script in a single line:

@echo off

echo Shutdown initiated...
echo.
choice /c xy /n /t 10 /d y /m "To cancel shutdown press "X""
if errorlevel 2 goto EXEC
if errorlevel 1 goto ABORT

:EXEC
echo.
echo Computer shutting down 
timeout /t 10 
exit
:ABORT
echo.
echo Shutdown cancelled 
timeout /t 10
exit

The above script needs to be passed via the vbs run command into cmd. The following is the closest I can get it:

option explicit
dim wshell, strcmd

set wshell = createobject("wscript.shell")

if hour(now()) >= 0 and hour(now()) < 6 then
strcmd = "cmd /c @echo off & echo ""Pre-Dawn Shutdown initiated"" & echo. & choice /c xy /n /t 10 /d y /m ""To cancel shutdown press ""X"""" & if errorlevel 2 goto exec & if errorlevel 1 goto abort & :exec & echo. & echo ""Computer shutting down"" & timeout /t 10 & exit & :abort & echo. & echo ""Shutdown cancelled"" & timeout /t 10 & exit"
wshell.run strcmd
end if

The above works as expected up until the choice command is reached then the script fails to execute the remainder correctly. Any help in resolving this is very much appreciated.

2

There are 2 best solutions below

1
On BEST ANSWER

You can write your batch script in a single line having in mind that GOTO command directs a batch script to jump to a labelled line. Hence, you need to rewrite your script using IF… ELSE… command syntax as follows:

@echo off

echo Shutdown initiated...
echo.
choice /c xy /n /t 10 /d y /m "To cancel shutdown press "X""
if errorlevel 2 (
  rem goto EXEC
  rem :EXEC
  echo.
  echo Computer shutting down 
  timeout /t 10 
  exit
) else if errorlevel 1 (
  rem goto ABORT
  rem :ABORT
  echo.
  echo Shutdown cancelled 
  timeout /t 10
  exit
)

For debugging purposes (i.e. to see output), in next oneliner is every exit replaced with pause:

@echo Shutdown initiated...&echo.&choice /c xy /n /t 10 /d y /m "To cancel shutdown press "X""&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10&pause) else if errorlevel 1 (echo.&echo Shutdown cancelled&timeout /t 10& pause )

Output:

==> @echo Shutdown initiated...&echo.&choice /c xy /n /t 10 /d y /m "To cancel shutdown pres
s "X""&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10&pause) else if erro
rlevel 1 (echo.&echo Shutdown cancelled&timeout /t 10& pause )
Shutdown initiated...

To cancel shutdown press X X

Shutdown cancelled

Waiting for  0 seconds, press a key to continue ...
Press any key to continue . . .

==> @echo Shutdown initiated...&echo.&choice /c xy /n /t 10 /d y /m "To cancel shutdown pres
s "X""&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10&pause) else if erro
rlevel 1 (echo.&echo Shutdown cancelled&timeout /t 10& pause )
Shutdown initiated...

To cancel shutdown press X Y

Computer shutting down

Waiting for  0 seconds, press a key to continue ...
Press any key to continue . . .

Next VBScript code snippet is slightly modified, again for debugging purposes.

option explicit
On Error GoTo 0
Dim strResult: strResult = Wscript.ScriptName

dim wshell, strcmd, Return 

set wshell = createobject("wscript.shell")

if True or (hour(now()) >= 0 and hour(now()) < 6) then
  strcmd = "cmd /c @echo Shutdown initiated...&echo." & _
    "&choice /c xy /n /t 10 /d y /m ""To cancel shutdown press ""X""""" & _ 
    "&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10" & _
    "&exit /B 2) else if errorlevel 1 (echo." & _
    "&echo Shutdown cancelled&timeout /t 10&exit /B 1)"
  strResult = strResult & vbNewLine & strcmd
  Return = wshell.run( strcmd, 1, True)
  strResult = strResult & vbNewLine & CStr( Return)
end if

'strResult = strResult & vbNewLine & 

Wscript.Echo strResult

Output: pressed X on the first run and Y (or nothing) on the later.

==> cscript //nologo D:\VB_scripts\SO\39313751.vbs
39313751.vbs
cmd /c @echo Shutdown initiated...&echo.&choice /c xy /n /t 10 /d y /m "To cancel shutdown p
ress "X""&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10&exit /B 2) else
if errorlevel 1 (echo.&echo Shutdown cancelled&timeout /t 10&exit /B 1)
1

==> cscript //nologo D:\VB_scripts\SO\39313751.vbs
39313751.vbs
cmd /c @echo Shutdown initiated...&echo.&choice /c xy /n /t 10 /d y /m "To cancel shutdown p
ress "X""&if errorlevel 2 (echo. &echo Computer shutting down&timeout /t 10&exit /B 2) else
if errorlevel 1 (echo.&echo Shutdown cancelled&timeout /t 10&exit /B 1)
2

==>
1
On

This is from Win32Shutdown method of the Win32_OperatingSystem class topic in Help - https://msdn.microsoft.com/en-us/library/aa394058(v=vs.85).aspx.

Dim testResult 
Dim WMIServiceObject, ComputerObject  

'Now get some privileges 
WMIServiceObject = GetObject(
"Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}")
ForEach ComputerObject In WMIServiceObject.InstancesOf("Win32_OperatingSystem") 
    testResult = ComputerObject.Win32Shutdown(0, 0) 'logoff 
    If testResult <> 0 Then 
        MsgBox("Sorry, an error has occurred while trying to perform selected operation") 
    EndIf 
Next

This is the table saying what you want to happen. (the first parameter)

0 (0x0) Log Off - Logs the user off the computer. Logging off stops all processes associated with the security context of the process that called the exit function, logs the current user off the system, and displays the logon dialog box.

4 (0x4) Forced Log Off (0 + 4) - Logs the user off the computer immediately and does not notify applications that the logon session is ending. This can result in a loss of data.

1 (0x1) Shutdown - Shuts down the computer to a point where it is safe to turn off the power. (All file buffers are flushed to disk, and all running processes are stopped.) Users see the message, It is now safe to turn off your computer. During shutdown the system sends a message to each running application. The applications perform any cleanup while processing the message and return True to indicate that they can be terminated.

5 (0x5) Forced Shutdown (1 + 4) - Shuts down the computer to a point where it is safe to turn off the power. (All file buffers are flushed to disk, and all running processes are stopped.) Users see the message, It is now safe to turn off your computer. When the forced shutdown approach is used, all services, including WMI, are shut down immediately. Because of this, you will not be able to receive a return value if you are running the script against a remote computer.

2 (0x2) Reboot - Shuts down and then restarts the computer.

6 (0x6) Forced Reboot (2 + 4) - Shuts down and then restarts the computer. When the forced reboot approach is used, all services, including WMI, are shut down immediately. Because of this, you will not be able to receive a return value if you are running the script against a remote computer.

8 (0x8) Power Off - Shuts down the computer and turns off the power (if supported by the computer in question).

12 (0xC) Forced Power Off (8 + 4) - Shuts down the computer and turns off the power (if supported by the computer in question). When the forced power off approach is used, all services, including WMI, are shut down immediately. Because of this, you will not be able to receive a return value if you are running the script against a remote computer.