Batch variables remove line break - batch-file

setlocal enabledelayedexpansion
... a lot of batch script ...
IF ... a lot of batch script ...
for /f "skip=2 delims== tokens=2" %%g in ('WMIC DATAFILE WHERE ^"Name^='!filePath!'^" GET Version /value') DO (
set fileVersion=%%g
)
ECHO Version: !fileVersion!
set nightlyBuildFullPath=%2\Setups\Nightly Builds\!fileVersion!\Full\
ECHO FullPath: !nightlyBuildFullPath!
Result:
Version: 1.5.1810.202
FullPath: C:\test\Setups\Nightly Builds\1.5.1810.202
\Full\
I want to remove the linebreaks in the fileVersion variable because I have to build a path for later use. If I actually build the path string I have a linebreak in it, which corrupts my path.

ECHO Version: "%fileVersion:~0,-1%"
may assist your investigations...

Try like this:
for /f "skip=2 delims== tokens=2" %%g in ('WMIC DATAFILE WHERE ^"Name^='!filePath!'^" GET Version /value') DO (
for /f "tokens=* delims=" %%# in ("%%g") do set "fileVersion=%%#"
)

Put the following line into a file named veronly.ps1. Change the file name to the one you want to examine.
Get-WmiObject -Class 'CIM_DataFile' -Filter "name='C:\\Program Files (x86)\\PuTTY\\psftp.exe'" | % { $_.Version }
Put the following into the .bat script file.
FOR /F %%v IN ('powershell -NoLogo -NoProfile -File .\veronly.ps1') DO (SET "THEVERSION=%%v")
ECHO %THEVERSION%

REM :: As you use the commutator '/Value', you can use it to parse for command.
set myParams = WMIC DATAFILE WHERE ^"Name^='!filePath!'^" GET Version /value
for /f "tokens=1-2 skip=1 delims==" %%i in ('wmic /node:"%1" %myParams%') do if "%%i" == "Version" set "myVers=%%j"
REM :: DOS commands have the advantage of being able to run natively on all Microsoft systems. This can be useful when you have obsolete systems or when system or network security limits the execution of system commands.

Related

Batch file to collect UUID and Serial number

I have been using this batch file to collect the Serial number and UUID number and output to a CSV and now it no longer works.
#echo off
set outputfile="Y:\HP\UUDI.csv"
for /f "delims== tokens=2" %%i in ('wmic csproduct Get "UUID" /value') do SET CSPRODUCT=%%i
for /f "delims== tokens=2" %%i in ('wmic bios get serialnumber /value') do SET SERIAL=%%i
echo UUID,Serial,>>%outputfile%
echo %CSPRODUCT%,%SERIAL%,>>%outputfile%
If someone can look at this file and help me understand what went wrong I would appreciate it
I don't understand what did you mean by "No Longer Works" ? Please be more explicit when you ask a question !
here is a test and tell me if this works or not on your side and i will edit this aswer according to your response !
#echo off
set "outputfile=%~dp0UUDI.csv"
#for /f %%i in (
'wmic csproduct Get "UUID" /value ^& wmic bios get serialnumber /value'
) do (
#for /f %%j in ("%%i") do set "%%j" & echo "%%j"
)
echo UUID,SerialNumber>"%outputfile%"
echo %UUID%,%SERIALNumber%>>"%outputfile%"
If exist "%outputfile%" Start "" "%outputfile%" & Exit
The only reason I can see for your provided code to change its behavior, is that which was commented already by Mofi. That is, you've somehow caused the location of WMIC.exe to have been removed from the %Path% environment.
I have decided to provide an alternative method of achieving your goal using your chosen command utility WMIC.exe, and using its full path, to prevent such a reliance in future.
The WMIC command is traditionally one of the slower ones, so this method invokes it only once. All you should need to do is Echo your commands, currently on lines 12and 14, each separated as in line 13. If any of your commands requires to Get more than one property, you should separate those with caret escaped commas, e.g. Get Property1^,Property2. The results, (subject to line/environment length limitations), will then be saved to variables, %Title%, and %Record%, which can later be output to a file outside of the loop. Note: all commands should use /Value, or the more correct, /Format:List.
Example, (don't forget to adjust your output file path on line 4 as needed):
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "outputfile=Y:\HP\UUDI.csv"
Set "WMIC=%SystemRoot%\System32\wbem\WMIC.exe"
Set "FIND=%SystemRoot%\System32\find.exe"
Set "Title="
Set "Record="
For /F "Tokens=1,* Delims==" %%G In ('
(
Echo CSProduct Get UUID /Value
^&
Echo BIOS Get SerialNumber /Value
^)
^| %WMIC% ^| %FIND% "="
') Do (If Not Defined Title (Set "Title=%%G") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Title!") Do (EndLocal
Set "Title=%%I,%%G"))
If Not Defined Record (Set "Record=%%H") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Record!") Do (EndLocal
Set "Record=%%I,%%H")))
If Defined Title ( Echo %Title%
Echo %Record%) 1>"%outputfile%"

Eliminate the extra spaces from WMIC

I am creating a script that will get the computer version and serial number, turn it into variables, and then combine them together to create the new hostname.
However, the WMIC command for the serial number returns "T300"-"FDHGFJ "
Running just the serial number WMIC alone (without the does not "wmic csproduct get version") does not include the extra spaces.
I've tried looping it around one more time as other posts suggest but no luck.
Below is the full code.
#ECHO ON
PUSHD "%~dp0"
setlocal EnableDelayedExpansion
for /f "usebackq skip=1 tokens=*" %%i in (`wmic bios get serialnumber ^| findstr /r /v "^$"`) do set "serialn=%%i"
for /f "usebackq skip=1 tokens=2 delims= " %%a in (`wmic csproduct get version ^| findstr /r /v "^$"`) do set "modeln=%%a"
ECHO "%modeln%"-"%serialn%" >>test.txt
POPD
exit
I want the final result to be "T300"-"FDHGFJ" as it might get implemented into a task sequence.
You can try a bit of a hack by setting the variable only if not defined. I removed "tokens=*" and "delims=" as that will get the entire line. We then just do substitution on whitespace.
#echo off
set serialn=
set modeln=
for /f "usebackq skip=1" %%i in (`wmic bios get serialnumber`) do if not defined serialn set "serialn=%%i"
for /f "usebackq skip=1" %%a in (`wmic csproduct get version`) do if not defined modeln set "modeln=%%a"
echo "%modeln: =%"-"%serialn: =%">>test.txt
Note the output of second string on my device wmic csproduct get version has only one value and therefore I had to change the string, if yours really has 2 tokens then you should use your original string:
for /f "usebackq skip=1 tokens=2" %%a in (`wmic csproduct get version`) do if not defined modeln set "modeln=%%a"
The wmic command with its get verb might pad the returned data by trailing SPACEs, which I assume you want to have removed without removing SPACEs in the returned values themselves.
To achieve this you need to change the output format by adding the VALUE option, like this:
#echo off
setlocal EnableDelayedExpansion
cd /D "%~dp0."
for /F "tokens=1* delims==" %%I in ('wmic BIOS get SerialNumber /VALUE') do for /F "delims=" %%K in ("%%J") do set "serialn=%%K"
for /F "tokens=1* delims==" %%I in ('wmic CSProduct get Version /VALUE') do for /F "delims=" %%K in ("%%J") do set "modeln=%%K"
>> "test.txt" echo "%modeln%"-"%serialn%"
endlocal
exit /B
In addition I changed the following:
I placed another for /F loop inside of the one that parses the wmic output in order to avoid Unicode-to-ASCII/ANSI conversion artefacts by for /F, like orphaned carriage-return characters;
I replaced the pushd/popd pair by cd /D, because setlocal/endlocal already localises the environment, including the current working directory;
I added an explicit endlocal just to explicitly end the environment localisation (although this would be done upon termination of the batch script anyway);
I replaced exit by exit /B in order to only quit the batch file but not the parent cmd instance;
I put the redirection portion >> "test.txt" in front of the echo command in order to avoid the trailing space between the last closing " and >> (in your code) to be returned too;
As my initial comment regarding using /Value has already been implemented into an answer, this one expands upon using the wmic CSV format:
#Echo Off
SetLocal DisableDelayedExpansion
Set "DWM=%__AppDir__%wbem"
Rem Fixes 'Invalid XSL format (or) file name' errors in some Windows versions.
Set "CSV="
For /F "Delims=" %%A In ('"Dir /B/S/A-D "%DWM%\csv.xsl" 2>Nul"'
)Do If Not Defined CSV Set "CSV=%%A"
If Not Defined CSV Exit /B
Set "Serial#=Null"
For /F "Skip=2Tokens=1*Delims=," %%A In (
'""%DWM%\wmic.exe" BIOS Get SerialNumber /Format:"%CSV%" 2>Nul"'
)Do For /F Tokens^=* %%C In ("%%~B")Do Set "Serial#=%%~C"
Set "Model#=Null"
For /F "Skip=2Tokens=1*Delims=," %%A In (
'""%DWM%\wmic.exe" CSProduct Get Version /Format:"%CSV%" 2>Nul"'
)Do For /F Tokens^=* %%C In ("%%~B")Do Set "Model#=%%~C"
Echo "%Model#%"-"%Serial#%">>"test.txt"
Pause

Get only numbers in version from dll file

I'm trying to get the vertion of a .dll file, but only the number of the version.
I find the code
wmic datafile where name='C:\\...\\MY_FILE.dll' get version
This code returns:
Version
3.56.0.1
I need the return to be only '3.56.0.1' and this could be saved in a variable for i'll can call in a echo after.
set var="HOW DO I DO?"
echo %var%
How can I get this?
I can use the code below too, but in this format I think its harder
wmic datafile where name='C:\\...\\MY_FILE.dll' get version /format:list
This code returns:
Version=3.56.0.1
And similarly to those posted, with minor differences.
A batch-file:
#For /F "Delims=" %%A In ('WMIC DataFile Where "Name='C:\\...\\MY_FILE.dll'" Get Version /Value 2^>Nul')Do #For /F "Tokens=*" %%B In ("%%A")Do #Set "%%B"
#Echo(%Version%&Pause
A cmd version:
For /F "Delims=" %A In ('WMIC DataFile Where "Name='C:\\...\\MY_FILE.dll'" Get Version /Value 2^>Nul')Do #For /F "Tokens=*" %B In ("%A")Do #Set "%B"
Where the variable %Version% should be set to the local environment.
You'll need to parse with a for /f.
And another for /f to repair broken WMIC output.
On cmdline (using a windows dll):
For /f "usebackqdelims=" %A in (`wmic datafile where name^='C:\\Windows\\System32\\authui.dll' get version /format:list^|findstr "Version"`) do #For /F "delims=" %B in ("%A") do #Set "%B"
set Version
Version=10.0.17134.1
In a batch file double the percent signs of the for meta variable(s)
So you would require a for loop to do this.. see more help on it by running for /? from cmd.exe
#echo off
for /f "tokens=1,* delims==" %%i in ('wmic datafile where name^="C:\\...\\MY_FILE.dll" get version /format:list') do if not defined var set var=%%j
echo %var%
Note that the help will not assist you with the caret escape character used on the = which however you can find help on here at SO.
You should use:
#echo off
for /F "delims== tokens=2" %%A IN ('wmic datafile where name^="C:\\...\\MY_FILE.dll" get version /format:list') do (
for %%B IN ("%%A") do set "var_name=%%~B"
)
echo %var_name%
which loops through your command and finds the second token according to the delimeter specified (=).
Due to wmic unusual line endings (<CR><CR><LF>), you should use a double for loop.
If you scripted in PowerShell, you could use:
$var = [Diagnostics.FileVersionInfo]::GetVersionInfo('C:/.../MY_FILE.dll').ProductVersion
If you want to do it in a .bat file script, there is some overhead.
C:>TYPE gv.bat
#ECHO OFF
FOR /F "delims=" %%v IN ('PowerShell -NoLogo -NoProfile -Command ^
"[Diagnostics.FileVersionInfo]::GetVersionInfo('C:/Windows/System32/dfscli.dll').ProductVersion"') DO (
SET "var=%%~v"
)
ECHO var is +++%var%+++
C:>CALL gv.bat
var is +++10.0.17763.1+++

Batch file get result into runtime variable

The following code is ment to get Chrome current version into a runtime variable. What am I missing here?
for /f %%i in ('wmic datafile where name="C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" get Version /value') do set VAR=%%i
echo %VAR%
pause
The result :
C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe - Invalid alias
verb.
Quoting gets a little different when inside a FOR command. Need the nested FOR to get rid of the empty lines.
#echo off
for /f "delims=" %%G in ('wmic datafile where "name='C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'" get Version /value ') do (
FOR /F "tokens=2 delims==" %%H in ("%%~G") do set var=%%H
)
echo %var%
pause

How can I convert this raw bytes output to GB?

I'm using the below code to output the current free space on the C: Drive. How can I convert the output from bytes to GB using batch?
#echo off
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do set FreeSpace=%%x
echo %FreeSpace%
Batch does not support float point arithmetic. This would be a nice workaround:
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do set FreeSpace=%%x
echo !FreeSpace:~0,-10!,!FreeSpace:~2,-8!GB
It only works if you run the .bat as administrator. It just inserts a dot after the 9. digits from the right, and trims the last 7. This is not exactly matching the value from windows, because 1k is here 1000 and not 1024
A better but more complex solution would be to use VBScript, described in the following article: Article
Here is a solution that gives GB in a whole number. May not be what you wanted, but it was easy to do, and may do the trick for what you need. I couldn't really get it to work for me using wmic, but wmic is probably better than dir.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "tokens=3" %%a in ('dir c:\') do (
set bytesfree=%%a
)
set bytesfree=%bytesfree:,=%
endlocal && set bytesfree=%bytesfree%
rem truncating end. loses precision
set /a kb=%bytesfree:~0,-3%
set /a mb = kb/1024
set /a gb = mb/1024
echo %gb%
Eh, well, here is the same thing using wmic.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='C:'" get FreeSpace /format:value`) do set FreeSpace=%%x
rem truncating end. losing precision
set /a kb=%FreeSpace:~0,-4%
set /a mb = kb/1024
set /a gb = mb/1024
echo %gb%
Must you use batch commands? Can you not use PowerShell?
[System.IO.DriveInfo]::GetDrives() | Where {$_.Name -eq 'C:\'} |
Select {$_.AvailableFreeSpace/1GB}
REM ECHO Disk Storage
for /f "tokens=1" %%d in (
'wmic logicaldisk where drivetype^=3 get deviceid ^| find ":"') do (
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%%d'" get Size /value`) do set Size=%%x
echo VolumeSize on %%d Partition = !Size:~0,-10!,!Size:~2,-8! GB >output.txt
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%%d'" get FreeSpace /value`) do set FreeSpace=%%x
echo Freespace on %%d Partition = !FreeSpace:~0,-10!,!FreeSpace:~2,-8! GB >> output.txt
echo.
)
)
Could use the StrFormatByteSize64() API function to convert a long int to human readable size. This results in a more accurate value than truncating to meet the cmd environment's 32-bit limit. This API function supports values in the ranges from bytes and kilobytes to petabytes and exabytes.
(This script is a hybrid Batch + PowerShell script. Save it with a .bat extension.)
<# : batch portion
#echo off & setlocal
for /f "tokens=2 delims==" %%x in (
'wmic logicaldisk where "DeviceID='C:'" get FreeSpace /value'
) do call :int2size FreeSpace %%x
echo %FreeSpace% free on C:
rem // end main runtime
exit /b
rem // batch int2size function
:int2size <return_varname> <int>
setlocal
set "num=%~2"
for /f "delims=" %%I in (
'powershell -noprofile "iex (${%~f0} | out-string)"'
) do endlocal & set "%~1=%%I" & goto :EOF
: end batch / begin PowerShell #>
Add-Type #'
using System.Runtime.InteropServices;
namespace shlwapi {
public static class dll {
[DllImport("shlwapi.dll")]
public static extern long StrFormatByteSize64(ulong fileSize,
System.Text.StringBuilder buffer, int bufferSize);
}
}
'#
$sb = new-object Text.StringBuilder 16
[void][shlwapi.dll]::StrFormatByteSize64($env:num, $sb, 16)
$sb.ToString()

Resources