Stuck in cmd script loop - windows

I'm using a script that, upon logging in, loads Remote Desktop Protocol (RDP) and pushes the user to a Virtual Desktop Environment (VDI), along with their credentials. The script does not allow the next command 'Shutdown /l' to run until it is finished running.
The problem I'm having is that once in the VDI, RDP tries to load up again. How do I prevent this from happening? Thank you in advanced.
start /wait \\ph-vda\C$\VDI_Users_RDP\%username%.rdp /multimon /noConsentPrompt
Shutdown /l

I think what you're describing is that the same script is running when the user logs in, even when they log into the VDI. You don't want the script to run in the VDI. If that's right, here's one idea.
#echo off
if exist "%userprofile%\in_vdi" goto :eof
type nul >"%userprofile%\in_vdi"
start /wait \\ph-vda\C$\VDI_Users_RDP\%username%.rdp /multimon /noConsentPrompt
del "%userprofile%\in_vdi"
Shutdown /l

Related

set batch script for loop to NOT wait for previous iteration to complete

I have the following script which launches multiple sessions of RDP connection files at once (colleted from a folder which only contains rdp files).
If I launch this from cmd prompt, it launches all sessions in parallel (which is what I want)
for /r %i in (*.rdp) do (mstsc %~nxi /f)
**while **if i run this script, it just launches the first session then waits for the relative process to end before running the second connection and so on.
for /r %%i in (*.rdp) do (mstsc %%~nxi /f)
What I'm doing wrong? Shouldn't it be the default behavior of batch to run all commands in parallel?
I've checked this but it doesn't address my exact scenario and it doesn't work anyhow as expected (e.g. START myBatchScript.bat doens't change the "waiting for process" behavior)
EDIT
Added answer based on comments (Thanks to #Compo and #Modi)
The coding solution to replicate the cmd behavior as a batch script is using the "start" command (as below, thanks to #Compo)
#for /r %i in (*.rdp) do #(start "" mstsc "%~nxi" /f)
for the reason why this happens refer to #Mofi comments.

Read variable from external file not working on running as scheduled task

I would like to run a batch file after resuming from sleep state in Windows.
If I start the batch file on command line everything works as expected.
But the batch script does not run properly as scheduled task.
What I have done:
External config file AutoMountConf.bat contains set Pass = Test
Local script file scheduleTask.bat contains
rem AutoMountConf.bat is in my intranet.
call X:\AutoMountConf.bat
start "" "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q
On command line the TrueCrypt container is mounted.
If I run the script from scheduled task I get the login screen to type the password manually.
There are two or perhaps even three issues.
The first one is set Pass = Test instead of set "Pass=Test" as Stephan reported already. For more details on how to assign a value right to an environment variable see my answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line?
The second issue is caused by the fact that network drives once mapped by a user to a drive letter and remembered in registry by Windows are automatically disconnected by Windows on user logs off and are only reconnected if the same user logs on again.
For a scheduled task it is therefore very often necessary to use UNC paths for files and folders on a shared folder in network or connect the network drive and disconnect it in the batch file itself executed as scheduled task.
It is not possible to call a batch file with UNC path. Windows does not allow that. Therefore it is necessary to connect and disconnect to network share manually in the batch file. I offer 2 solutions for this problem.
The first one is using command net use:
%SystemRoot%\System32\net.exe use X: \\ComputerName\ShareName password /user:Domain\UserName /persistent:no
if not errorlevel 1 (
call X:\AutoMountConf.bat
%SystemRoot%\System32\net.exe use X: /delete
start "" /wait "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q
)
password and /user:Domain\UserName is necessary only if the scheduled task is not executed with a user account which has the permissions to access the batch file on the remote machine. In general it is much more secure to define the scheduled task with the right user account and safe the password also for this account together with the task. Windows stores the password for the task encrypted like it does it also for the user account itself.
Run in a command prompt windows net use /? for details on the required and optional options. /persistent:no is what avoids remembering the network share in Windows registry for automatic reconnect after login by same user.
The second one is using commands pushd and popd:
pushd \\ComputerName\ShareName
if not errorlevel 1 (
call AutoMountConf.bat
popd
start "" /wait "C:\Program Files\TrueCrypt\TrueCrypt.exe" /auto favorites /p %Pass% /q
)
Please execute in a command prompt window pushd /? and read the output help to understand why this works.
But this solution requires that the user account used for the scheduled task with correct password is one which has appropriate permissions on the share on the remote computer. Password and user name can't be specified with this solution in the batch file itself.
if not errorlevel 1 means if previous command exited NOT with a value greater or equal 1 meaning if exit code of previous command is 0 and therefore command execution was successful. It can always happen that the remote machine is currently not available on network and therefore it is always good to check success on connecting to share on remote machine.
There is perhaps one more reason why Pass is not defined after running AutoMountConf.bat.
AutoMountConf.bat contains setlocal and the variable Pass is defined after this command was executed and before endlocal is executed in same batch file or implicitly called by command processor on exiting AutoMountConf.bat.
setlocal results in creating always a copy of existing environment variables and all modifications on environment variables are done on this local copy. The previous environment variables are restored on execution of (matching) endlocal or when end of a batch file is reached in which case the command processor automatically restores previous environment.
Please execute in a command prompt window setlocal /? and read the output help.
For examples to understand environment management by commands setlocal and endlocal perhaps even better see answers on Echoing a URL in Batch and Why is my cd %myVar% being ignored?
set Pass = Test
sets a variable pass<space> with the Content <space>Test. So %pass% keeps empty.
use this Syntax:
set "Pass=Test"
to avoid any unintended spaces.

How to close Windows console automatically (send CTRL+C to console programatically)?

I have two windows batch scripts, script1.bat and script2.bat. script2.bat is launched from script1.bat.
script1.bat:
...
start call script2.bat
...
script2.bat has to be closed when user closes script1.bat's console (in another words, script2.bat and its console should be closed automatically when script1.bat is closed). But script2.bat should not be killed, It should be terminated because script2.bat has to release database connection. I mean unix signal teminology by using kill and terminate words. So scrip2.bat should not be killed immediately, it should be terminated in way that allows the process to perform nice termination releasing resources and saving state if appropriate.
I made it for unix system and I resolved it as following.
script1.sh:
...
sh script2.sh > /dev/null 2>&1 &
script2_pid="$!"
trap 'kill -15 $script2_pid' EXIT HUP TERM INT KILL
...
How to make it on Windows?
====EDIT====
I think that my question is not entirely clear for everyone so I would like to clarify it.
I have java application which connects to JBoss application server. It is tested now and I need to launch both in very convenient way. I prepared batch script (script1.bat)which starts both, client application and JBoss application. This script also do another things like setting environment variables. So script2.bat is a Jboss standalone.bat file in fact. I wouldn't like to edit this file.
script1.bat is my script, it sets environment variables, start JBoss and start my java application.
My script (script1.bat):
...
set environment variable
...
REM start jboss
start standalone.bat
REM start my java application
java ...
When user closes Java application, JBoss should also be closed. I need it only for tester's convenient and I know that in production environmnet it should work in another way.
I don't know how to terminate JBoss automatically after user closes my java client application. JBoss connects to H2 database and creates lock on it so if JBoss will be killed immediately then database lock is still there. If JBoss process receives CTRL+C it terminates properly (removes database lock). I want to make it automatically, After user closes java client application, JBoss has to be closed as it receives CTRL+C.
I have no idea how to do it on Windows. But I did it on linux and I added my code to this question.
Sorry, but your script makes no sense. start call script2.bat?? The combination of start and call is nonsense. You use either one or the other but not both.
Further I have to disappiont you. There is no way to close a console but keep the code running. You can't even start a hidden console in Windows. Closing the console will instantly stop the execution of the code.
EDIT:
Now I understand what you are asking. Start your first script using
start "somename" script1.bat
This will start script1 in a console with "somename" as window title.
In the second script you can use this:
:WORKING
REM Do some stuff here
REM and here
REM and here
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections
REM exit script2
This part will check if the a console with "somename" in the title is running and if yes reenter the loop. At the end of the loop it alway checks whether script1 is still active. As soon as it's not found the code goes on to the shutdown part.
If you only want to wait for script1 to terminate you can use PING -n 5 127.0.0.1 > NUL as a 5 (or longer, just replace the 5 ^^) second timeout to avoid busy-waiting:
:WORKING
PING -n 5 127.0.0.1 > NUL
FOR /f "tokens=*" %%A IN ('tasklist^ /v^| findstr /i /c:"somename"') DO GOTO WORKING
REM shutdown part
REM close db connections etc.
REM exit script2
If CLI is enabled in JBoss then JBoss can be shutdowned by CLI. Following batch shows how to shutdown JBoss
...
set environment variable
...
REM start jboss
start "UNIQUE_NAME" path_to_JBoss\bin\standalone.bat -c standalone.xml
REM start java application
java ...
REM shutdown JBoss by CLI
call path_to_JBoss\bin\jboss-cli.bat --connect ":shutdown"
REM it is just in case. If CLI did not shutdown JBoss, then following line kills JBoss without release of resource.
FOR /f "TOKENS=1,2,*" %%a IN ('tasklist^ /FI "WINDOWTITLE eq UNIQUE_NAME*" /nh') DO taskkill /pid %%b

Windows shutdown not working as expected

I'm trying to remotely shutdown computers in my lab with the commands:
shutdown /s /m 192.168.1.57
shutdown /s /m 192.168.1.56
Shutdown occurs properly when I run each command separately. But when I combine them via:
shutdown /s /m 192.168.1.57 & shutdown /s /m 192.168.1.56
only one machine shuts down, then Windows gives an error:
The entered computer name is not valid or remote shutdown is not supported on the target computer. Check the name and then try again or contact your system administrator.(53)
Any ideas how to troubleshoot/resolve?
same issue occurs when I combine the commands in a batch file.
systems all running Win 7, connected to the same workgroup.
bear in mind that I am not an IT professional.
Thanks in advance.
Another forum pointed me to a workaround/correct implementation. I just need to put a "cmd /k" between the & and the 2nd command. Still not sure why my ampersand combination didn't work.
there is nothing like (&) to combined the command.. I don't think you can do it like this.
You have to write the address with separate shutdown command. CMD doesn;t provide such a way to concatenate or pass array or arguments..

RDP kill a program specifically

I know that you can use tskill to kill processes in a batch file, among other things, but...I have users that remote desktop into a Windows Server 2003 box to run a Microsoft Access program. Occasionally, if someone RDPs in the Access Program will already be open (meaning they have entered someone else's session). This means they are using someone else's Access log on and I have certain forms that record that info and use it to autoemail people reminders. Since everyone uses the same program only on the server, I have all rdp login as the same user. When I tried to do a tskill batch program for msaccess.exe, it killed the Access of everyone logged in--doh! I can't see making everyone log in when they rdp in, so I am hoping the answer isn't make a log in for everyone in the enterprise and then get to their computers to change their save rdp log on information. Is there a way to run something like tskill for ONLY the current session? The batch command I was using is taskkill /f /im msaccess.exe . Thank you in advance for your time and your replies.
I believe this script will do the trick.
:: Find the current session.
FOR /F "tokens=3 delims= " %%F IN ('query session %USERNAME%') DO SET SESSIONID=%%F
:: Kill all msaccess processes *in this specific session*.
taskkill /FI "SESSION eq %SESSIONID%" /IM msaccess.exe /F

Resources