Query the Windows registry through batch syntax - windows

I'm trying to query a particular registry folder (or whatever you want to call it) to obtain some information.
Particularly the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall folder contains a list of installed software.
The issue is that each software is identified through a random key value like {0001B4FD-9EA3-4D90-A79E-FD14BA3AB01D} instead of the actual software (like Skype).
This makes it hard to find the Skype identifier because I need to loop through everything inside this Uninstall folder and check whether the DisplayName value corresponds to Skype (or whatever other application name).
I need to use batch syntax... this is what I have so far but it doesn't behave the same on different computers, maybe I get different variables assigned based on some erroneous formatting of the reg output? I don't know. Can I use a data structure to contain whatever reg outputs? Anything would work.
#echo off
for /f "tokens=*" %%a in ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall') do (
for /f "tokens=2,* delims= " %%b in ('reg query %%a /v Publisher') do (
IF "%%c" == "Skype Technologies S.A." (
for /f "tokens=2,* delims= " %%d in ('reg query %%a /v UninstallString') do (
echo %%e
)
)
)
)
Is there a cleaner and safer way to achieve this in batch?

It seems me more easy to use
reg QUERY HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /f "Skype Technologies S.A." /s
as a basis for your batch file. It produces a simple output like following
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{D103C4BA-F905-437A-8049-DB24763BBE36}
Publisher REG_SZ Skype Technologies S.A.
End of search: 1 match(es) found.

This batch loop through items under the Uninstall key and search for the defined software name e.g. Skype. Once it located the software and the full key, it will then use it to search and print out DisplayName and UninstallString as shown in Output below.
Note:
For some software e.g. Skype, Notepad++ the key may not contain a GUID e.g. {BEB5FB69-4080-466F-96C4-F15DF271718B}. This batch is able to find software with or without a GUID
It can return multiple software if the name is too short
Use %x86GUID% variable to search 32 bit software and %x64GUID% for 64 bit software
.
#echo off
setlocal ENABLEDELAYEDEXPANSION
set SoftwareName=Skype
set x86GUID=HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
set x64GUID=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
REM It's faster to first locate the software GUID, then search it's Name, Version & UninstallString
for /f "delims=" %%P in ('reg query "%x86GUID%" /s /f "%SoftwareName%" 2^>nul ^| findstr "Uninstall\\%SoftwareName% Uninstall\\{"') do (
echo %%P
for /f "tokens=2*" %%A in ('reg query "%%P" /v "DisplayName" 2^>nul ^|findstr "DisplayName"') do echo Found: %%B
for /f "tokens=2*" %%A in ('reg query "%%P" /v "UninstallString" 2^>nul ^|findstr "UninstallString"') do echo %%B
)
endlocal
Output
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Skype_is1
DisplayName: Skype version 8.64
UninstallString: "C:\Program Files (x86)\Microsoft\Skype for Desktop\unins000.exe"

Related

Get from the windows system the user email registered from cmd

do you know how to retrieve from the windows system the email with which the user registered in the operating system? When you create an account, windows asks you for an email to register. Is it possible to retrieve that information via code line, cmd or who knows what else?
I got a customer PC in today which actually had a single account which was created using an email address. The only possibilities I could find were by trying to retrieve the email address via the Windows registry.
This first idea was to see if the user account still had the default OneDrive account attributed to that email. So based upon that as a possibility you could try to isolate it from the User registry branch.
From the Command Prompt:
For /F "EOL=H Tokens=2*" %G In ('%SystemRoot%\System32\reg.exe Query "HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Personal" /V "UserEmail" 2^>NUL') Do #Echo(%H
From a batch file:
#For /F "EOL=H Tokens=2*" %%G In ('%SystemRoot%\System32\reg.exe Query "HKCU\SOFTWARE\Microsoft\OneDrive\Accounts\Personal" /V "UserEmail" 2^>NUL') Do #Echo(%%H
Alternatively you'd have to use the Machine registry branch, which would list all found. This however would only identify the current user if theirs was the only account on that machine which had been created to log in with an email address created account. If there are more than one, then it would list them all.
From the Command Prompt:
For /F "Delims=" %G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\IdentityStore\LogonCache" /S /F "Name2Sid" /K 2^>NUL ^| %SystemRoot%\System32\find.exe "HKEY_"') Do #For /F "EOL=H Tokens=2*" %H In ('%SystemRoot%\System32\reg.exe Query "%G" /S /V "IdentityName" 2^>NUL ^| %SystemRoot%\System32\find.exe "#"') Do #Echo(%I
From a batch file:
#For /F "Delims=" %%G In ('%SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\IdentityStore\LogonCache" /S /F "Name2Sid" /K 2^>NUL ^| %SystemRoot%\System32\find.exe "HKEY_"') Do #For /F "EOL=H Tokens=2*" %%H In ('%SystemRoot%\System32\reg.exe Query "%%G" /S /V "IdentityName" 2^>NUL ^| %SystemRoot%\System32\find.exe "#"') Do #Echo(%%I
Please note, as per the comment section, the majority of user's computers I've worked on, and that is a very large number, do not have user accounts created using an email address, and the above examples would be unlikely to perform the task you require.

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"

Nesting commands in windows batch file and Parsing results recursively

Screenshot
I am trying to fetch all registry entries under
HKEY_Local_Machine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList and Delete if REG_EXPAND_SZ key contains value C:\Users\sas-
Ideal Steps Script should do :
1) Get all Registry entries for users Using :
reg query "HKEY_Local_Machine\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
>> xyz.txt
2)If users name is sas-### (which we can get in "REG_EXPAND_SZ") then delete this entry :
for /f "skip=10 tokens=* " %%a in (xyz.txt) do (
for /f "eol=; skip=2 tokens=4 delims=\t" %k in ('reg query "%%a" /t REG_EXPAND_SZ') do (
if %k == "sas-" (reg delete "%%a")
)
)
Try this:
for /f "tokens=*" %%a in ('
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"') do (
for /f "tokens=*" %%b in ('
reg query "%%a" /v "ProfileImagePath" 2^>nul ^| find "sas-"') do
rem reg delete "%%a"
echo "%%a" >>C:\names.txt
)
I've based this on you querying the ProfileImagePath value, and deleting any of the keys that contain sas-* in the value. I've also put in a few line breaks you will have to remove (just for easy viewing on SO).
Please test this first (I've echo'd them to a text file at the moment), if you are happy with it then remove rem from the reg delete line.
You should be able to do it from a single For loop; however, I do not particularly like the idea of removing profiles using this method.
#Echo Off
For /F "Tokens=1-2*" %%A In ('Reg Query^
"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /S^
/F ProfileImagePath /V 2^>Nul') Do (
If Not "%%~A%%B"=="ProfileImagePathREG_EXPAND_SZ" (
Set "_C=Reg Delete "%%A%%B"") Else (Set "_P=%%~C"
SetLocal EnableDelayedExpansion
If Not "!_P:C:\Users\sas-=!"=="!_P!" Echo=!_C!
EndLocal))
Timeout -1
If you're happy with the console output then remove Echo= from line 8 and delete line 10.

Batch file, query the registry

Hello People of StackoverFlow,
I am trying to query the follow registry location(every folder in here)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
In there are random numbers like so:
{071c9b48-7c32-4621-a0ac-3f809523288f}
In each of these random numbers, I need to check if the key 'DisplayName' that is in each of these locations contains a certain text, lets say 'OverFlow'.
I've done some querys but not like this, if anyone can help that would be great!
EDIT: I've made some progress but am encountering a problem( I have done alot of research...)
Below is what I have so far:
#echo off
setlocal
:RemoveCVCP
set PythonReg=
for /f "tokens=1" %%A in ('reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /v "DisplayName" ^| find "Python"') do set "PythonReg=%%A"
if %ERRORLEVEL% neq 0 (
GOTO RemovePyCP)
echo %PythonReg%
endlocal
pause
What I'm trying to do is loop through 'KLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', and look at the 'DisplayName' key, if the data contains 'Python' then delete it. and keep going till there are no longer any more.
Right Now I am testing this with an echo, but it will evetually delete it.
(I'm just using python as an example, I have already removed everything else that is related to the software I'm trying to remove, this is the last location.)
Thanks, Michael
First, list all values that contain python, two lines will be printed for each entry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{E43BBAEB-4914-44C6-88C0-E7A1DBD20A91}
DisplayName REG_SZ Some application title with python in its name
then delete those keys where the printed value name is DisplayName:
#echo off
setlocal enableDelayedExpansion
for /f "tokens=1,2*" %%A in ('^
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /d /f "python"^
') do (
if "%%A"=="DisplayName" (
echo Deleting %%C
reg delete !key! /f
) else (
set str=%%A
if "!str:~0,4!"=="HKEY" set key=%%A
)
)
pause
This code assumes there are no spaces in the key name.

How to retrieve substring from a string in Windows batch file?

How do I retrieve the string "C:\Program Files (x86)\Stupid\MS\" from the following input?
HKEY_CURRENT_USER\Software\Stupid\MS`
installpath REG_SZ C:\Program Files (x86)\Stupid\MS\`
please use windows bat file.
My way:
#echo off
Setlocal enabledelayedexpansion
for /f "tokens=2,* delims=:" %%i in ('reg query "HKEY_CURRENT_USER\Software\Stupid\MS" /v "installpath"') do (
echo %%i
)
pause
the result is : \Program Files (x86)\Stupid\MS\
req query "HKEY_CURRENT_USER\Software\Stupid\MS" /v "installpath"
returns this on my xp (sorry I don't have anything more recent at the moment)
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Software\Stupid\MS
installpath REG_SZ C:\Program Files (x86)\Stupid\MS
When using delim's default value (a space) what we actually need is the third and following tokens from the last line. "third and following" is tokens=3*. The third token will be available in %%i, the "and following" in %%j. This letter is automatically assigned.
Unfortunately the first line also has a third and following token, so we need to exclude the first line. We can do that by using the eol option to exclude lines starting with "!". "Setlocal enabledelayedexpansion" doesn't change anything in this litte batch file so I dropped it.
Summary: this works for me:
#echo off
for /f "eol=! tokens=3*" %%i in ('reg query "HKEY_CURRENT_USER\Software\Conceptworld\Piky\Settings" /v "installpath"') do echo %%i %%j
This should work - put a tab character in where it says TAB and leave the space too.
#echo off
for /f "tokens=2,* delims=:TAB " %%i in ('reg query "HKEY_CURRENT_USER\Software\Stupid\MS" /v "installpath"') do (
set "var=%%j"
)
echo "%var%"
pause

Resources