Test if process is running on remote units and output to log - batch-file

We would like to check if a certain process is running on any of our listed servers, outputting the result to a log file like this:
SERVERNAME Process is running
SERVERNAME Process is not running
I'm new to batch but this is how far I got:
FOR /F "TOKENS=*" %%A IN (LIST.TXT) DO TASKLIST /S %%A /FI "IMAGENAME EQ IEXPLORE.EXE" >> ECHO %%A D:\SEARCH.LOG

This should pretty much do what you want.
#echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (list.txt) do (
tasklist /s %%a | find /I "iexplore.exe" >nul
if !errorlevel! equ 0 (echo %%a Process is Running) else (echo %%a Process is Not Running)
) >> d:\search.log
As for your requirement on RPC errors, perhaps consider rpcping and echo to file if not available.
#echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (list.txt) do (
rpcping -s %%a |find /i "Completed" >nul
if not !errorlevel! equ 0 echo %%a RPC Server not available
tasklist /s %%a | find /I "iexplore.exe" >nul
if !errorlevel! equ 0 (echo %%a Process is Running) else (echo %%a Process is Not Running)
) >> d:\search.log

What you have, isn't far away, to get the output you asked for however, you could change your script more like this:
#ECHO OFF
(FOR /F "TOKENS=*" %%A IN (LIST.TXT
) DO TASKLIST /S %%A|FIND /I "IEXPLORE.EXE">NUL&&(Echo %%A Process is running
)||Echo %%A Process is not running)>D:\SEARCH.LOG

Related

Batch File looping until certain text is displayed

Currently have a batch file for replacing NTFS permissions using the takeown and icacls commands, i have added these commands to a loop and it works great.
Is there a way to exit the loop when a certain response is displayed? like "Failed processing 0 files" or something like that? the code i am using is below, hopefully this will help some other people also.
#echo off
setlocal enabledelayedexpansion
for /l %%x in (1,1,1000) do (
echo Taking ownsership of Folders & Files - loop %%x
for /f "delims=" %%i in ('takeown.exe /R /A /F "F:\Shares\NetBackup Clients" /D N ^| findstr /i /C:"Failed processing 0 files"') do (
set "error=%%i"
if "!errorlevel!"=="0" goto :end
)
echo Applying permissions to filestore - loop %%x
icacls.exe "F:\Shares\NetBackup Clients" /grant "Domain\Group":F /grant "Domain\Group":R /T /C
echo Finished applying permissions to filestore - loop %%x >> C:\Loopy.txt
)
goto :eof
:end
echo %error%
Many Thanks
I think you might have the error the wrong way around, so you would need to adjust it accordingly, but we use findstr and if we meet the requirement (errorlevel is 0) we exit the loop.
#echo off
setlocal enabledelayedexpansion
for /l %%x in (1,1,1000) do (
echo %%x
for /f "delims=" %%i in ('takeown.exe /R /A /F "\\fileserver\share\" /D N ^| findstr /i "Failed processing 0 files"') do (
set "error=%%i"
if "!errorlevel!"=="0" goto :end
)
echo Finished takeown >> C:\Loopy.txt
icacls.exe "\\fileserver\share\" /grant "Domain\Group":F /grant "Domain\Group":R /T /C
echo Finished icacls >> C:\Loopy.txt
echo Loop %%x >> C:\Loopy.txt
)
goto :eof
:end
echo %error%

Formatting results in .CMD

I am attempting to create a basic script that runs and checks for basic system info but I want the output to be formatted so the results are on the same line and easily readable.
#Echo Off
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
wmic cpu get name, status
systeminfo | findstr /C:"Total Physical Memory"
#echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
ECHO(Total Space: %disktotal:~0,-9% GB
ECHO(Available Space: %diskavail:~0,-9% GB
systeminfo | find "System Boot Time:"
systeminfo | find "System Type:"
Echo Antivirus: & wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed
The main example of this would be the wmic command placing the result on the next line rather than the same line.
Also any tips of better ways of scripting what I currently have would be appreciated.
#echo off
setlocal
for /f "tokens=1,* delims=:" %%A in ('systeminfo') do (
if "%%~A" == "OS Name" (
call :print "%%~A" %%B
) else if "%%~A" == "OS Version" (
call :print "%%~A" %%B
call :cpu
) else if "%%~A" == "Total Physical Memory" (
call :print "%%~A" %%B
call :fsutil C:
) else if "%%~A" == "System Boot Time" (
call :print "%%~A" %%B
) else if "%%~A" == "System Type" (
call :print "%%~A" %%B
)
)
:next
call :antivirus
pause
exit /b
:print
setlocal enabledelayedexpansion
set "name=%~1"
if not defined name exit /b
set "name=%~1 "
set "full=%*"
set "full=!full:,=!"
set "data="
set "skip1="
for %%A in (!full!) do (
if not defined skip1 (
set "skip1=defined"
) else if not defined data (
set "data=%%~A"
) else (
set "data=!data! %%~A"
)
)
echo !name:~,30!: !data!
exit /b
:antivirus
setlocal enabledelayedexpansion
set "antivirus="
for /f "tokens=*" %%A in ('
2^>nul wmic /node:localhost
/namespace:\\root\SecurityCenter2 path AntiVirusProduct
Get DisplayName /value
^| findstr /i /b /c:"DisplayName" ^|^| echo No Antivirus installed
') do set "antivirus=%%~A"
if /i "!antivirus:~,12!" == "DisplayName=" set "antivirus=!antivirus:~12!"
call :print Antivirus "!antivirus!"
exit /b
:cpu
for /f "tokens=1,* delims==" %%A in ('wmic cpu get name^, status /value') do (
call :print "%%~A" %%B
)
exit /b
:fsutil
setlocal enabledelayedexpansion
2>nul >nul net session || exit /b
for /f "tokens=1,* delims=:" %%A in ('2^>nul fsutil volume diskfree %1') do (
set "name=%%~A"
set "value=%%~B"
call :print "!name:bytes=GBs!" !value:~,-9!
)
exit /b
The fsutil command outputs alittle different.
I chose an easy option if it is OK.
Unsure of antivirus output as you need both results of
installed or not to be sure.
It only runs systeminfo once to save time.
Look at set /? for information about substitution that
is used.
The net session command is used to test if script is run as Admin.
If not Admin, then fsutil will be skipped as it requires Admin.
Look at for /? for usage of the command that is used in the script.
Use of enabledelayedexpansion is used to prevent special
characters being exposed which may cause error otherwise.
And used in code blocks to delay expansion as needed.
Remove comma from value strings which get replaced with a space.
A comma is often used as thousands separator and numbers look odd
with a space instead. This occurs because of usage of a simple
for loop interpreting comma as a argument separator. Some other
chararters may also do this though perhaps a space maybe better
than none in their case.
The output of WMIC is unicode !
The trailing <CR> can be removed by passing the value through another FOR /F loop. This also removes the phantom "blank" line (actually a <CR>)
#Echo Off
Call :GET_CPU name CPU_Name
Set "WMIC_Antivirus=wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName ^| findstr /V /B /C:displayName"
#For /F "delims=" %%I in ('%WMIC_Antivirus%') do (
for /f "delims=" %%A IN ("%%I") DO SET "Antivirus=%%A"
)
echo CPU : %CPU_Name%
echo Antivirus : %Antivirus%
pause & exit
::----------------------------------------------------
:GET_CPU
Set "WMIC_CPU=wmic cpu get name /Value"
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_CPU% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::----------------------------------------------------
You can try to save the output into a text file :
#Echo Off
:::::::::::::::::::::::::::::::::::::::::
:: Automatically check & get admin rights
:::::::::::::::::::::::::::::::::::::::::
REM --> Check for permissions
Reg query "HKU\S-1-5-19\Environment" >nul 2>&1
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
Echo.
ECHO **************************************
ECHO Running Admin shell... Please wait...
ECHO **************************************
goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B
:gotAdmin
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
SetLocal EnableDelayedExpansion
set "Log=%~dp0Log.txt"
If exist "%Log%" Del "%Log%"
Call :GET_CPU name CPU_Name
Set "WMIC_Antivirus=wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName ^| findstr /V /B /C:displayName"
#For /F "delims=" %%I in ('%WMIC_Antivirus%') do (
for /f "delims=" %%A IN ("%%I") DO SET "Antivirus=%%A"
)
(
Echo.
Echo ***************************** General infos ***********************************
Echo.
Echo Running under: %username% on profile: %userprofile%
Echo Computer name: %computername%
Echo.
systeminfo
Echo Operating System:
Echo PROCESSOR ARCHITECTURE : %PROCESSOR_ARCHITECTURE%
echo NUMBER_OF_PROCESSORS : %NUMBER_OF_PROCESSORS%
echo PROCESSOR_IDENTIFIER : %PROCESSOR_IDENTIFIER%
echo PROCESSOR_LEVEL : %PROCESSOR_LEVEL%
echo PROCESSOR_REVISION : %PROCESSOR_REVISION%
echo OS TYPE : %OS%
echo(
echo Program files path : %Programfiles%
echo Program files(86^) path : %Programfiles(86^)%
echo ProgramW6432 path : %ProgramW6432%
echo PSModulePath : %PSModulePath%
echo SystemRoot : %SystemRoot%
echo Temp Folder : %Temp%
echo CPU : !CPU_Name!
echo Antivirus : !Antivirus!
Echo.
Echo **************************** Drives infos *************************************
Echo.
Echo Listing currently attached drives:
wmic logicaldisk get caption,description,volumename | find /v ""
Echo.
Echo Physical drives information:
for /F "tokens=1-3" %%A in ('fltmc volumes^|find ":"') do echo %%A %%B %%C
)>>"%Log%"
Start "" "%Log%" & exit
::----------------------------------------------------
:GET_CPU
Set "WMIC_CPU=wmic cpu get name /Value"
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_CPU% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::----------------------------------------------------

Recursively search for specific files in all locations, including hidden with batch

I want to search all files with .xlsx extension, for now I'm using this:
for /R c:\ %%f in (*.xlsx) do set target=%%f
echo %target%
But, only searchs in "C" and does not includes the hidden files. So, my questions:
1) How can I search in all locations, I mean: C, D, E ... drives?
2) How I can search for hidden files too?
You can try something like that :
#echo off
Color 9A & Mode con cols=70 lines=5
Set "Ext=xlsx"
Title %~nx0 to search all *.%Ext% files
set "Log=%~dp0%Ext%_PATH.txt"
If Exist "%Log%" Del "%Log%"
setlocal ENABLEDELAYEDEXPANSION
for /f "tokens=2" %%i in ('wmic logicaldisk where "drivetype=3" ^|find /i ":"') do (
set "Fixed_Drive=%%i"
Call :ShowMsg !Fixed_Drive!
(
#For /f "delims=" %%x in ('Dir /b /s /a "!Fixed_Drive!\*.%Ext%"') do (
#echo "%%x"
)
)>> "%Log%"
)
Start "" "%Log%"
Exit
::******************************************************************
:ShowMsg
Cls
echo(
echo ***********************************
Echo Please wait a while Scanning "%~1"
echo ***********************************
Timeout /T 2 /nobreak>nul
exit /b
::******************************************************************
Edit :
To make a multiple search by extension like .xlsx .docx at the same time and get a separte log archive per each extension, you should try like this way :
#echo off
Color 9A & Mode con cols=70 lines=5
Set "Ext=xlsx docx"
For %%a in (%Ext%) Do (
if exist "%~dp0%%a_PATH.txt" del "%~dp0%%a_PATH.txt"
Call :Search "%%a" "%~dp0%%a_PATH.txt"
)
For %%a in (%Ext%) Do (
If Exist "%~dp0%%a_PATH.txt" Start "" "%~dp0%%a_PATH.txt"
)
Exit
::**********************************************************************************
:Search <Ext> <Log>
Cls
Title %~nx0 to search all "*.%~1 files"
echo(
echo ***********************************
Echo Please wait a while Scanning "%~1"
echo ***********************************
Timeout /T 2 /nobreak>nul
setlocal ENABLEDELAYEDEXPANSION
for /f "tokens=2" %%i in ('wmic logicaldisk where "drivetype=3" ^|find /i ":"') do (
set "Fixed_Drive=%%i"
(
#For /f "delims=" %%x in ('Dir /A:-D /b /s "!Fixed_Drive!\*.%~1"') do (
#echo "%%x"
)
)>> "%~2"
)
exit /b
::**********************************************************************************
At "for in", hidden files cannot be searched. Using option "/a" of "dir", hidden files can be srarched.
To search all of files with the extension of "xlsx" on a drive, I thought following method. But about this, each drive name has to input by user.
Drive C:
dir c:\*.xlsx /b /s /a
Drive D:
dir d:\*.xlsx /b /s /a
If you want to use data from "dir" at a batch file, how about following script?
#echo off
setlocal enabledelayedexpansion
set ct=0
for /f "usebackq tokens=*" %%a in (`dir c:\*.xlsx /b /s /a`) do (
set target[!ct!]=%%a
set /a ct=!ct!+1
)
set /a ct=%ct%-1
for /l %%i in (0,1,%ct%) do echo !target[%%i]!
The Where command searches 'hidden files', so using a method similar to Hackoo's:
#Echo(Searching...&#(For /F "Skip=1" %%A In ('WMIC LogicalDisk Where^
"DriveType>1 And DriveType!=5 And FreeSpace Is Not Null" Get DeviceID'
) Do #For %%B In (%%A) Do #For /F "Delims=" %%C In (
'Where/F /R %%B\ *.xlsx') Do #Echo=%%C)&Timeout -1

How to Detect Multiple Monitors in a Batch File

I have recently started diving into writing Batch files and I have a question. I'm trying to create a file that checks to see if my secondary monitor is connected and than if it is switches the primary display to the secondary screen. (Yes I do know about the windows+P shortcut)...
So far I have figured out that "DisplaySwitch.exe /external" sets the default display to the secondary monitor but I cannot find out how to detect whether the display is there first.
-Cheers, Luke
With Windows 10, may be just a call to:
wmic desktopmonitor get DeviceID
output:
DeviceID
DesktopMonitor1
DesktopMonitor2
More details about monitor with :
wmic desktopmonitor get
By calling a powershell from the cmd the following will get the number of monitors:
powershell -Command "exit (Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | Select-String -Pattern 'InstanceName').length"
set nMons=%ERRORLEVEL%
One possible way is to use dxdiag though it is not the fastest way:
#echo off
del ~.txt /q /f >nul 2>nul
dxdiag /t ~
w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:3 >nul 2>&1
setlocal enableDelayedExpansion
set currmon=1
for /f "tokens=2 delims=:" %%a in ('find "Current Mode:" ~.txt') do (
echo Monitor !currmon! : %%a
set /a currmon=currmon+1
)
endlocal
del ~.txt /q /f >nul 2>nul
this will print the resolutions of all monitors.
Update:
dxdiag prints info about all monitors so you can check if there are more than one monitors:
#echo off
del ~.txt /q /f >nul 2>nul
start "" /w dxdiag /t ~
for /f "tokens=1* delims=:" %%a in ('find /c "Current Mode:" "~.txt"') do (
set /a "number_of_monitors=%%b"
rem echo #%%b#
)
rem exit /b 0
echo %number_of_monitors%
rem :---- if it needed -----:
if defined number_of_monitors ( if %number_of_monitors% GTR 1 ( echo second monitor connected ) else (echo only one monitor connected ))
del ~.txt /q /f >nul 2>nul
#npocmaka's answer didn't quite work for me, but this variation of his code did (Windows 10):
rem #echo off
del %TEMP%\dxdiag.txt /q /f >nul 2>nul
start "" /w dxdiag -64bit -t %TEMP%\dxdiag.txt
for /f "tokens=3" %%f in ('find /c"Monitor Name:" %TEMP%\dxdiag.txt') do set MONITOR_COUNT=%%f
if defined MONITOR_COUNT ( if %MONITOR_COUNT% GTR 1 ( echo second monitor connected ) else (echo only one monitor connected ))
del %TEMP%\monitors.txt /q /f >nul 2>nul
SET monitors=monitors.txt
SET nMons=0
MultiMonitorTool.exe /scomma "%monitors%"
FOR /F "skip=1 tokens=9 delims=," %%a IN (%monitors%) DO IF %%a GTR 0 SET /A nMons += 1
echo Number of monitors: %nMons%
MultiMonitorTool
Here is quick way to get connected monitors count via powershell
$m = Get-PnpDevice -Class Monitor -Status OK | measure; $m.Count

detect crashed application with .bat

Hi guys is it possible to detect application crash with .bat code then restart that with .bat.
pleas give me a method.
i write a code to start and restart application but i don't know how to detect crashed application.
thank you
#echo off
cls
echo Protecting NpAPIserver from crashes...
title NpAPIServer Watchdog
tasklist /FI "aplication.exe" | find /i "aplication.exe"
for /f "tokens=2" %%x in ('tasklist ^| findstr aplication.exe') do set PIDTOKILL=%%x
IF ERRORLEVEL 2 GOTO KILLPROGRAM
IF ERRORLEVEL 1 GOTO LAUNCHPROGRAM
:KILLPROGRAM
taskkill /F /PID %PIDTOKILL%
goto LAUNCHPROGRAM
:LAUNCHPROGRAM
cd "c:\np"
start aplication.exe
goto WAITLUNCH
:WAITLUNCH
timeout /T 300
for /f "tokens=2" %%x in ('tasklist ^| findstr aplication.exe') do set PIDTOKILL=%%x
taskkill /F /PID %PIDTOKILL%
goto LAUNCHPROGRAM
(tasklist /FI "Status eq not responding"|find "lol.exe")&&rem not reponding

Resources