I've searched already and honestly, the responses I've found so far, I don't understand enough to modify my existing code. Would appreciate any help.
I have a list of hostnames in a file called devices.txt and was provided this:
:TOP
for /f %%j in (devices.txt) do call CS.CMD %%j
:End
I then run the cs.cmd script I was provided which pings against the hostnames in the devices.txt file. Output is provided in 2 response files: Device_offline.txt
Devices_online.txt
The response files currently only contain the hostnames. I would like to have the IP addresses as well (for the devices responding), and ideally as a single line of text per devices (that way I can separate in spreadsheet if needed)
Here is the current script:
echo off
:TOP
echo %1 - Processed Device
echo.
echo Seeing if system is on.
echo.
:test
ping %1 -n 2 > pingout.lis
find "bytes="<pingout.lis
if errorlevel 1 goto badping
:goodping
echo.
echo Checking status on %1
echo
echo %1 - Device is online
echo %1 >> Device_Online.txt
goto End
:badping
echo
echo %1 - No ping response...The Device is turned off.
echo %1 >> Device_Offline.txt
GOTO End
:End
Conversely, I also have a list of IPs that I would like to ping and have offline/online output files with the associated hostname... maybe that's as easy as inputting IP addresses in the device.txt file instead of hostnames?
Appreciate any guidance, thank you!
Related
I am creating a batch file with some simple commands to gather information from a system. The batch file contains commands to get the time, IP information, users, etc.
I assembled all the commands in a batch file, and it runs, but I would like the batch file, when run to output the results to a text file (log). Is there a command that I can add to the batch that would do so?
Keep in mind I do not want to run the batch from cmd, then redirect output ; I want to redirect the output from inside the batch, if that is possible.
The simple naive way that is slow because it opens and positions the file pointer to End-Of-File multiple times.
#echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt
A better way - easier to write, and faster because the file is opened and positioned only once.
#echo off
>output.txt (
command1
command2
...
commandN
)
Another good and fast way that only opens and positions the file once
#echo off
call :sub >output.txt
exit /b
:sub
command1
command2
...
commandN
Edit 2020-04-17
Every now and then you may want to repeatedly write to two or more files. You might also want different messages on the screen. It is still possible to to do this efficiently by redirecting to undefined handles outside a parenthesized block or subroutine, and then use the & notation to reference the already opened files.
call :sub 9>File1.txt 8>File2.txt
exit /b
:sub
echo Screen message 1
>&9 echo File 1 message 1
>&8 echo File 2 message 1
echo Screen message 2
>&9 echo File 1 message 2
>&8 echo File 2 message 2
exit /b
I chose to use handles 9 and 8 in reverse order because that way is more likely to avoid potential permanent redirection due to a Microsoft redirection implementation design flaw when performing multiple redirections on the same command. It is highly unlikely, but even that approach could expose the bug if you try hard enough. If you stage the redirection than you are guaranteed to avoid the problem.
3>File1.txt ( 4>File2.txt call :sub)
exit /b
:sub
etc.
if you want both out and err streams redirected
dir >> a.txt 2>&1
I know this is an older post, but someone will stumble across it in a Google search and it also looks like some questions the OP asked in comments weren't specifically addressed. Also, please go easy on me since this is my first answer posted on SO. :)
To redirect the output to a file using a dynamically generated file name, my go-to (read: quick & dirty) approach is the second solution offered by #dbenham. So for example, this:
#echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)
Will create a file like what you see in this screenshot of the file in the target directory
That will contain this output:
Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log
Also keep in mind that this solution is locale-dependent, so be careful how/when you use it.
echo some output >"your logfile"
or
(
echo some output
echo more output
)>"Your logfile"
should fill the bill.
If you want to APPEND the output, use >> instead of >. > will start a new logfile.
#echo off
>output.txt (
echo Checking your system infor, Please wating...
systeminfo | findstr /c:"Host Name"
systeminfo | findstr /c:"Domain"
ipconfig /all | find "Physical Address"
ipconfig | find "IPv4"
ipconfig | find "Default Gateway"
)
#pause
Add these two lines near the top of your batch file, all stdout and stderr after will be redirected to log.txt:
if not "%1"=="STDOUT_TO_FILE" %0 STDOUT_TO_FILE %* >log.txt 2>&1
shift /1
There is a cool little program you can use to redirect the output to a file and the console
some_command ^| TEE.BAT [ -a ] filename
#ECHO OFF
:: Check Windows version
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
:: Keep variables local
SETLOCAL
:: Check command line arguments
SET Append=0
IF /I [%1]==[-a] (
SET Append=1
SHIFT
)
IF [%1]==[] GOTO Syntax
IF NOT [%2]==[] GOTO Syntax
:: Test for invalid wildcards
SET Counter=0
FOR /F %%A IN ('DIR /A /B %1 2^>NUL') DO CALL :Count "%%~fA"
IF %Counter% GTR 1 (
SET Counter=
GOTO Syntax
)
:: A valid filename seems to have been specified
SET File=%1
:: Check if a directory with the specified name exists
DIR /AD %File% >NUL 2>NUL
IF NOT ERRORLEVEL 1 (
SET File=
GOTO Syntax
)
:: Specify /Y switch for Windows 2000 / XP COPY command
SET Y=
VER | FIND "Windows NT" > NUL
IF ERRORLEVEL 1 SET Y=/Y
:: Flush existing file or create new one if -a wasn't specified
IF %Append%==0 (COPY %Y% NUL %File% > NUL 2>&1)
:: Actual TEE
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
> CON ECHO.%%B
>> %File% ECHO.%%B
)
:: Done
ENDLOCAL
GOTO:EOF
:Count
SET /A Counter += 1
SET File=%1
GOTO:EOF
:Syntax
ECHO.
ECHO Tee.bat, Version 2.11a for Windows NT 4 / 2000 / XP
ECHO Display text on screen and redirect it to a file simultaneously
ECHO.
IF NOT "%OS%"=="Windows_NT" ECHO Usage: some_command ³ TEE.BAT [ -a ] filename
IF NOT "%OS%"=="Windows_NT" GOTO Skip
ECHO Usage: some_command ^| TEE.BAT [ -a ] filename
:Skip
ECHO.
ECHO Where: "some_command" is the command whose output should be redirected
ECHO "filename" is the file the output should be redirected to
ECHO -a appends the output of the command to the file,
ECHO rather than overwriting the file
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Modified by Kees Couprie
ECHO http://kees.couprie.org
ECHO and Andrew Cameron
#echo OFF
[your command] >> [Your log file name].txt
I used the command above in my batch file and it works. In the log file, it shows the results of my command.
Adding the following lines at the bottom of your batch file will grab everything just as displayed inside the CMD window and export into a text file:
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt
It basically performs a select all -> copy into clipboard -> paste into text file.
This may fail in the case of "toxic" characters in the input.
Considering an input like thisIsAnIn^^^^put is a good way how to get understand what is going on.
Sure there is a rule that an input string MUST be inside double quoted marks but I have a feeling that this rule is a valid rule only if the meaning of the input is a location on a NTFS partition (maybe it is a rule for URLs I am not sure).
But it is not a rule for an arbitrary input string of course (it is "a good practice" but you cannot count with it).
I want to create a batch file to first ping a share drive on start to see if it is ready to be mapped, then map when the ping is returned. As psuedo, something like this:
while true:
ping ipaddr -t
if (ping returned):
break
map drive
I believe the syntax would be something like:
:checkping
ping ipaddr -t
if ping:
goto mountZ
fi
goto checkping
:mountZ
net use Z:....
So how do I go about setting the ping in a usable variable to break the loop?
You could use the below. If there is a TTL (Time To Live) then it will go to A, otherwise it will continue.
:checkping
ping -n 1 www.google.com | findstr TTL && goto a
goto checkping
Break
:a
REM Mapped Drive is connected
:loop
net use K: \\127.0.0.1\C$
If errorlevel 1 goto loop
Is one simple way of doing it.
#echo off
:checkping
ping 8.8.8.8 > nul
IF ERRORLEVEL 1 echo Not Connected & goto checkping
IF ERRORLEVEL 0 echo Connected & net use Z:....
pause
What I want is a command (or series of commands) that works with Windows 7, 8.1, and 10. It needs to collect user input at any time during the execution of the batch file it's in, only to checked and interpreted later. I do not mind using an input text file.
I've already searched for an answer, but the closest I've come to it is <nul set /p "input=", but it requires the user to press a key and hit enter at the exact moment the command is run. Any help would be greatly appreciated.
This method utilizes GOTO to create a loop which checks the first line of input.txt every 6 seconds or so. You could replace the content of :DOSTUFF with anything you want. Let me know if you have questions.
#echo off
GOTO DOSTUFF
:CHECKINPUT
for /f %%a in (input.txt) do (
if %%a NEQ "" (
set "input=%%a"
GOTO GOTINPUT
)
exit /b
)
GOTO DOSTUFF
:GOTINPUT
echo Thanks for the input!
echo Here is what you entered:
echo %input%
GOTO ENDER
:DOSTUFF
echo I could be doing other things here, but instead I'm just waiting for input...
PING 127.0.0.1 -n 6 >nul
GOTO CHECKINPUT
:ENDER
pause
While this was running in one window, I just ran echo test>input.txt in another command prompt.
To make this more robust you might want to overwrite the file after you check it. This can easily be done with echo.>input.txt
Good Morning,
I'm looking for a way to speed up my work with a batch file and I was wondering if anyone can help. What I'm looking for is a script to run on Command Prompt that will perform a ping on a computer name and then use the resulting ip address of that ping in a ping -a command.
At best all I can think to do is this, despite knowing that it's wrong:
#echo off
set /p asset="Enter asset: "
ping %asset%
read result
ping %result%
#pause
Any help is gratefully received.
The usual way of reading the output of a command is for/f. Choosing the correct delimiters and the right token gets you exactly what you want:
for /f "tokens=2 delims=[]" %%i in ('ping -n 1 -4 %asset%') do set result=%%i
I am creating a batch file with some simple commands to gather information from a system. The batch file contains commands to get the time, IP information, users, etc.
I assembled all the commands in a batch file, and it runs, but I would like the batch file, when run to output the results to a text file (log). Is there a command that I can add to the batch that would do so?
Keep in mind I do not want to run the batch from cmd, then redirect output ; I want to redirect the output from inside the batch, if that is possible.
The simple naive way that is slow because it opens and positions the file pointer to End-Of-File multiple times.
#echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt
A better way - easier to write, and faster because the file is opened and positioned only once.
#echo off
>output.txt (
command1
command2
...
commandN
)
Another good and fast way that only opens and positions the file once
#echo off
call :sub >output.txt
exit /b
:sub
command1
command2
...
commandN
Edit 2020-04-17
Every now and then you may want to repeatedly write to two or more files. You might also want different messages on the screen. It is still possible to to do this efficiently by redirecting to undefined handles outside a parenthesized block or subroutine, and then use the & notation to reference the already opened files.
call :sub 9>File1.txt 8>File2.txt
exit /b
:sub
echo Screen message 1
>&9 echo File 1 message 1
>&8 echo File 2 message 1
echo Screen message 2
>&9 echo File 1 message 2
>&8 echo File 2 message 2
exit /b
I chose to use handles 9 and 8 in reverse order because that way is more likely to avoid potential permanent redirection due to a Microsoft redirection implementation design flaw when performing multiple redirections on the same command. It is highly unlikely, but even that approach could expose the bug if you try hard enough. If you stage the redirection than you are guaranteed to avoid the problem.
3>File1.txt ( 4>File2.txt call :sub)
exit /b
:sub
etc.
if you want both out and err streams redirected
dir >> a.txt 2>&1
I know this is an older post, but someone will stumble across it in a Google search and it also looks like some questions the OP asked in comments weren't specifically addressed. Also, please go easy on me since this is my first answer posted on SO. :)
To redirect the output to a file using a dynamically generated file name, my go-to (read: quick & dirty) approach is the second solution offered by #dbenham. So for example, this:
#echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)
Will create a file like what you see in this screenshot of the file in the target directory
That will contain this output:
Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log
Also keep in mind that this solution is locale-dependent, so be careful how/when you use it.
#echo off
>output.txt (
echo Checking your system infor, Please wating...
systeminfo | findstr /c:"Host Name"
systeminfo | findstr /c:"Domain"
ipconfig /all | find "Physical Address"
ipconfig | find "IPv4"
ipconfig | find "Default Gateway"
)
#pause
echo some output >"your logfile"
or
(
echo some output
echo more output
)>"Your logfile"
should fill the bill.
If you want to APPEND the output, use >> instead of >. > will start a new logfile.
Add these two lines near the top of your batch file, all stdout and stderr after will be redirected to log.txt:
if not "%1"=="STDOUT_TO_FILE" %0 STDOUT_TO_FILE %* >log.txt 2>&1
shift /1
There is a cool little program you can use to redirect the output to a file and the console
some_command ^| TEE.BAT [ -a ] filename
#ECHO OFF
:: Check Windows version
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
:: Keep variables local
SETLOCAL
:: Check command line arguments
SET Append=0
IF /I [%1]==[-a] (
SET Append=1
SHIFT
)
IF [%1]==[] GOTO Syntax
IF NOT [%2]==[] GOTO Syntax
:: Test for invalid wildcards
SET Counter=0
FOR /F %%A IN ('DIR /A /B %1 2^>NUL') DO CALL :Count "%%~fA"
IF %Counter% GTR 1 (
SET Counter=
GOTO Syntax
)
:: A valid filename seems to have been specified
SET File=%1
:: Check if a directory with the specified name exists
DIR /AD %File% >NUL 2>NUL
IF NOT ERRORLEVEL 1 (
SET File=
GOTO Syntax
)
:: Specify /Y switch for Windows 2000 / XP COPY command
SET Y=
VER | FIND "Windows NT" > NUL
IF ERRORLEVEL 1 SET Y=/Y
:: Flush existing file or create new one if -a wasn't specified
IF %Append%==0 (COPY %Y% NUL %File% > NUL 2>&1)
:: Actual TEE
FOR /F "tokens=1* delims=]" %%A IN ('FIND /N /V ""') DO (
> CON ECHO.%%B
>> %File% ECHO.%%B
)
:: Done
ENDLOCAL
GOTO:EOF
:Count
SET /A Counter += 1
SET File=%1
GOTO:EOF
:Syntax
ECHO.
ECHO Tee.bat, Version 2.11a for Windows NT 4 / 2000 / XP
ECHO Display text on screen and redirect it to a file simultaneously
ECHO.
IF NOT "%OS%"=="Windows_NT" ECHO Usage: some_command ³ TEE.BAT [ -a ] filename
IF NOT "%OS%"=="Windows_NT" GOTO Skip
ECHO Usage: some_command ^| TEE.BAT [ -a ] filename
:Skip
ECHO.
ECHO Where: "some_command" is the command whose output should be redirected
ECHO "filename" is the file the output should be redirected to
ECHO -a appends the output of the command to the file,
ECHO rather than overwriting the file
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com
ECHO Modified by Kees Couprie
ECHO http://kees.couprie.org
ECHO and Andrew Cameron
#echo OFF
[your command] >> [Your log file name].txt
I used the command above in my batch file and it works. In the log file, it shows the results of my command.
Adding the following lines at the bottom of your batch file will grab everything just as displayed inside the CMD window and export into a text file:
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt
It basically performs a select all -> copy into clipboard -> paste into text file.
This may fail in the case of "toxic" characters in the input.
Considering an input like thisIsAnIn^^^^put is a good way how to get understand what is going on.
Sure there is a rule that an input string MUST be inside double quoted marks but I have a feeling that this rule is a valid rule only if the meaning of the input is a location on a NTFS partition (maybe it is a rule for URLs I am not sure).
But it is not a rule for an arbitrary input string of course (it is "a good practice" but you cannot count with it).