0

May be out of line here but I stumbled on a batch script here on Stack Overflow and it was just what I wanted to do. But it is a quit old post and I can't get it to work.

Original post: Batch to query registry key, find a string within that key, then create a new key

:start
setlocal ENABLEDELAYEDEXPANSION
set qry=reg query "HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}" /s /v DriverDesc
for /f "Tokens=*" %%p in ('%qry%') do (
 set var=%%p
 set var=!var:^&=!
 set var=!var:^)=!
 set var=!var:^(=!
 call :parse
)
endlocal
goto :EOF
:parse
if /i "%var:~0,5%" NEQ "HKEY_" goto parse1
set key=%var%
set key=%key:HKEY_LOCAL_MACHINE=HKLM%
goto :EOF
:parse1
setlocal ENABLEEXTENSIONS
for /f "Tokens=*" %%f in ('@echo %var%^|findstr /i /c:"Intel(R)"') do (
  if defined key reg add %key% /v PnPCapabilities /t REG_DWORD /d 56 /f&set key=
)
endlocal >nul 2>&1

I executed this batch file on Windows 10 Home Edition and it has not changed anything in Windows registry although running it as administrator.

Can someone please help me to get this script to work?

Result of reg query:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0000
    DriverDesc    REG_SZ    Microsoft Kernel Debug Network Adapter

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0001
    DriverDesc    REG_SZ    Intel(R) Ethernet Connection I217-V

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0002
    DriverDesc    REG_SZ    Qualcomm Atheros AR946x Wireless Network Adapter

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0003
    DriverDesc    REG_SZ    Broadcom 802.11ac Network Adapter

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0004
    DriverDesc    REG_SZ    Bluetooth Device (RFCOMM Protocol TDI)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0005
    DriverDesc    REG_SZ    Microsoft Wi-Fi Direct Virtual Adapter
Mofi
  • 46,139
  • 17
  • 80
  • 143

1 Answers1

0

The batch file written by Matt M does not work because all &, ( and ) are removed from all lines before calling the subroutine parse. For that reason Intel(R) is modified already to IntelR and FINDSTR cannot find in any modified line the string Intel(R). That's why reg add is never executed by batch file posted in question.


I decided to rewrite the batch code for the task to disable power management on all Intel ® network adapters.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "DetectionCount=0"

for /F "delims=" %%I in ('%SystemRoot%\System32\reg.exe query "HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}" /s /v DriverDesc 2^>nul') do call :ProcessLine "%%I"

if not %DetectionCount% == 0 echo/ & pause
endlocal
goto :EOF

:ProcessLine
set "RegistryLine=%~1"
if "%RegistryLine:~0,5%" == "HKEY_" set "RegistryKey=%~1" & goto :EOF

for /F "tokens=2*" %%A in ("%~1") do set "AdapterDescription=%%B"

if "%AdapterDescription:Intel(R)=%" == "%AdapterDescription%" goto :EOF

echo/
%SystemRoot%\System32\reg.exe add "%RegistryKey%" /v PnPCapabilities /t REG_DWORD /d 56 /f >nul
if errorlevel 1 (
    echo Failed to add double word value "PnPCapabilities" with value 56 for
) else (
    echo Added successfully double word value "PnPCapabilities" with value 56 for
)
echo network adapter "%AdapterDescription%" at registry key:
echo %RegistryKey%
set /A DetectionCount+=1
goto :EOF

How was the batch file tested?

I tested the script with the posted output of registry query

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}" /s /v DriverDesc

copied into text file RegistryOutput.txt and using the FOR loop

for /F "delims=" %%I in (RegistryOutput.txt) do call :ProcessLine "%%I"

instead of the FOR loop in posted batch code processing the output of the registry query directly. The line with reg.exe add was disabled by putting echo at beginning of this line.

The output of the batch file was:

Added successfully double word value "PnPCapabilities" with value 56 for
network adapter "Intel(R) Ethernet Connection I217-V" at registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0001

How does the batch file work?

The FOR command executes console application REG in a background command process with the command line:

C:\Windows\System32\cmd.exe /c C:\Windows\System32\reg.exe query "HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}" /s /v DriverDesc 2>nul

REG could output an error message to handle STDERR if it cannot find the specified registry key. This is very unlikely because this is the registry key for network adapters. However, the error message would be redirected to device NUL to suppress it using 2>nul. Please read the Microsoft article about Using Command Redirection Operators for details about input and output redirection. The redirection operator > must be escaped here with caret character ^ to be interpreted as literal character when Windows command interpreter processes the entire FOR command line before executing internal command FOR. Otherwise 2>nul would be interpreted as misplaced redirection of command FOR resulting in a syntax error message by Windows command interpreter instead of running FOR.

The output of REG written to handle STDOUT in background command process is captured by FOR and then processed line by line.

Empty lines are skipped by FOR as well as lines starting with a semicolon which does not occur here because no line ever starts with a semicolon.

All other lines would be split up into substrings (tokens) using space and horizontal tab characters as delimiters for the strings. This split behavior is not wanted here. Therefore "delims=" is used to disable line splitting and get assigned to loop variable I each non empty line.

The line with a registry key or registry value DriverDesc is passed enclosed in double quotes to subroutine ProcessLine as first and only argument. An argument string must be enclosed in double quotes if it contains 1 or more spaces or 1 or more of following characters: &()[]{}^=;!'+,`~|<>

The subroutine ProcessLine assigns first the passed line without the double quotes to environment variable RegistryLine.

A line on which the first 5 characters are case-sensitive equal to string HKEY_ is interpreted as line with a registry key assigned to environment variable RegistryKey and the subroutine is exited with goto :EOF.

Otherwise the registry line with a DriverDesc is processed as string by one more FOR loop.

The option "tokens=2*" results in splitting up the line into the three parts:

  1. DriverDesc
  2. REG_SZ
  3. The string starting with first non whitespace character REG_SZ up to end of line.

The second substring (token) REG_SZ is assigned to loop variable A. This string is of no interest for this task. For that reason loop variable A is not referenced by command line executed by FOR.

The third token being the network adapter description is assigned to next loop variable after specified loop variable A according to ASCII table which is B. That is the reason why loop variables are case-sensitive while environment variables are not.

The description of the driver of the network adapter is assigned to variable AdapterDescription for further processing.

The IF condition compares the adapter description with all occurrences of Intel(R) case-insensitive replaced by an empty string and therefore removed from the description with the unmodified network adapter description. Equal strings means the network adapter description does not contain the string Intel(R) resulting in exiting the subroutine with no further processing. In other words the registry key of this network adapter is ignored by the batch file.

But the double word value PnPCapabilities is added to the registry key containing this description value with the decimal value 56 for a network adapter with Intel(R) in description most likely at beginning of the description.

All other lines of the batch file are for informing the user of the batch file if any Intel ® network adapter was detected at all and if the registry value could be successfully added to registry or if that failed, for example on not running this batch file as administrator required for write access to any key of registry hive HKEY_LOCAL_MACHINE.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • reg /?
  • reg add /?
  • reg query /?
  • set /?
  • setlocal /?

See also the Microsoft support article Testing for a Specific Error Level in Batch Files. The answer on Single line with multiple commands using Windows batch file explains operator &.

Mofi
  • 46,139
  • 17
  • 80
  • 143