Batch script stops executing after winrs command - windows

I have a script that contains a call to winrs in order to remotely start the execution of a .exe on a user specified target machine.
I want the following functionality:
start script
prompt user for name of target PC
winrs into target PC executing the .exe and tell user who ran the script that this is being done.
stop the execution of winrs and tell the user who ran the script that it has finished.
exit.
I want all the output on the machine that the script was run on and don't want any show of activity on the target machine.
The code I have is as follows:
#echo off
echo -------------------------------------------------------
echo PLEASE ENTER PC NAME OF DISCONNECTED MACHINE
echo -------------------------------------------------------
SET /p pcToReconnect=
echo Attempting to contact Agent.
call winrs -r:%pcToReconnect% "C:\Path\To The\exe that I want\toExecute.exe" >> logfile.txt 2>>&1
echo Agent reconnected. Please allow ~5mins for your management console to update.
The code executes until the winrs call, and it does infact execute the .exe on the target machine, but it seems then that the remote shell just stays open doing nothing after this.
If I push ctrl+c at this point "Terminate the shell? (y/n)" gets placed in my logfile, (but no output in the cmd prompt) and I can then push "y" and enter, upon which the remote shell exits and "Terminate batch job (Y/N)" appears in the cmd prompt, however the last echo statement never executes.
How can I get the remote shell to automatically close after the .exe has been run, and echo some sort of confirmation that the script has completed on the prompt of whoever has executed it?
All help appreciated!

You are using call which executes a new cmd.exe window and running winrs in that new window and exiting.
Remove it and it will work. I added pause at the end, in case you are running batch by double clicking it.
#echo off
echo -------------------------------------------------------
echo PLEASE ENTER PC NAME OF DISCONNECTED MACHINE
echo -------------------------------------------------------
SET /p pcToReconnect=
echo Attempting to contact Agent.
winrs -r:%pcToReconnect% "C:\Path\To The\exe that I want\toExecute.exe" >> logfile.txt 2>>&1
echo Agent reconnected. Please allow ~5mins for your management console to update.
pause
EDIT
After some analysis it seems that the batch is waiting for the program to finish, so it would be possible to just call it with start which should call it and return to the original prompt.
start winrs -r:%pcToReconnect% "C:\Path\To The\exe that I want\toExecute.exe" >> logfile.txt 2>>&1

Related

running windows commands remotely

I'm trying to run a command remotely.
Here is what I've tried
wmic /node:"my_server" /user:my_username /password:my_pass process call create "cmd.exe \c dir C:>C:\temp\x.txt"
I can see the process id returned and I see a terminal running on the remote machine with that process id and that process is just stuck and the output x.txt is not generated.
Any idea how to make it work?
Any idea why the process is running but not doing anything?
My goal is to get the output back so it is not necessary to write to a file.

Shell script for .bat to quit telnet window upon logging off app

I have an app' which is started from within run.bat; this connects through a telnet server.
Upon logging off the app' the end user is returned to the telnet service which we don't want, as workers would have access to it.
So I'm looking for a way to close the window but keep the telnet server active at the same time.
This is the telnet alluser.bat which will lead into our app' run.bat:
ALLUSER.BAT:
echo ================================================================
echo .\scripts\allusers.bat
echo this script is executed for all users
echo delete/rename it if you dont need it
echo ================================================================
chcp 437
cd %USERPROFILE%
start "" "C:\davinci\dvrfapp\run.bat"
RUN.BAT:
start C:\davinci\dvrfapp\dvrfapp.exe c:\davinci\dvrfapp\config.json
exit
The exit part on the run bat is to close the previous window left open for the ALLUSER.BAT.

How can I return from a shell script and then reboot (to use with VirtualBox)?

I am using guestcontrol with Virtual Box with a Windows host and a Linux (RHEL7) guest. I want to do some config from the host to the guest by running a shell script on the guest (from a .bat on the host). This is fine and the script runs, however, it hangs when I call the reboot (I believe it is because nothing is returned). So when the following .sh is called:
#!/bin/bash
echo "here"
exit
The .bat file shows "here" and then exits (or if I use pause gives the correct message). However, when I add the reboot, the .bat never processes anything past where it calls the script. I think this would be because the guest never tells the host that the script is complete.
I have tried things like:
#!/bin/bash
{ sleep 1; reboot; } >/dev/null &
exit
or even:
#!/bin/bash
do_reboot(){
sleep 1
reboot
}
do_reboot() &
exit
but the .bat never gets past the line where it runs the .sh
How can I tell the host that the .sh script (on the guest) is complete so it can continue with the .bat script?
We need to make sure there are no sub processes running, so we want to do a no heads up using the nohup command. So the script simply becomes this:
#!/bin/bash
nohup reboot &> /tmp/nohup.out </dev/null &
exit
The stdin and stdout were causing the issues, so this just sends them into the void so that the script will not be waiting for any input from any other processes.
If you have any issues with this script, you could do something like:
#!/bin/bash
nohup /path/to/reboot_delay.sh &> /tmp/nohup.out </dev/null &
exit
And then in /path/to/reboot_delay.sh you would have:
#!/bin/bash
sleep 10 # or however many seconds you need to wait for something to happen
reboot
This way you could even allow some time for something to finish etc, yet the host machine (or ssh or wherever you are calling this from) would still know the script had finished and do what it needs to do.
I hope this can help people in future.

Why does a non-interactive batch script think I've pressed control-C?

So my batch script is ticking along nicely when suddenly this appears in the output log:
21:27:13.99 c:\apps\w7lab-scripting>some-command
Error 3221225786
^CTerminate batch job (Y/N)?
and the script stops dead.
The batch script is running in session zero, so I know it didn't receive a real control-C, and none of my code calls GenerateConsoleCtrlEvent so that can't be it. The only clue is that some-command was communicating with an interactive application at the time, and that application's console received a control-C. The expected behaviour was for some-command to display the other application's exit code, then exit with the same code. The batch script would have dealt with the error appropriately, if it hadn't stopped dead.
What's going on here?
The magic here is in exit code 3221225786, aka 0xC000013A or STATUS_CONTROL_C_EXIT.
The interactive application received a control-C, and didn't catch it, so as expected, it was aborted with STATUS_CONTROL_C_EXIT. The some-command application correctly reported this as the remote application's exit code, and passed it back to the batch script.
What I hadn't realized was that cmd.exe detects control-C in a batch script in exactly this way, by checking whether a child process returns STATUS_CONTROL_C_EXIT. So by returning this error code I was inadvertently stopping the batch script.
This can be demonstrated with a simple batch script:
cmd /c exit 3221225786
echo hello
which, when run, produces
C:\working\test>cmd /c exit 3221225786
^CTerminate batch job (Y/N)?
Alternatively, it is possible to terminate batch session using commands that provoke brutal batch end (from https://superuser.com/a/805637), any of the following (attempting to feed STDERR to STDIN breaks):
cd invalidPath 2>&0
vol x 2>&0
move nonExistentFile 2>&0
set nonExistentVariable 2>&0
dir nonExistentFile 2>&0
So, a subroutine could be:
:SubSelfTerminate
cd invalidPath 2>&0
exit /b 0
which would be called from Main batch as:
call :SubSelfTerminate
Note: "exit /b 0" in subroutine is useless as will always be ignore it is used but mark the end the subroutine.

Running remotely Linux script from Windows and get execution result code

I have the current scenario to deal with:
I have to schedule the backup of my company's Linux-based server (under Suse Linux) with ARCServe R15 (installed on Windows 2003R2SP2).
I know I have the ability in my backup software (ARCServe) to add pre/post execution scripts to my backup-jobs.
If failure of the script, ARCServe would be specified NOT to run the backup-job, and if success, specified to be run. I have no problem with this.
The problem is, I want to make a windows script (to be launched by ARCServe) for executing a Linux script on the cluster:
- If this Linux-script fails, I want my windows-script to fail, so my backup job in ARCServe wouldn't run
- If the Linux-script success, I want my windows-script to end normally with error code 0, so my ARCServe job would run normally.
I've tried creating this batch file (let's call it HPC.bat):
echo ON
start /wait "C:\Program Files\PUTTY\plink.exe" -v -l root -i "C:\IST\admin\scripts\HPC\pri.ppk" [cluster_name] /appli/admin/backup_admin
exit %errorlevel%
If I manually launch this .bat by double-clicking on it, or launching it in a command prompt under Windows, it executes normally and then ends.
If I make it being launched by ARCServe, the script seems never to end.
My job stays in "waiting" status, it seems the execution code of the linux script isn't returned to my batch file, and this one doesn't close.
In my mind, what's happening is plink just opens the connection to the Linux, send the sript execution signal, and then close the connection, so the execution code can't be returned to the batch. Am I right ?
Is what I want to do possible or am I trying something impossible to do ?
So, do I have to proceed differently ?
Do I have to use PUTTY or CygWin instead of plink ?
Please, it's giving me headaches ...
If you install Cygwin, you could do it exactly like you can do it on Linux to Linux, i.e. remotely run a command with ssh someuser#remoteserver.com somecommand
This command will return with the same return code on the calling client, as the command exited with on the remote end. If you use SSH shared keys for authentication instead of passwords, it can also be scripted without user interaction.

Resources