Formatting results in .CMD - batch-file

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
::----------------------------------------------------

Related

Output in a file a variable in batch

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.

IF NOT EXIST causing failure in batch file

I'm trying to execute a script that pulls a bunch of information for me. It was working until I removed my pause break points and re-introduced the IF NOT EXIST (which was working before I added the CPU get name and the part that pulls RAM info). Now the file will not run at all.
Using pause and echo, I have managed to find out that the script stops at IF NOT EXIST. If I add a pause between %location% and ( the script pauses then starts working from there. I have no idea why this is and I need this to run as silently as possible with NO interaction by the user.
REM Set save location
REM set location="\\colfs1\public\inventory\%computername%.txt"
SET location="c:\users\jpell\desktop\%computername%.txt"
REM If file is not there create it and populate info
pause
IF NOT EXIST %location% (
pause
systeminfo | findstr /i /b /c:"host name" /c:"os name" /c:"os version" /c:"original" /c:"system manu" /c:"system model" >> %location%
pause
#echo. >> %location%
pause
wmic /append:%location% bios get serialnumber
pause
wmic /append:%location% computersystem get systemtype
pause
wmic /append:%location% cpu get name
pause
REM Script to pull RAM info taken from StackOverflow
Set "WMIC_TOTMEM=wmic ComputerSystem get TotalPhysicalMemory /format:Value"
Set "WMIC_Capacity=wmic memorychip get capacity /format:Value"
Set "CAP=Capacity"
Set "TOT=TotalPhysicalMemory"
Call :GetTOTMEM %TOT% TotalPhysicalMemory
Call :GetCapacityMem %CAP% Capacity
Call :Convert %TotalPhysicalMemory% TotalPhysicalMemory_Converted
Call :Convert %Capacity% Capacity_Converted
echo -------------------------------------------------
echo TotalPhysicalMemory = %TotalPhysicalMemory%
echo Memorychip Capacity = %Capacity%
echo -------------------Converted---------------------
echo TotalPhysicalMemory = %TotalPhysicalMemory_Converted% >> %location%
echo Memorychip Capacity = %Capacity_Converted% >> %location%
echo -------------------------------------------------
GOTO :Continue
pause
::-------------------------------------------------------
:GetCapacityMem
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_Capacity% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::-------------------------------------------------------
:GetTOTMEM
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_TOTMEM% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::-------------------------------------------------------
:Convert
Set "VBS=%Temp%\%Random%.vbs"
(
echo wscript.echo Convert("%~1"^)
echo 'Function to format a number into typical size scales
echo Function Convert(iSize^)
echo aLabel = Array("bytes", "KB", "MB", "GB", "TB"^)
echo For i = 0 to 4
echo If iSize ^> 1024 Then
echo iSize = iSize / 1024
echo Else
echo Exit For
echo End If
echo Next
echo Convert = Round(iSize,2^) ^& " " ^& aLabel(i^)
echo End Function
)>"%VBS%"
for /f "delims=" %%a in ('Cscript //NoLogo "%VBS%"') do set "%2=%%a"
Del "%VBS%"
Exit /b
::-------------------------------------------------------
REM Continue the script after pulling RAM
:Continue:
#echo. >> %location%
#echo Current User: >> %location%
whoami >> %location%
#echo. >> %location%
#echo Forticlient or Sophos: >> %location%
wmic product get version,vendor | findstr /i /c:"forti" /c:"sophos" >> %location%
pause
)
pause
This script pulls a bunch of hardware information from a computer and puts it into a text file. This file is then used for inventory purposes. The information is populating with the pause in there and when the IF NOT EXIST is REMed out.
Yes, follow your own comment and reverse the logic:
if exist "%location%" goto :Jumpover
to avoid :labels and pseudo labels ::-- inside (code blocks)
All your pause commands for debugging could also be put in a variable %dbg%
and switched on/off on demand to not have to change much of the code.
Untested:
REM Set save location
REM set location="\\colfs1\public\inventory\%computername%.txt"
SET location="c:\users\jpell\desktop\%computername%.txt"
REM If file is not there create it and populate info
set "dbg=pause"
::set "dbg=Rem"
%dbg%
IF EXIST "%location%" goto :JumpOver
%dbg%
systeminfo | findstr /i /b /c:"host name" /c:"os name" /c:"os version" /c:"original" /c:"system manu" /c:"system model" >> %location%
%dbg%
#echo. >> %location%
%dbg%
wmic /append:%location% bios get serialnumber
%dbg%
wmic /append:%location% computersystem get systemtype
%dbg%
wmic /append:%location% cpu get name
%dbg%
REM Script to pull RAM info taken from StackOverflow
Set "WMIC_TOTMEM=wmic ComputerSystem get TotalPhysicalMemory /format:Value"
Set "WMIC_Capacity=wmic memorychip get capacity /format:Value"
Set "CAP=Capacity"
Set "TOT=TotalPhysicalMemory"
Call :GetTOTMEM %TOT% TotalPhysicalMemory
Call :GetCapacityMem %CAP% Capacity
Call :Convert %TotalPhysicalMemory% TotalPhysicalMemory_Converted
Call :Convert %Capacity% Capacity_Converted
echo -------------------------------------------------
echo TotalPhysicalMemory = %TotalPhysicalMemory%
echo Memorychip Capacity = %Capacity%
echo -------------------Converted---------------------
echo TotalPhysicalMemory = %TotalPhysicalMemory_Converted% >> %location%
echo Memorychip Capacity = %Capacity_Converted% >> %location%
echo -------------------------------------------------
GOTO :Continue
%dbg%
::-------------------------------------------------------
:GetCapacityMem
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_Capacity% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::-------------------------------------------------------
:GetTOTMEM
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_TOTMEM% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::-------------------------------------------------------
:Convert
Set "VBS=%Temp%\%Random%.vbs"
(
echo wscript.echo Convert("%~1"^)
echo 'Function to format a number into typical size scales
echo Function Convert(iSize^)
echo aLabel = Array("bytes", "KB", "MB", "GB", "TB"^)
echo For i = 0 to 4
echo If iSize ^> 1024 Then
echo iSize = iSize / 1024
echo Else
echo Exit For
echo End If
echo Next
echo Convert = Round(iSize,2^) ^& " " ^& aLabel(i^)
echo End Function
)>"%VBS%"
for /f "delims=" %%a in ('Cscript //NoLogo "%VBS%"') do set "%2=%%a"
Del "%VBS%"
Exit /b
::-------------------------------------------------------
REM Continue the script after pulling RAM
:Continue:
#echo. >> %location%
#echo Current User: >> %location%
whoami >> %location%
#echo. >> %location%
#echo Forticlient or Sophos: >> %location%
wmic product get version,vendor | findstr /i /c:"forti" /c:"sophos" >> %location%
%dbg%
:JumpOver
%dbg%```

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

Batch file for installed software

I am very new to batch just learnt a few. I agree to having shamelessly lifted this code from a website. This is the code I want for displaying list of installed software, however there is just one problem, the version and the softwares are being displayed in different lines. How can I have both in the same line?
Ex: If you run the batch you will see the versions at the beginning and then the softwares.
Any help would be greatly appreciated. Thanks in advance.
#echo off
If Exist C:\Final.txt Del C:\Final.txt
regedit /e C:\regexport.txt "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport2.txt "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport3.txt "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
find "DisplayName" C:\regexport.txt > C:\regprogs.txt
find "DisplayName" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayName" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
find "DisplayVersion" C:\regexport.txt > C:\regprogs.txt
find "DisplayVersion" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayVersion" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
del C:\regexport.txt
del C:\regexport2.txt
del C:\regexport3.txt
del C:\regprogs.txt
sort C:\installedprogs.txt > C:\alles.txt
del C:\installedprogs.txt
:: script om alle dubbele lijnen eruit te gooien
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL EnABLEDELAYEDEXPANSION
REM -- Prepare the Prompt for easy debugging -- restore with prompt=$p$g
prompt=$g
rem The finished program will remove duplicates lines
:START
set "_duplicates=TRUE"
set "_infile=C:\alles.txt"
set "_oldstr=the"
set "_newstr=and"
call :BATCHSUBSTITUTE %_infile% %_oldstr% %_newstr%
pause
goto :SHOWINTELL
goto :eof
:BATCHSUBSTITUTE
type nul> %TEMP%.\TEMP.DAT
if "%~2"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %1|find /n /v """') do (
set "_line=%%B"
if defined _line (
if "%_duplicates%"=="TRUE" (
set "_unconverted=!_line!"
set "_converted=!_line:"=""!"
FIND "!_converted!" %TEMP%.\TEMP.DAT > nul
if errorlevel==1 (
>> %TEMP%.\TEMP.DAT echo !_unconverted!
)
)
) ELSE (
echo(>> %TEMP%.\TEMP.DAT
)
)
goto :eof
:SHOWINTELL
#echo A|move %TEMP%.\TEMP.DAT C:\allesnietdubbel.txt
del C:\alles.txt
::Alle lijnen weggooien waar 'KB' in voor komt
type C:\allesnietdubbel.txt | findstr /V KB > C:\drivers\Final.txt
goto :eof
exit
Try next approach. Edited - saves output to a csv file (rfc4180 compliant):
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_csvfile=%TEMP%\%COMPUTERNAME%_39082171.csv" change to match your needs
> "%_csvfile%" (
rem (facultative, optional) CSV header
echo "version","displayname","comment"
call :getsw "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
ENDLOCAL
goto :eof
:getsw
for /F "delims=" %%g in ('reg query "%~1" 2^>NUL') do (
set "_swRegKey=%%~g"
set "_swName="
set "_swVers="
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayName 2^>NUL ^| findstr /I "DisplayName"
') do set "_swName=%%~I"
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayVersion 2^>NUL ^| findstr /I "DisplayVersion"
') do set "_swVers=%%~I"
call :echosw
)
goto :eof
:echosw
SETLOCAL EnableDelayedExpansion
if "%_swName%%_swVers%"=="" (
rem comment up next ECHO command if you don't require such information
ECHO "","","unknown !_swRegKey:HKEY_LOCAL_MACHINE=HKLM!"
) else (
echo "!_swVers!","!_swName!",""
)
ENDLOCAL
goto :eof
Sample output (largely narrowed down for demonstration here):
==> D:\bat\SO\39082171.bat
==> type "%TEMP%\%COMPUTERNAME%_39082171.csv"|findstr /I "comment KB unknown"
"version","displayname","comment"
"","","unknown HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\Connection Manager"
"12.0.31101","Visual Studio 2013 Update 4 (KB2829760)",""
"12.0.30112","Update for Microsoft Visual Studio 2013 (KB2932965)",""
"1","Update for (KB2504637)",""
==>
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(helpful particularities) Windows CMD Shell Command Line Syntax
(%~G, %~1 etc. special page) Command Line arguments (Parameters)
(special page) EnableDelayedExpansion
(2>NUL, 2>&1, | etc. special page) Redirection
(2^>NUL, ^| etc.) Escape Characters, Delimiters and Quotes

Batch file help - adding output from command to csv file

I currently have a batch file that reads a list of computer names and pings each of these and outputs the ones that reply to a csv file with the computer name and ip address.
I now need to edit this to also find out the user of the machine. I need to contact users which are online to arrange some work done to their computer. Their can be over a hundred machines in the batch file so to manually find out each user takes time. Is there a way to do this?
`IF EXIST C:\test\new.csv (del C:\test\new.csv)
IF EXIST C:\test\final.csv (del C:\test\final.csv)
set ComputerList=C:\test\ClientList.txt
Echo Computer Name,IP Address>Final.csv
setlocal enabledelayedexpansion
echo please wait...
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|findstr Reply') do (
set IPadd=%%B
echo %%A,!IPadd:~0,-1!>>final.csv
)
)
findstr /V "IPAddress" final.csv >> C:\test\new.csv
echo identified machines for Install
start excel C:\test\new.csv
echo opened csv file`
The command I want to use to get the username is:
`wmic.exe /NODE: %%A COMPUTERSYSTEM GET USERNAME`
Thanks
Mark
Here is a function I wrote to do just what you are trying to do:
:GetLoggedInUser comp user
for /f %%u in (
'wmic /NODE:"%1" Computersystem get username^|find "\"') do (
if not errorlevel 1 ( for /f "tokens=2 delims=\" %%a in (
'wmic /NODE:"%1" Computersystem get username^|find "\"' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
) ELSE (for /f "skip=1" %%a in (
'wmic /NODE:"%1" Computersystem get username' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
))
Exit /b
Here is my function for pinging. It returns a 0 if the ping succeeded and a 1 otherwise.
:IsPingable comp
ping -n 1 -w 3000 -4 -l 8 "%~1" | Find "TTL=">nul
exit /b
Usage example:
for /l %%a in (1,1,255) do (
call:IsPingable 10.6.1.%%a && (
echo ping 10.6.1.%%a used )||( echo ping 10.6.1.%%a unused )
)
And here is for if you're pinging IP's and want to return the hostname as well:
:IsPingable2 comp ret
setlocal
for /f "tokens=2" %%a in (
'"ping -a -n 1 -4 "%~1" | Find "Pinging" 2>nul"') do set name=%%a
endlocal & set %~2=%name%
ping -n 1 -w 3000 -4 -l 8 "%~1" | Find "TTL=">nul
exit /b
Usage example:
#echo off
setlocal enabledelayedexpansion
for /l %%a in (1,1,255) do (
call:IsPingable2 10.6.1.%%a host && (
echo ping !host! - 10.6.1.%%a used )||( echo ping !host! - 10.6.1.%%a unused )
)
I just posted these because they just might come in handy for this type of thing in the future. You can use the :IsPingable now though.
You would use it like this in your code:
IF EXIST C:\test\final.csv (del C:\test\final.csv)
set ComputerList=C:\test\ClientList.txt
Echo Computer Name,IP Address,Logged In User>Final.csv
setlocal enabledelayedexpansion
echo please wait...
echo.
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|find "TTL="') do (
if not errorlevel 1 (
set IPadd=%%B
call :GetLoggedInUser %%B uname
echo %%A,!IPadd:~0,-1!,!uname!>>final.csv
)
)
)
echo identified machines for Install
start excel C:\test\final.csv
echo opened csv file
goto :eof
:GetLoggedInUser comp user
for /f %%u in (
'wmic /NODE:"%1" Computersystem get username^|find "\"') do (
if not errorlevel 1 ( for /f "tokens=2 delims=\" %%a in (
'wmic /NODE:"%1" Computersystem get username^|find "\"' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
) ELSE (for /f "skip=1" %%a in (
'wmic /NODE:"%1" Computersystem get username' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
))
Exit /b
The below code will count the number of lines in two files sequentially and is set to the variables SalaryCount and TaxCount.
#ECHO OFF
echo Process started, please wait...
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set SalaryCount=%%C
echo Salary,%SalaryCount%
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set TaxCount=%%C
echo Tax,%TaxCount%
Now if you need to output these values to a csv file, you could use the below code.
#ECHO OFF
cd "D:\CSVOutputPath\"
echo Process started, please wait...
echo FILENAME,FILECOUNT> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set Count=%%C
echo Salary,%Count%>> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set Count=%%C
echo Tax,%Count%>> SUMMARY.csv
The > will overwrite the existing content of the file and the >> will append the new data to existing data. The CSV will be generated in D:\CSVOutputPath

Resources