using piped commands with for /f on windows (with reg query) - windows

I am trying to query the install location of a program in the registry. All I'm interested in is the location output.
This question has a partial solution, but it doesn't quite help.
On Windows 7, the reg command outputs a stupid registry key header along with the value, as shown below:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode" /v InstallLocation
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode
InstallLocation REG_EXPAND_SZ C:\Program Files\NSIS
First, is there a way to turn off the header and simplify the output?
At the command prompt, I can change the above to
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode" /v InstallLocation | findstr InstallLocation
so that it returns me just the second line.
Now, if I am to use a FOR /F to parse this and get only the directory value, the FOR command fails saying | was unexpected at this time.
Here's my batch file:
#for /f "tokens=2* delims= " %%k in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode" /v InstallLocation | findstr InstallLocation') do #echo %%k
So where am I going wrong?

You must escape the | character using a caret (^).
#echo off
setlocal
set KEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode
set V=InstallLocation
for /f "tokens=2* delims= " %%k in ('reg query "%KEY%" /v %V% ^| findstr "%V%"') do echo %%k
this would return REG_SZ on my machine.

The pipe char is special and has to be escaped with ^.
#for /f "tokens=2* delims= " %%k in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NSIS Unicode" /v InstallLocation ^| findstr InstallLocation') do #echo %%k

Related

Windows version from a batch script

I need to add to a script that gets the windows version, Ex. 21H2.
I can get the OS name and build, but really need the 21H2.
What I have is:
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
And I get:
OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.19044 N/A Build 19044
Does anyone know how to get the 21H2, without using PowerShell, (which is disallowed in my work environment).
Regardless of my earlier comment, the simplest, and quickest way to retrieve the result requested in your specific question is:
#For /F "EOL=H Tokens=2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /V DisplayVersion 2^>NUL') Do #Echo %%H
[EDIT /]
BTW, based upon my earlier comment, you can change DisplayVersion to CurrentBuildNumber, if 19044 will still satisfy your requirements. This could be useful because the number can be better used in comparisons with IF and EQU/GTR/GEQ/LSS/LEQ etc.
And if you want the OS, Edition, Version, and Build all in one command, you could probably expand that to something like this:
#For /F "EOL=H Tokens=1,2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /T REG_SZ 2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"^ *CurrentBuildN" /C:" *ProductN" /C:" *D" ^| %SystemRoot%\System32\sort.exe /R') Do #Set /P "=%%I " 0<NUL
Alternatively modify the output:
#For /F "EOL=H Tokens=1,2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /T REG_SZ 2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"^ *CurrentBuildN" /C:" *ProductN" /C:" *D"') Do #Echo %%G: %%I "
Or define three variables:
#For /F "EOL=H Tokens=1,2,*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /T REG_SZ 2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"^ *CurrentBuildN" /C:" *ProductN" /C:" *D"') Do #Set "%%G=%%I"

Excluding a character in a FOR loop

I would like to display the information regarding the ProfileImagePath value of one windows user who don't have the "_" character in his username :
#echo off
cls
for /f %%I in ('dir /a:d-h /b C:\Users\ ^| %SystemRoot%\System32\findstr.exe /b /l /v "_"') do (
FOR /F "delims=" %%k IN ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"^|findstr.exe /R "S-1-5-21-[0-9]*-[0-9]*-[0-9]*-[0-9]*$" 2^>nul') do (
reg query "%%k" /v "ProfileImagePath"|findstr /i /e /c:"%%~I"
)
)
But the findstr command also takes into account users with the "_" character, while in the first FOR command, I have excluded this character :
ProfileImagePath REG_EXPAND_SZ C:\Users\user1
ProfileImagePath REG_EXPAND_SZ C:\Users\_user1
How is it possible ? How to take this into account in the 2nd FOR command ?
findstr /i /e /c:"user1" searches for strings ending with user1. However _user1 also ends with user1 :(
Changing it to findstr /i /e /c:"\%%~I" is one way to solve your problem :)

Issues when getting a list of user profiles using WMIC

I was using the following batch command to retrieve all local user profiles (including domain users too) :
for /f "delims=" %%I in ('dir /a:d-h /b "%SystemDrive%\Users\*" 2^>nul ^| %SystemRoot%\System32\findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"') do (
The problem is that this command has its limits: it doesn't really check if the users in question do actually have an account.
The user Compo provided me a methodology for retrieving the profile names, using WMIC.
So I ended up writing the following command:
#For /F "tokens=* skip=1" %%I In ('%__AppDir__%wbem\WMIC.exe UserAccount Get Name ^|%__AppDir__%findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"') do (
The problem is: it ignores my exclusion file (which contains one user per line) and it ends up a profile without any name.
Any idea How I can solve these issues ?
#echo off
setlocal
set "bin=%~dp0"
for /f "tokens=* skip=1" %%I in ('
%__AppDir__%wbem\WMIC.exe UserAccount where Disabled^="FALSE" get Name ^|
%__AppDir__%WindowsPowerShell\v1.0\powershell -noprofile -command "$input.trim()" ^|
%__AppDir__%findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"
') do echo "%%~I"
The wmic output is piped to powershell to be trimmed and then piped to findstr.
The wmic command will exclude disabled accounts by use of the where clause.
Change the setting of bin as needed.
If you want a solution which still uses WMIC, and your exclusion list, then the following should do as you require.
#For /F Tokens^=4Delims^=^" %%G In ('%__AppDir__%wbem\WMIC.exe UserAccount Where "LocalAccount='TRUE'" Assoc:List /ResultRole:Name 2^>NUL')Do #Echo %%G|%__AppDir__%findstr.exe /VXLIG:"%~dp0exclude_users.txt"
You can split that over multiple lines for easier reading too:
#For /F Tokens^=4Delims^=^" %%G In ('%__AppDir__%wbem\WMIC.exe UserAccount^
Where "LocalAccount='TRUE'" Assoc:List /ResultRole:Name 2^>NUL'
)Do #Echo %%G|%__AppDir__%findstr.exe /VXLIG:"%~dp0exclude_users.txt"

How to set FULL computer name to a variable in windows batch file

When right clicking >Computer > Properties, my full computer name is 50 characters.
If I set Cname=%COMPUTERNAME% and echo %Cname%, the FULL name is truncated from 50 characters down to just the Host name of 14 chars
In a batch file, how is the FULL computer name extracted?
This example is based purely on the vbscript you stated was retuning the string you require:
#Echo Off
Set "Pre=HKLM\SYSTEM\CurrentControlSet"
For /F "Delims==" %%A In ('Set _ 2^>Nul') Do Set "%%A="
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Control\Computername\ActiveComputerName" /V "ComputerName" 2^>Nul
')Do Set "_ActiveComputerName=%%B"
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Control\Computername\ComputerName" /V "ComputerName" 2^>Nul
')Do Set "_ComputerName=%%B"
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Services\TCPIP\Parameters" /V "HostName" 2^>Nul
')Do Set "_HostName=%%B"
Set _
Simply choose the example which outputs the string you were requiring for your purposes.
Either:
#Echo Off
Set "Pre=HKLM\SYSTEM\CurrentControlSet"
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Control\Computername\ActiveComputerName" /V "ComputerName" 2^>Nul
')Do Set "ActiveComputerName=%%B"
Set ActiveComputerName
Pause
Else:
#Echo Off
Set "Pre=HKLM\SYSTEM\CurrentControlSet"
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Control\Computername\ComputerName" /V "ComputerName" 2^>Nul
')Do Set "Computer-Name=%%B"
Set Computer-Name
Pause
Or:
#Echo Off
Set "Pre=HKLM\SYSTEM\CurrentControlSet"
For /F "Tokens=2*" %%A In ('
Reg Query "%Pre%\Services\TCPIP\Parameters" /V "HostName" 2^>Nul
')Do Set "Host-Name=%%B"
Set Host-Name
Pause
For the reference for Computer Name and Full computer name
https://superuser.com/questions/640046/what-is-the-difference-between-computer-name-and-full-computer-name
Now coming to your question, You can get your computer name with following ways:
%computername%
net config workstation | findstr /C:"Full Computer name"
wmic computersystem get name
Reference :
https://www.windows-commandline.com/find-computer-name-from-command-line/
There is no limitation of DOS console, I have tested as below:

Use reg_query to return data only for Typed URL and SystemshutDown

C:\Users\Admin1>REG QUERY HKLM\SYSTEM\ControlSet001\Control\Windows /v ShutdownTime
Retruns
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Windows
ShutdownTime REG_BINARY 42B96F5BC9F7D101
I want CMD to show only the data of the key 42B96F5BC9F7D101 so that I can output this to a csv file
Ive googled and read the forum and obtained this from another example -
for /f "tokens=2*" %%a in ('REG QUERY HKLM\SYSTEM\ControlSet001\Control\Windows /v ShutdownTime 2^>nul') do set "ShutdownTime=%%b"
echo %ShutdownTime%
which returns
C:\Users\Admin1>for /f "tokens=2*" %%a in ('REG QUERY HKLM\SYSTEM\ControlSet001
Control\Windows /v ShutdownTime 2^>nul') do set "ShutdownTime=%%b"
%%a was unexpected at this time.
C:\Users\Admin1>echo %ShutdownTime%
%ShutdownTime%
I also want to obtain only the data to display from
REG QUERY HKCU\Software\Microsoft\Internet Explorer\TypedURLs /v url1
Any help greatly appreciated
%%a was unexpected at this time.
That error is because for loop parameters are named with a single % when used in a cmd shell and with a double %% when used within a batch file:
%%parameter : A replaceable parameter:
in a batch file use %%G (on the command line %G)
Source for /f
So you need to replace %%a with %a and %%b with %b.
Example 1:
F:\test>#for /f "tokens=2*" %a in ('REG QUERY HKLM\SYSTEM\ControlSet001\Control\Windows /v ShutdownTime 2^>nul') do #set "ShutdownTime=%b"
F:\test>#echo %ShutdownTime%
BE7AE7FCE7DCD101
Example 2:
F:\test>#for /f "tokens=2*" %a in ('REG QUERY "HKCU\Software\Microsoft\Internet Explorer\TypedURLs" /v url1 2^>nul') do #set "Url1=%b"
F:\test>#echo %Url1%
http://www.example.com
Note:
Example 2 has quotes " around the key name as it contains spaces.
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
for /f - Loop command against the results of another command.

Resources