I am currently working on a batch file to delete all registry keys containing or named a specific string (yes I know the dangers of doing this), however, I'm having a few issues.
The code I was attempting to use is:
@echo off
set "key=HKEY_LOCAL_MACHINE\SOFT-EXT"
set "search=string"
for /f "delims=" %%a in ('reg query "%key%" /s^| findstr "%search%"') do reg delete "%key%" /v "%%~a"
This works for a very specific, predetermined area of the registry - the only drawback for me is that my script needs to parse the ENTIRE SOFTWARE
registry hive, which is loaded from an external drive. What currently happens is the script will run for about ~20 seconds with no returns in the command prompt. After that, I get continues lines containing FINDSTR: Line 50300 too long
, with an increasing value on the line number. Some brief reading leads me to believe that findstr
can only manage so many bytes of data, and I am obviously overloading it due to the massive size of this registry hive (approx. 80-100MB each).
To fix this issue, I attempted to change the for loop to have an additional query with two conditional &&
s and ||
, however, this doesn't work either, because occasionally the registry key containing the string might be named HKLM\SOFTWARE\Classes\CSID\{###-###-###}\Example
, with a DWORD with the name of Name
and the data value of string
.
Is there any way to do what I would like to do with a batch file? I believe it is possible to do with PowerShell, however, the environment I'm working in does not support PowerShell or VB scripting.
I'm not really sure what you want:
Do you really want to delete registry keys displayed on left side in tree in Regedit as written in title of question, or registry values of type ? (REG_SZ?) displayed on right side in Regedit.
I think, you want to delete registry values of type ? which is much more difficult than deleting registry keys.
Here is a batch code to search for registry keys and either just list them with Action=Find
or additionally delete them with Action=Delete
at top of the commented batch code.
It is strongly recommended to run this batch code first with Action=Find
as posted here and look on found registry keys before deleting them using Action=Delete
.
@echo off
setlocal
rem Change value "Find" to "Delete" to really delete all found keys.
set "Action=Find"
rem Define the root key for the search.
set "RegKey=HKEY_LOCAL_MACHINE\SOFTWARE"
rem Define the string which must be found in name of a key to delete.
rem It should not contain characters interpreted by FINDSTR as regular
rem expression character, see help output on entering FINDSTR /? in a
rem command prompt window.
set "Search=ABCDEFGHIJKLM"
rem Check if specified registry key exists at all.
%SystemRoot%\System32\reg.exe query "%RegKey%" 1>nul 2>nul
if not errorlevel 1 goto RunSearch
echo.
echo Registry key "%RegKey%" not found.
goto EndBatch
:RunSearch
rem Exporting everything of defined root key to a temporary text file.
echo Exporting registry key "%RegKey%" ...
%SystemRoot%\System32\reg.exe query "%RegKey%" /s >"%TEMP%\RegExport.tmp" 2>nul
rem The backslash is the escape character in regular expressions. Therefore
rem it is necessary to escape this character in root registry key to get a
rem working regular expression search string as long as the root registry
rem key and the search string do not contain other characters with special
rem registry expression meaning.
set "RegKey=%RegKey:\=\\%"
rem Interesting are only lines in exported registry which contain the
rem search string in last key of a registry key path. In other words
rem the deletion of a key is always done only on root key containing in
rem name the search string and not also on all subkeys to improve speed.
if /I "%Action%"=="Delete" (
echo Searching for keys containing "%Search%" and delete all found ...
) else (
echo Searching for keys containing "%Search%" and list all found ...
)
rem The expression below works only correct if whether RegKey nor
rem Search contains characters with a regular expression meaning.
set "FoundCounter=0"
set "DeleteCounter=0"
for /f "delims=" %%K in ('%SystemRoot%\System32\findstr.exe /R "^%RegKey%.*%Search%[^\\]*$" "%TEMP%\RegExport.tmp" 2^>nul') do (
echo %%K
set /A FoundCounter+=1
if /I "%Action%"=="Delete" (
%SystemRoot%\System32\reg.exe delete "%%K" /f >nul
if not errorlevel 1 set /A "DeleteCounter+=1"
)
)
del "%TEMP%\RegExport.tmp"
set "FoundPlural="
if not %FoundCounter%==1 set "FoundPlural=s"
set "DeletePlural="
if not %DeleteCounter%==1 set "DeletePlural=s"
echo.
if /I "%Action%"=="Delete" (
echo Deleted %DeleteCounter% key%DeletePlural% of %FoundCounter% key%FoundPlural% containing "%Search%".
) else (
echo Found %FoundCounter% key%FoundPlural% containing "%Search%".
)
:EndBatch
endlocal
echo.
echo Exit with any key ...
pause >nul