How to kill a single process on multiple workstations - shell

I'm trying to write a .bat file that can look at clients that are in a file (hosts.txt) and see if calculator is running and kill it or them but it keeps say there are not instances found.
#echo off
cd \
for /F "tokens=1-2" %%a in ("hosts.txt") do (
wmic /node:%%a process where name='Calculator.exe' call terminate
)
What would be a better way of doing this or what am I missing?

My comment as an answer, (one line only):
#WMIC /Node:#hosts.txt Process Where "Name='calc.exe'" Call Terminate
The answer assumes you have privileges to do so, you may need to include /user:privilegedusername and /password:privilegeduserpassword.

Related

To run a windows command over multiple files on the same time

I want to trigger a windows command over multiple files inside a directory at the same time. 'FOR' loop and other recursive methods are triggering the commands one after another. I need an alternative that can run the same command on all files at the same time. The present code I have is
#echo off
call :scan
goto :eof
:scan
for %%f in (*.txt) do *mycommand* -i %%f
for /D %%d in (*) do (
cd %%d
call :scan
cd ..
)
exit /b
The easiest way to have slow tasks running in parallel on Windows is by using the start command and calling another batch file, e.g.:
scan.bat
#echo off
echo Processing %1
dir %1
exit
main.bat
for %%f in (*.txt) do start scan.bat %%f
This will create a new window for each scan.bat instance. If you want to use the current window, use start /b scan.bat.
The exit command at the end of scan.bat is important so that the command processor exists (so that the window is closed).
In case you want to limit the number of tasks running in parallel, you should use something more powerful like gnu make (which can be used on Windows with cygwin or mingw; see Limiting the number of spawned processes in batch script for a solution using batch files (from #LotPings).

Execute Batch File With Different Process Name

I have 6 different batch scripts that I am running together at the same time. The problem is, it is difficult to differentiate between them in the Windows Task Manager because the process is always just cmd.exe I was wondering if there was a way to change the process name for a batch script to something else so that each script would be more identifiable.
I have done a lot of research on this topic so far, and the only lead that I have is creating a copy of cmd.exe in system32 that has a different name, one of my choosing. The problem is, I am not sure how I would get my bash script to use this new executable with a different name, rather than the default cmd.exe
Requirement: Must use only built in Windows functionality. I do not want to install any other programs if possible.
You can do it with something like the subroutine below. The reason for the first goto is so that you don't fall into the subroutine when you are done. I incorporate another FOR loop to iterate through a list of filenames to check. Let's get this working first.
Your existing bat file goes here
CALL :IsitRunning "SomeFileName"
The rest of your existing bat file goes here
GOTO :eof
:IsitRunning
REM 1=Filename
FOR /F "delims=" %%A in ('WMIC PROCESS WHERE NAME^='CMD.EXE' LIST FULL ^| FINDSTR /I "%~1" ^| FINDSTR /I /V WMIC') DO ECHO(%~1 is running
GOTO :eof
Or you can run this command from a CMD prompt.
wmic process WHERE NAME='cmd.exe' list full | findstr /i "SomeFileName.bat"
You can see command line in Task Manager, turn it on View menu - Choose Columns.
If you want to change process name you have to change the process. So your approach is only way.

how to send each iteration of a loop in a batch script to a new cmd window and continue with loop

Disclaimer: I'm an engineer not a programmer, so while I do have technical knowledge, please bear with me if I am using the wrong terminology or asking the wrong questions.
I am trying to write a windows batch script that will allow me to submit multiple finite element simulations as a batch with all of the same settings. I currently have a script that works after a fashion, but it is not as efficient as I would like. My current script steps through the directories and runs the simulation in the command window before moving on to the next directory and repeating the loop. This script can be seen below:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
title BEST FRM Runs batch submission
echo This script will step through the run# directories and run the blast.k file in each run# folder. The .cmd file needs to be placed in the "FRMRuns" directory. You may need to change the reference to the LSDYNA solver if the version has changed.
SET /P ANSWER=Do you want to continue (y/n)?
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={n} (goto :no)
:yes
SET /P i=Enter input file name (e.g blast.k)
SET /P n=Enter number of CPUs (e.g. 2)
SET /P m=Enter memory (e.g 500m)
FOR /D %%D IN (run*) DO (
echo %%D
cd %%D
set lstc_license=network
set lstc_license_server=###.##.##.##
::the solver reference may need to be changed as we move on to new versions
c:\LSDYNA\program\ls971_s_R5.1.1_winx64_p.exe i=%i% ncpu=%n% memory=%m%
cd ..
)
exit /b
:no
exit /b
Our network licensing for LSDYNA allows for queuing of jobs, so ideally I would like to run through the entire loop and have the jobs run simultaneously rather than run one after another. I think this would be possible if I could send each iteration of the loop to a new command window and have it execute independently while the loop in batch script continues.
I'm not sure if I am searching for the wrong things, or if this is a unique request, but I have not been able to find anything that really helps with what I am trying to do. I have tried various things using start /b cmd /k, but I have not been able to pass the loop commands to the new window and have the loop continue in the original window. I have managed to get the new window to open, but not to actually execute any commands, and the code does not continue until the new window is closed.
I would appreciate any suggestions that you might have for how to accomplish my goal.
Thank you!
This starts each command in it's own process, with the start "" at the beginning.
start "" c:\LSDYNA\program\ls971_s_R5.1.1_winx64_p.exe i=%i% ncpu=%n% memory=%m%

How to pass the output of a executable as one of args of another executable in Windows CMD?

As title,
I need to process data in my program,
which those data are needed by an existed executable.
And I want to pass data through pipe instead of writing data as a file.
My platform is Windows 7.
Any one can help me?
Thanks!
You can't use a pipe for passing output as an argument to another program. Pipes connect the STDOUT of one process with STDIN of another process.
If you want the output of the first process to be used as an argument for the second process you could do something like this:
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%a in ('p1.exe') do set output=!output! %%a
p2.exe "%output%" /foo /bar ...
endlocal

how to run several .cmd files in parallel

I have 4 .cmd files. I want to run then in parallel taking 2 at one time.
say my files are : 1.cmd, 2.cmd, 3.cmd, 4.cmd
i want to run 1.cmd and 2.cmd in parallel. Now when any of these ends , i want to run 3.cmd and then 4.cmd. In short, at any given time i want 2 of the .cmd files to run.
I am using the Start command for parallel execution. But I am new to scripting and I am getting confused on how to furmulate the above mentioned way of running the cmd files.
Any help would be appreciated.
Thanks
Debjani
I have given an answer to “Parallel execution of shell processes” once, quoted here:
Sounds more like you want to use
Powershell 2. However, you can spawn
new cmd windows (or other processes)
by using start, see also this
answer. Although you probably have to
use some other tools and a little
trickery to create something like a
"process pool" (to have only a maximum
of n instances running at a time).
You could achieve the latter by using
tasklist /im and counting how many
are already there (for loop or wc,
if applicable) and simply wait (ping
-n 2 ::1 >nul 2>&1) and re-check again whether you can spawn a new
process.
I have cobbled together a little test
batch for this:
#echo off
for /l %%i in (1,1,20) do call :loop %%i
goto :eof
:loop
call :checkinstances
if %INSTANCES% LSS 5 (
rem just a dummy program that waits instead of doing useful stuff
rem but suffices for now
echo Starting processing instance for %1
start /min wait.exe 5 sec
goto :eof
)
rem wait a second, can be adjusted with -w (-n 2 because the first ping
returns immediately;
rem otherwise just use an address that's unused and -n 1)
echo Waiting for instances to close ...
ping -n 2 ::1 >nul 2>&1
rem jump back to see whether we can spawn a new process now
goto loop
goto :eof
:checkinstances
rem this could probably be done better. But INSTANCES should contain
the number of running instances
afterwards.
for /f "usebackq" %%t in (tasklist /fo csv /fi "imagename eq
wait.exe"^|wc -l) do set
INSTANCES=%%t
goto :eof
It spawns a maximum of four new
processes that execute in parallel and
minimized. Wait time needs to be
adjusted probably, depending on how
much each process does and how long it
is running. You probably also need to
adjust the process name for which
tasklist is looking if you're doing
something else.
There is no way to properly count the
processes that are spawned by this
batch, though. One way would be to
create a random number at the start of
the batch (%RANDOM%) and create a
helper batch that does the processing
(or spawns the processing program) but
which can set its window title to a
parameter:
#echo off
title %1
"%2" "%3"
This would be a simple batch that sets
its title to the first parameter and
then runs the second parameter with
the third as argument. You can then
filter in tasklist by selecting only
processes with the specified window
title (tasklist /fi "windowtitle eq
..."). This should work fairly
reliable and prevents too many false
positives. Searching for cmd.exe
would be a bad idea if you still have
some instances running, as that limits
your pool of worker processes.
You can use %NUMBER_OF_PROCESSORS%
to create a sensible default of how
many instances to spawn.
You can also easily adapt this to use
psexec to spawn the processes
remotely (but wouldn't be very viable
as you have to have admin privileges
on the other machine as well as
provide the password in the batch).
You would have to use process names
for filtering then, though.
I have not tried this, but I assume you can do this with PowerShell. Use this type of structure:
http://www.dougfinke.com/blog/index.php/2008/01/30/run-your-powershell-loops-in-parallel/
Within this example you should be able to execute cmd/bat files.
Check out the following thread for some ideas (possible duplicate?)
Parallel execution of shell processes

Resources