PowerShell 如何在注册表中找到必要的条目
问题描述
我编写了一个小的PowerShell脚本,用于在注册表中找到唯一命名的监视器文件夹,然后在其他预定义的条目中创建一个键 – https://github.com/SLStyler/Dithering-for-Windows-Simple-BAT-
以下几行应该定义正确的条目\路径:
$DisplayPath = "HKLM:\SYSTEM\CurrentControlSet\Enum\DISPLAY" \\ This path should contain display "unique" name
$GetDisplay = Get-ChildItem -Path $DisplayPath -exclude Default* | Select-Object Name |Split-Path -Leaf
$GetDisplay = $GetDisplay.replace("}","")
$Path = "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase\" \\ This path should contain "unique" display identifier subkey and some other subkeys, so using $GetDisplay, script chooses the right one
$GetFolder = Get-ChildItem -Path $Path -include $GetDisplay* -recurse |Select-Object Name |Split-Path -Leaf
$GetFolder = $GetFolder.replace("}","")
我的系统完美运行,此条目仅包含两个子条目\子键。
图片:$GetDisplay = HKLM:\SYSTEM\CurrentControlSet\Enum\DISPLAY
GSM5B55 是我的显示器的“唯一”名称,通过排除“ Default_Monitor ”,脚本找到需要的那个。
但在某些系统上,脚本在启动时显示错误,因为它无法找到文件夹,要么是因为有多个“唯一”命名的子键,要么是根本没有子键。(我不知道它取决于什么,但可能只有Nvidia开发者能解释。)
在我的情况下,只有一个名称为 GSM5B55… 显示器,所以脚本没有错误,决定使用哪个子条目:
图片:$GetFolder = HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase\
这是一个随机人的同一路径的屏幕截图。我想在他的情况下,唯一的显示标识符是 ACI27EC 。但出于某种原因,我的脚本在他的个人电脑上不起作用。
我完全没有主意,很乐意得到任何形式的帮助,谢谢。
解决方案
- 您必须处理以下特殊情况:
- 只可能有一个默认监视器。
- 可能有多个非默认监视器。
- 将
Select-Object Name
替换为Select-Object -ExpandProperty Name
或更简单的ForEach-Object Name
。Select-Object
(select
)默认返回[pscustomobject]
实例,该实例具有所请求的属性 – 即使您只要求一个属性。建议的更改只返回Name
属性的值。有关详细信息,请参见 此答案 。
因此:
- ** PowerShell (Core) 7+ ** 解决方案:
$displayPath = 'HKLM:\SYSTEM\CurrentControlSet\Enum\DISPLAY'
$nonDefaultMonitorNames =
Get-ChildItem -LiteralPath $displayPath -Exclude Default* |
ForEach-Object Name |
Split-Path -Leaf
$displayDatabasePath = 'HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase'
$displayDatabaseKeyNames =
Get-ChildItem -Recurse -LiteralPath $displayDatabasePath -Include $nonDefaultMonitorNames.ForEach({ $_ + '*' }) |
ForEach-Object Name |
Split-Path -Leaf
- Windows PowerShell 解决方案 :
不幸的是,在 Windows PowerShell 中,使用 -Include
和 -Exclude
存在许多怪异和错误。
虽然 PowerShell(Core)目前与 注册表 提供程序无关,但是,对于 文件系统提供程序 而言,它仍然存在问题。
$displayPath = 'HKLM:\SYSTEM\CurrentControlSet\Enum\DISPLAY'
$nonDefaultMonitorNames =
Get-Item -Path $displayPath\* -Exclude Default* |
ForEach-Object Name |
Split-Path -Leaf
$displayDatabasePath = 'HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase'
$displayDatabaseKeyNames =
Get-ChildItem -Recurse -Path $displayDatabasePath -Include $nonDefaultMonitorNames.ForEach({ $_ + '*' }) |
ForEach-Object Name |
Split-Path -Leaf
注意:
-
HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase
注册表项似乎是NVIDIA专用的,因此可能不会在所有机器上出现。 -
$nonDefaultMonitorNames.ForEach({ $_ + '*' })
可能会通过向$nonDefaultMonitorNames
的每个元素的值附加'*'
来创建包含模式的数组,使用内置的.ForEach()
方法。