How do I make a batch variable = to a command answer? - batch-file

I have looked in quite a few places. Maybe I have not asked the right question, but I am now here. I am making a batch file to sense what the Operating system is.
My current attempt:
set os=systeminfo |find "OS Name"
EDIT: a WINDOWS batch file
EDIT: If a command returns a line in the console. How do I make a variable = the returned string. (This is my main question. Sorry if I was not very clear.)
Example:
varName = Command |find "String"

#echo off
for /f "delims=" %%a in ('wmic OS get caption ^|find /i "windows"') do (set #OS=%%a)
set #

See how this works for you:
#echo off
setlocal EnableDelayedExpansion
:: Routine by Aacini
::Identify OS
for /F "delims=" %%a in ('ver') do set ver=%%a
set Version=
for %%a in (95=95 98=98 ME=ME NT=NT 2000=2000 5.1.=XP 5.2.=2003 6.0.=Vista 6.1.=7 6.2.=8 6.3=8.1) do (
if "!Version!" equ "this" (
set Version=Windows %%a
) else if "!ver: %%a=!" neq "%ver%" (
set Version=this
)
)
::Identify bit
if exist "%SYSTEMDRIVE%\Program Files (x86)" (
set Type=64 bit
) else (
set Type=32 bit
)
::Display result
echo %Version% %Type%
echo/
pause

this
http://www.robvanderwoude.com/sourcecode.php?src=winver2_nt
and this
http://www.robvanderwoude.com/sourcecode.php?src=winver_bat
should do the work.Not sure if are updated to support Windows 8.
Here are all build numbers.
EDIT (only checks if it is Windows XP or 7 - see comments bellow.Will work also on Windows home editions which have no WMIC command)
#echo off
for /f " tokens=4,5 delims=. " %%a in ('ver') do set /a wver=%%a%%b
if "%wver%" == "61" echo Windows7
if "%wver%" == "51" echo WindowsXP

In bash:
UN=`uname`
echo $UN
In windows you can just examine the OS environment variable:
echo %OS%

Maybe this is what you are looking for:
wmic os get caption /value
There isa lot more of information. Try
wmic os get /value

Here is a routine I wrote to do this. WMIC returns goofy names for some OS's and version number isn't robust enough since some versions are the same for server and workstation. This works for everything.
#echo off
setlocal
call :GetOS cap bit sp
echo %cap%%bit% (%sp%)
exit /b
:GetOS caption servicepack
setlocal
set arc=%PROCESSOR_ARCHITECTURE%
set key="HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
for /f "tokens=3*" %%a in (
'reg query %key%^|findstr /i ProductName') do set cap=%%a %%b
for /f "tokens=3*" %%a in (
'reg query %key%^|findstr /i CSDVersion') do set sp=%%a %%b
endlocal & set %1=%cap% & set %2=%arc% & set %3=%sp%
exit /b

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%"

Batch / REG QUERY get the path of found value

I am trying to make a batch file, that finds a specific interface (their name vary from computer to computer = query). To find the interface I use a specific IP that is under that interface as a value.
The code here can find the interface in question based on the IP i insert into "IP-ADDRESS".
But my ultimate goal is to based on this search add two registry values into this interface, and therefore I need the path.
How do I get the path into a variable based on the search below?
for /f "tokens=3*" %%a in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ /s /f "IP-ADDRESS"') do set Myvar=%%b
ECHO %Myvar%
PAUSE
Thank you in advance!
The following batch-file returns here:
> Q:\Test\2018\11\16\SO_53340832.cmd
IPADDRESS:192.168.56.1 on interface:{4fe80965-dda5-466a-801d-14937fd3829c}
It uses "tokens=1,2*" and /v IPADDRESS without dash.
:: Q:\Test\2018\11\16\SO_53340832.cmd
#Echo off & SetLocal EnableExtensions EnableDelayedExpansion
Set "Key=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
Set "Val=IPADDRESS"
For /f "tokens=1,2*" %%A in (
'reg query "%Key%" /s /v "%Val%" ^| findstr /i "^HKEY %Val%"'
) Do if /i "%%A" neq "%Val%" (rem must be HKEY
Set "Interface=%%A"
) Else (
Echo %VAL%:%%C on interface:!Interface:%Key%\=!
)
Here's one possibility for you:
#Echo Off
Set "RKP=HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
Set "RVD=172.26.193.3"
Set "RKC="
For /F "Delims=}" %%A In ('Reg Query "%RKP%" /S /F "%RVD%" /D 2^>Nul'
) Do If Not Defined RKC Set "RKC=%%A}"
If Not Defined RKC Exit /B
Rem show the variable and value for five seconds
Set RKC
Timeout 5 >Nul

batch command - find multiple texts in seperate lines and output them as columns

i am trying to make an inventory of installed software in domain PCs by following reg command
Reg Query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall /S ^| Find /I "DisplayName"
I am using Find /I "DisplayName" to get software-name. I also need the version number (and may be few more fields later), but its in another line as DisplayVersion.
Since I am running this on multiple computers, my script looks like this:
for /f %%i in (computers_ALL.txt) do (
for /f "tokens=1,2,*" %%j in ('psexec \\%%i Reg Query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall /S ^| Find /I "DisplayName"') do (
echo x64 %%i %%l >>%OUTPUT_FILE%
)
for /f "tokens=1,2,*" %%j in ('psexec \\%%i Reg Query HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S ^| Find /I "DisplayName"') do (
echo x86 %%i %%l >>%OUTPUT_FILE%
)
)
Now I can only find DisplayName. How can I find DisplayVersion which is on another line and add it to second column? My output will be like,
ComputerName, Platform (32-64 bit), Software Name, Software Version
I can take care upto software-name, but having difficulty to get version and put it on second column. Appreciate your help. Thanks.
Following script works against a local Windows machine. Adapting it for a list computers_ALL.txt instead of "%computername%" and adding psexec \\%_comp% should be a simple task.
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "OUTPUT_FILE=%temp%\41887529.txt"
for /F %%i in ("%computername%") do (
set "_comp=%%i"
call :proHive "x64" "\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :proHive "x86" "\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
rem debugging output
type "%OUTPUT_FILE%"
ENDLOCAL
goto :eof
:proHive
rem %1 platform
rem %2 registry key
>>"%OUTPUT_FILE%" (
for /f "tokens=*" %%G in ('
Reg Query "HKLM%~2" /S /V DisplayName ^| Find /I "HKEY_LOCAL_MACHINE%~2"
') do (
set "_DisplayName="
set "_DisplayVersion="
for /f "tokens=1,2,*" %%j in ('
Reg Query "%%G" ^| Findstr /I "DisplayName\> DisplayVersion\>"') do set "_%%j=%%l"
SETLOCAL EnableDelayedExpansion
echo %_comp%,%~1,!_DisplayVersion!,!_DisplayName!
ENDLOCAL
)
)
goto :eof
#ECHO OFF
SETLOCAL
SET "output_file=u:\report.txt"
DEL "%output_file%" /F /Q
for /f %%i in (q41887529.txt) do (
SET "compname=%%i"
CALL :clrsoft
FOR %%z IN (\ \Wow6432Node\) DO (
for /f "tokens=1,2,*" %%j in (
'Reg Query HKLM\Software%%zMicrosoft\Windows\CurrentVersion\Uninstall /S ^| Findstr /I "DisplayName DisplayVersion HKEY_LOCAL_MACHINE\\"'
) do (
IF /i "%%j"=="Displayname" (
SET "softname=%%l"
) ELSE (
IF /i "%%j"=="Displayversion" (
SET "softver=%%l"
) ELSE (
CALL :report %%z
)
)
)
REM processed all data - final report
CALL :report %%z
)
)
GOTO :EOF
:: Report routine parameters :
:: %1 indicates x64 ("\") or x86 (\Wow6432Node\)
:report
IF NOT DEFINED softname GOTO clrsoft
IF "%1"=="\" (
ECHO "%compname%",x64,"%softname%","%softver%">>"%output_file%"
) ELSE (
ECHO "%compname%",x86,"%softname%","%softver%">>"%output_file%"
)
:clrsoft
SET "softname="
SET "softver="
GOTO :EOF
Naturally, you'd need to set up your own output filename. I've also removed the psexec \\%%i and set up my machine name in q41887529.txt for testing on my machine.
Since the only difference between the queries is the node, I combined the steps and controlled them using %%z.
Clear the tempvars, then process each return line for one of the three target strings.
If it's a name, then call :report to report any accumulated data, then record the name
If it's a version, record the version and since this should now give us a pair, report it.
If it's neither, then it must be a new key, so report what we have so far.
The wart is that the version need not exist - and the final entry may be versionless, so we try reporting again to ensure any accumulated data is output.
I've revised this now and replaced the original.
It will report the machine name extracted from the file and I believe that the often-missing version number has been fixed - the order of name and version are unpredictable, so the report is triggered with the data accumulated between instances of HKEY_ and at the very end.

Search file with wildcard path

I want to write a script to prompt user for file path and list all files found. The file path can contain wildcards. Something similar to this. But the batch script version of it. For example:
C:\Somewhere\user*\app\version-*.*\start.exe
The files might be located like this:
C:\Somewhere\user345\app\version-1.0\start.exe
C:\Somewhere\user898\app\version-1.2\start.exe
C:\Somewhere\user898\app\version-1.3\start.exe
I tried to use FOR and it turns out to be so much harder than expected because FOR does not support wildcards in the middle of a path.
Is there a way to list these files? (Maybe without using for?)
I think this recursive solution works pretty well; you may name it WCDIR.bat:
#echo off
setlocal
if "%~1" neq "" set "next=%~1" & goto next
echo Show files selected by several wild-cards
echo/
echo WCDIR wildcardPath
echo/
echo Each folder in the path may contain wild-cards
echo the last part must be a file wild-card
goto :EOF
:next
for /F "tokens=1* delims=\" %%a in ("%next%") do set "this=%%a" & set "next=%%b"
if defined next (
for /D %%a in ("%this::=:\%") do (
setlocal
cd /D "%%~a" 2>NUL
if not errorlevel 1 call :next
endlocal
)
) else (
for /F "delims=" %%a in ('dir /B /A:-D "%this%" 2^>NUL') do echo %%~Fa
)
exit /B
EDIT: I fixed a small bug in the last for /F command.
For example, the output of WCDIR.bat C:\Windows\Sys*\find*.exe command in my Windows 8.1 64-bits computer is:
C:\Windows\System32\find.exe
C:\Windows\System32\findstr.exe
C:\Windows\SysWOW64\find.exe
C:\Windows\SysWOW64\findstr.exe
You can try with the command Where /?
The WHERE command is roughly equivalent to the UNIX 'which' command. By default, the search is done in the current directory and in the PATH.
#echo off
Where /R "%programfiles%" *winrar.exe
pause
#echo off
:: Example d'input
set UserInput=*drive*
:: building the Pattern
set cmd=%Userinput%.exe
:: storage Where.exe command in a macro, the execution will be faster
set whereCmd=where.exe /r c:\windows\ %cmd%
:: execution of macro and output formatting
for /f %%a in ('%whereCmd%') do echo %%~nxa --^> %%a
pause

How do I get wmic to use a delayed variable in a for loop?

I'm stuck and need your help please:
I am trying to test for the existence of a specific application and version within a batch file so I can uninstall non current versions.
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
set currver=7.1.10.21187
set appname=Juniper Installer Service
set junver=1
echo %currver%
echo %appname%
FOR /F "tokens=2 delims==" %%i in ('wmic product where "name='%appname%'" get version /VALUE ^| find "Version="') do (echo version: %%i
set junver=%%i
echo Juniper version detected: !junver!
if !junver! NEQ %currver% (echo non-current version found...
echo ...uninstalling %appname%
wmic product where ^( name='%appname%' and version='!junver!' ^) call uninstall
echo !errorlevel!
echo %appname% uninstalled))
echo.
echo %junver%
All of the code works except for the second wmic command that contains the code: and version='!junver!'
I have tried adding the double carat to escape the exclaimation marks to no avail, also using the %%i variable also does not work.
I have also tried using the different where filter syntaxes also to no avail.
Edited to process the subroutine in a loop:
If you use this style of coding then you don't need extra care in escaping.
I can't test the code though... the call uninstall looks odd to me there.
Spaces and & characters can be an issue if you have them and make sure that the junvar variable from the WMIC command doesn't have a trailing CR.
#echo off
set currver=7.1.10.21187
set appname=Juniper Installer Service
set junver=1
echo %currver%
echo %appname%
FOR /F "tokens=2 delims==" %%i in ('wmic product where "name='%appname%'" get version /VALUE ^| find "Version="') do set "junver=%%i" & call :next
echo done
pause
goto :EOF
:next
echo Juniper version detected: "%junver%"
if %junver% EQU %currver% goto :EOF
echo non-current version found...
echo ...uninstalling %appname%
wmic product where (name='%appname%' and version='%junver%') call uninstall.bat
echo %errorlevel%
echo %appname% uninstalled
echo.
echo %junver%
goto :EOF
I believe that this is your problem : http://www.dostips.com/forum/viewtopic.php?f=3&t=4266
You can try also with this change in your code:
FOR /F "tokens=2 delims==" %%B in ('wmic product where "name='%appname%'" get version /VALUE ^| find "Version="') do #for /f "delims=" %%i in ("%%B") do (
echo version: %%i
set junver=%%i
echo Juniper version detected: --!junver!--
)
If you want to use your original script (so you can check if each instance installed on the computer is the current version and remove non-current versions):
edit this line:
wmic product where ^( name='%appname%' and version='!junver!' ^) call uninstall
to this:
set juniperuninstall=wmic product where ^( name='%appname%' and version='!junver!' ^) call uninstall
then add this line straight after:
cmd /c !juniperuninstall!
this changes the wmic line into a readable format which gets read into a fresh command instance.
not clean, but works.

Resources