Output in a file a variable in batch - batch-file

I would like to input a variable to a text file in batch. I've tried a couple of things but I can't seem to find the proper variable. Can anybody help?
Here's my code:
echo.
echo List of all recorded wifi networks and their passwords:
echo.
setlocal enabledelayedexpansion
for /f "tokens=2delims=:" %%a in ('netsh wlan show profile ^|findstr ":"') do (
set "ssid=%%~a"
call :getpwd "%%ssid:~1%%"
)
echo.
echo.
choice /M "Do you want to save results to a txt file?"
set path=%errorlevel%
if %path% EQU 1 goto save_to_txt
if %path% EQU 2 goto END
:save_to_txt
if not exist List.txt (
echo Output of Wifi password grabber.bat > List.txt
)
echo ssid: %ssid% pass: %%i>> List.txt
pause
exit /b
:END
echo This is the no area
pause
exit /b
:getpwd
set "ssid=%*"
for /f "tokens=2delims=:" %%i in ('netsh wlan show profile name^="%ssid:"=%" key^=clear ^| findstr /C:"Key Content"') do echo ssid: %ssid% pass: %%i
Epicurieux.

You cannot use %%i outside of the for loop. it is a temporary variable used by for. You don't need to use multiple labels either, just ask beforehand if you want to save to file:
#echo off & set outfile=
setlocal enabledelayedexpansion
if not exist list.txt echo Output of Wifi password grabber.bat>list.txt
choice /c yn /M "would you like log SSID results to file?
if not errorlevel 2 set "outfile=>>list.txt"
for /f "tokens=2*delims=:" %%a in ('netsh wlan show profile ^|find /i "All User Profile"') do (
set "ssid=%%~a"
for /f "tokens=2*delims=:" %%i in ('netsh wlan show profile name^="!ssid:~1!" key^=clear ^| findstr /C:"Key Content"') do (echo ssid: "!ssid:~1!" pass: %%i)%outfile%
)
or without setting variables in the for loops and without the need for delayedexpansion
#echo off & set outfile=
if not exist list.txt echo Output of Wifi password grabber.bat>list.txt
choice /c yn /M "would you like log SSID results to file?
if not errorlevel 2 set "outfile=>>list.txt"
for /f "tokens=2*delims=:" %%a in ('netsh wlan show profile ^|find /i "All User Profile"') do for /f "tokens=2*delims=:" %%i in ('netsh wlan show profile name^=%%a key^=clear ^| findstr /C:"Key Content"') do (echo ssid: %%a pass: %%i)%outfile%

As a result of my comment, (beneath the other currently existing answer), I searched my script personal collection for an example of something similar.
The following, (which may fail if certain things do not match the specific criteria under which this was designed), is intended to return the Profile name, the Interface name, the SSID, and the password Key.
Other than the addition of the 'results to file' portion of the code, it is tested on Windows 8+ [English]
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "LDN=_tmp"
For /F Tokens^=*^ Delims^=^ EOL^= %%G In ('Dir "%TEMP%" /B /A:D /O:N 2^>NUL'
) Do Set "LDN=%%G%LDN%"
MD "%TEMP%\%LDN%" 2>NUL || GoTo :EOF
For /F "Delims==" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe OS Call /? ^|
%SystemRoot%\System32\find.exe "=="') Do Set "HT=%%G"
(Set LF=^
% 0x0A %
)
For /F %%G In ('Copy /Z "%~f0" NUL') Do Set "CR=%%G"
%SystemRoot%\System32\choice.exe /M "Print WLAN Profile results to file"
If ErrorLevel 2 (Set "FOD=CON") Else Set "FOD=%~dp0list.txt"
For /F Tokens^=2^,4^ Delims^=^" %%G In ('%SystemRoot%\System32\netsh.exe WLAN
export profile key^=clear folder^="%TEMP%\%LDN%"') Do (Set "_=%%~nH"
Set "{="
For /F "Tokens=* Delims=" %%I In ('%SystemRoot%\System32\cmd.exe /V /S /D
/C %SystemRoot%\System32\findstr.exe /R /I /C:"<keyMaterial>"^
/C:".*!CR!*!LF![\ \%HT:~-1%]*<\/SSID>" "%%H"') Do (Set "]=%%I"
SetLocal EnableDelayedExpansion
If "!]:~-6,1!" == "/" (For %%J In ("!]:~,-7!") Do (EndLocal
Set "}=%%~J")) Else For %%J In ("!]:~,-14!") Do (EndLocal
Set "{=%%~J")
If Defined { (SetLocal EnableDelayedExpansion
For /F Tokens^=*^ Delims^=^ EOL^= %%K In ('
Echo(^| Set /P "=!_:-%%G="^&:"!" 0^<NUL') Do (
(Echo Name="%%G" Interface="%%K" SSID="!}:*>=!" Key="!{:*>=!"
) 1>>"%FOD%" & EndLocal))))
RD /Q /S "%TEMP%\%LDN%"
If /I "%FOD%" == "CON" (Setlocal EnableDelayedExpansion
For /F "Tokens=1,2" %%G In ("!CMDCMDLINE!") Do (Endlocal
If /I "%%~nG" == "cmd" If /I "%%~H" == "/C" Pause))
EndLocal
GoTo :EOF
The file list.txt, if you choose to write to one, will be located along side the batch file, %~dp0, it should create it if it does not exist, or add to it, if it does.

Related

How to detect a pendrive by cmd (BATCH)

I'm making a program that needs a pendrive, and I want detect if a pendrive is in the pc and distinguish he from a internal disk or anything else, somebody can help me?
Here's an example.
#Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
For /F "Skip=2 Tokens=*" %%A In ('WMIC DiskDrive Where InterfaceType^="USB"^
Assoc /AssocClass:Win32_DiskDriveToDiskPartition 2^>Nul') Do (
For /F UseBackQ^ Delims^=^"^ Tokens^=2 %%B In ('%%A') Do (
For /F Delims^=^":^ Tokens^=6 %%C In (
'WMIC Path Win32_LogicalDiskToPartition^|Find "%%B"') Do (
For /F "Skip=1 Delims=" %%D In ('WMIC LogicalDisk Where^
"DeviceID='%%C:'" Get DeviceID^, VolumeName') Do Echo( %%D
Set "_C=!_C!%%C")))
If Not Defined _C Echo( You do not have a USB drive connected && GoTo :EndIt
If "%_C:~,1%" Equ "%_C%" GoTo :Picked
Echo( Enter the USB drive letter from the above [%_C%]:
For /F "Delims=? Tokens=2" %%A In ('Choice /C %_C%') Do Set "Letter=%%A:"
:Picked
If Not Defined Letter (Call :Task %_C%:) Else (Call :Task %Letter%)
:EndIt
>Nul Timeout 5
Exit/B
:Task
Rem Place your commands here
Echo Your selected pen drive is %1
Pause

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

Set doesn't work in for + if in bat script, even if set ENABLEDELAYEDEXPANSION

My Script (a.bat):
SETLOCAL ENABLEDELAYEDEXPANSION
if "%1"=="on" (
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (set lanst=%%a)
set lanst=%lanst: =%
echo Local Area Connection: %lanst%
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (set curwifi=%%b)
set curwifi=%curwifi: =%
echo Current Wifi: %curwifi%
)
When I run this script in commandline, seems the set dosen't work in for + if:
But when I remove if-statement, the script is:
SETLOCAL ENABLEDELAYEDEXPANSION
echo %1
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (set lanst=%%a)
set lanst=%lanst: =%
echo Local Area Connection: %lanst%
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (set curwifi=%%b)
set curwifi=%curwifi: =%
echo Current Wifi: %curwifi%
the result shows:
According the output, I found, in the situation of if+for, seems the statement in do() will not be executed.
Why's that, and how to fix?
try with:
SETLOCAL ENABLEDELAYEDEXPANSION
if "%1"=="on" (
FOR /F "tokens=1" %%a in ('netsh interface show interface ^| findstr Local') DO (
set lanst=%%a
)
set lanst=!lanst: =!
echo Local Area Connection: !lanst!
FOR /F "delims=: tokens=2" %%b in ('netsh wlan show interface ^| findstr SSID ^| findstr /v B') DO (
set curwifi=%%b
)
set curwifi=!curwifi: =!
echo Current Wifi: !curwifi!
)
here's more info about the delayed expansion

Can a .bat Script Copy Marked Text From One File to A Marked Location in Another File?

In the source file I have:
...
<!-- MARK_BEGIN -->
some text line 1
some text line 2
...
<!-- MARK_END -->
...
that I want to copy the above marked content, without the begin/end marks, into a destination file, either at the very beginning, the very end, or at a location marked as:
...
<!-- INSERT_HERE -->
...
The command would be:
copyMarkedContent.bat sourceFile destFile [TOP | BOTTOM | MARKED ]
The sourceFile is guaranteed to have the lines containing MARK_BEGIN and MARK_END in them. The destFile is guaranteed to have the line containing INSERT_HERE if the MARKED argument is given to the copyMarkedConent.bat command.
Is there a way to do this with a .bat script on Windows (Windows 7 or Windows 2008) using just those facilities that come with the OS?
I haven't tested this, but I think it'll do what you are looking for. If there's an error in it, at least it'll get you started.
#echo off
setlocal enabledelayedexpansion
if #%3==# goto usage
:: convert %3 to upper case
for /f "tokens=5" %%I in ('find "" "%3" 2^>^&1') do set arg=%%I
for %%I in (TOP BOTTOM MARKED) do (if "%arg%"=="%%I" goto next)
:usage
echo usage: %~nx0 sourceFile destFile [TOP^|BOTTOM^|MARKED]
goto :EOF
:next
set /p I="Scraping data from %1... "<NUL
set tempfile=~%time::=%.txt
set tempfile=%tempfile: =%
set tag=0
for /f "tokens=1,2* delims=:" %%H in ('findstr /n ".*" %1') do (
if not "%%J"=="" (set line=%%I:%%J) else (set line=%%I)
if !tag!==1 (
for /f "tokens=*" %%x in ('echo "!line!" ^| find /i "<!-- mark"') do (
echo Done.
goto %arg%
)
if "!line!"=="" (echo;>>%tempfile%) else (echo !line!>>%tempfile%)
)
for /f "tokens=*" %%x in ('echo "!line!" ^| find /i "<!-- mark"') do set tag=1
)
:TOP
set /p I="Prepending data to %2... "<NUL
type %2>>%tempfile%
move /y %tempfile% %2 >NUL
echo Done.
goto :EOF
:BOTTOM
set /p I="Appending data to %2... "<NUL
type %tempfile%>>%2
del /q %tempfile%
echo Done.
goto :EOF
:MARKED
set /p I="Inserting data into %2... "<NUL
set tag=0
set tempfile2=~%time::=%_2.txt
set tempfile2=%tempfile2: =%
for /f "tokens=1,2* delims=:" %%H in ('findstr /n ".*" %2') do (
if not "%%J"=="" (set line=%%I:%%J) else (set line=%%I)
if "!line!"=="" (echo;>>%tempfile2%) else (echo !line!>>%tempfile2%)
if !tag!==0 (
for /f "tokens=*" %%x in ('echo "!line!" ^| find /i "<!-- insert"') do (
set tag=1
type %tempfile%>>%tempfile2%
del /q %tempfile%
)
)
)
move /y %tempfile2% %2 >NUL
echo Done.
EDIT 1 : I made the checks for <!-- MARK and <!-- INSERT case insensitive and not dependent on having no spaces before.
EDIT 2 : I broke down and actually started testing my changes. I made a few changes to ensure that indentation and other formatting gets preserved, and the script tests successfully on my Win 7 machine.

Resources