需要使用批处理/Windows 命令行枚举未知注册表项
Need to enumerate unkown registry keys using batch / Win command line
我的任务是枚举
中的所有注册表项
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render
(子项名称未知,因为它们在每台 PC 上都是可变的)并检查每个子项的特定值,例如
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{45be4e8b-f46c-4c2d-a1ff-ccae63ad5f80}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{8997a378-f558-4435-8134-b37565604f54}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{a7472931-1ee7-4561-9df3-6efacd010613}
并检查每个属性中的属性子项值 {a45c254e-df1c-4efd-8020-67d146a850e0},2
。
如果它等于某些文本,我需要更改父键中的值 DeviceState
。
我所做的很平常,并且为我工作了很多次 - 我用于 /f
:
@echo off
Setlocal EnableDelayedExpansion
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render" > c:\temp\reg.txt
for /f %%a in ('find /c /v "" ^< "c:\temp\reg.txt"') do set count=%%a
echo Number of lines: %count%
for /l %%i in (2,1,%count%) do (
echo Current line is: %%i
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b
echo %test%
set regstring=%test%^\Properties
echo %regstring%
pause
for /f "tokens=3*" %%c in ('reg query %regstring% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value%
)
那一行有什么奇怪的
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b
没有给 "test" 变量赋值。
同时如果我把
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do echo %%b
它向屏幕输出 %%b
。
我完全迷失了试图理解为什么它不将值传递给变量。
我尝试了一个更简单的代码,但没有导出到 txt 文件并稍后从中读取,但它都不起作用。它在屏幕上回显 %%a
但没有为 "key" 变量赋值:
@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`) do (
echo %%a
pause
set key=%%a
echo %key%
for /f "tokens=3*" %%c in ('reg query %key% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value%
)
能请教一下吗?
好的,我自己搞定了,也许有人会觉得它有用。它枚举子项并检查每个子项中的值。在每次之后,它将该值与戴尔的已知值进行比较并输出信息。
在命令中:
@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`) do (
set key=%%a^\Properties
echo !key!
for /f "tokens=3*" %%c in ('reg query !key! ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo !value!
)
pause
在 powershell 中:
$alldevices = Get-ChildItem -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render | select -ExpandProperty name
foreach($device in $alldevices)
{
$dkey = $device -split 'HKEY_LOCAL_MACHINE',2 | select -last 1
$devitem = "HKLM:"+$dkey+"\Properties"
$i = Get-ItemProperty $devitem -Name "{a45c254e-df1c-4efd-8020-67d146a850e0},2" | select -ExpandProperty "{a45c254e-df1c-4efd-8020-67d146a850e0},2"
if ($i -like '*DELL U*') {
"Dell Displays found:"
$i
#The below throws access denied errors
#$editkey = "HKLM:"+$dkey
#Set-ItemProperty -Path $editkey -Name DeviceState -Value 268435457
#Alternative
$tmpFileFullPath = [System.io.Path]::getTempFileName()
"Windows Registry Editor Version 5.00" | Out-File -FilePath $tmpFileFullPath -Append
" " | Out-File -FilePath $tmpFileFullPath -Append
"[$device]" | Out-File -FilePath $tmpFileFullPath -Append
#10000001 disables but makes it visible in GUI | 00000004 disables and prevents it from being visible in Recording Devices GUI
"`"DeviceState`"=dword:10000001" | Out-File -FilePath $tmpFileFullPath -Append
" " | Out-File -FilePath $tmpFileFullPath -Append
regedit.exe /S $tmpFileFullPath
$i+" disabled"
}
}
在 powershell 中直接使用它自己比为 regedit.exe
创建 .reg 文件更好
示例:
$dkey = "HKLM:"+$dkey
Set-ItemProperty -Path $dkey -Name DeviceState -Value 00000004
Set-ItemProperty -Path $devitem -Name '{b3f8fa53-0004-438e-9003-51a46e139bfc},3' -Value 0
如果有人想将这些注册表更改用作 GPO 启动脚本,则必须首先创建额外的 GPO 以授予 SYSTEM 用户更改这些注册表项的提升权限:
- 根据GPO打开或新建一个GPO。
- 导航到以下位置:
[计算机Configuration\Policies\WindowsSettings\SecuritySettings\Registry]
- 右击右面板,选择Add Key添加“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio”并赋予Admin和SYSTEM Full Control权限。
但是非常感谢您提供上面的脚本。我针对删除所有 VMware 音频设备的项目进行了调整,并在我的 Clearcube Zeroclients 上的 Teradici 音频驱动程序中取消选中“允许应用程序独占控制此设备”选项,以避免 Skype 等语音通信器之间的声音控制冲突。
我的任务是枚举
中的所有注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render
(子项名称未知,因为它们在每台 PC 上都是可变的)并检查每个子项的特定值,例如
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{45be4e8b-f46c-4c2d-a1ff-ccae63ad5f80}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{8997a378-f558-4435-8134-b37565604f54}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Reder\{a7472931-1ee7-4561-9df3-6efacd010613}
并检查每个属性中的属性子项值 {a45c254e-df1c-4efd-8020-67d146a850e0},2
。
如果它等于某些文本,我需要更改父键中的值 DeviceState
。
我所做的很平常,并且为我工作了很多次 - 我用于 /f
:
@echo off
Setlocal EnableDelayedExpansion
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render" > c:\temp\reg.txt
for /f %%a in ('find /c /v "" ^< "c:\temp\reg.txt"') do set count=%%a
echo Number of lines: %count%
for /l %%i in (2,1,%count%) do (
echo Current line is: %%i
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b
echo %test%
set regstring=%test%^\Properties
echo %regstring%
pause
for /f "tokens=3*" %%c in ('reg query %regstring% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value%
)
那一行有什么奇怪的
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do set test=%%b
没有给 "test" 变量赋值。 同时如果我把
for /f "usebackq tokens=2 delims=]" %%b in ('find /n /v "" ^< "c:\temp\reg.txt" ^| findstr "^\[%%i\]"') do echo %%b
它向屏幕输出 %%b
。
我完全迷失了试图理解为什么它不将值传递给变量。
我尝试了一个更简单的代码,但没有导出到 txt 文件并稍后从中读取,但它都不起作用。它在屏幕上回显 %%a
但没有为 "key" 变量赋值:
@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`) do (
echo %%a
pause
set key=%%a
echo %key%
for /f "tokens=3*" %%c in ('reg query %key% ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo %value%
)
能请教一下吗?
好的,我自己搞定了,也许有人会觉得它有用。它枚举子项并检查每个子项中的值。在每次之后,它将该值与戴尔的已知值进行比较并输出信息。
在命令中:
@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq delims=" %%a in (`reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"`) do (
set key=%%a^\Properties
echo !key!
for /f "tokens=3*" %%c in ('reg query !key! ^/v "{a45c254e-df1c-4efd-8020-67d146a850e0},2"') do set value=%%c %%d
echo !value!
)
pause
在 powershell 中:
$alldevices = Get-ChildItem -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render | select -ExpandProperty name
foreach($device in $alldevices)
{
$dkey = $device -split 'HKEY_LOCAL_MACHINE',2 | select -last 1
$devitem = "HKLM:"+$dkey+"\Properties"
$i = Get-ItemProperty $devitem -Name "{a45c254e-df1c-4efd-8020-67d146a850e0},2" | select -ExpandProperty "{a45c254e-df1c-4efd-8020-67d146a850e0},2"
if ($i -like '*DELL U*') {
"Dell Displays found:"
$i
#The below throws access denied errors
#$editkey = "HKLM:"+$dkey
#Set-ItemProperty -Path $editkey -Name DeviceState -Value 268435457
#Alternative
$tmpFileFullPath = [System.io.Path]::getTempFileName()
"Windows Registry Editor Version 5.00" | Out-File -FilePath $tmpFileFullPath -Append
" " | Out-File -FilePath $tmpFileFullPath -Append
"[$device]" | Out-File -FilePath $tmpFileFullPath -Append
#10000001 disables but makes it visible in GUI | 00000004 disables and prevents it from being visible in Recording Devices GUI
"`"DeviceState`"=dword:10000001" | Out-File -FilePath $tmpFileFullPath -Append
" " | Out-File -FilePath $tmpFileFullPath -Append
regedit.exe /S $tmpFileFullPath
$i+" disabled"
}
}
在 powershell 中直接使用它自己比为 regedit.exe
创建 .reg 文件更好示例:
$dkey = "HKLM:"+$dkey
Set-ItemProperty -Path $dkey -Name DeviceState -Value 00000004
Set-ItemProperty -Path $devitem -Name '{b3f8fa53-0004-438e-9003-51a46e139bfc},3' -Value 0
如果有人想将这些注册表更改用作 GPO 启动脚本,则必须首先创建额外的 GPO 以授予 SYSTEM 用户更改这些注册表项的提升权限:
- 根据GPO打开或新建一个GPO。
- 导航到以下位置: [计算机Configuration\Policies\WindowsSettings\SecuritySettings\Registry]
- 右击右面板,选择Add Key添加“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio”并赋予Admin和SYSTEM Full Control权限。
但是非常感谢您提供上面的脚本。我针对删除所有 VMware 音频设备的项目进行了调整,并在我的 Clearcube Zeroclients 上的 Teradici 音频驱动程序中取消选中“允许应用程序独占控制此设备”选项,以避免 Skype 等语音通信器之间的声音控制冲突。