PowerShell 如何在注册表中找到必要的条目

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

PowerShell 如何在注册表中找到必要的条目

GSM5B55 是我的显示器的“唯一”名称,通过排除“ Default_Monitor ”,脚本找到需要的那个。

但在某些系统上,脚本在启动时显示错误,因为它无法找到文件夹,要么是因为有多个“唯一”命名的子键,要么是根本没有子键。(我不知道它取决于什么,但可能只有Nvidia开发者能解释。)

在我的情况下,只有一个名称为 GSM5B55… 显示器,所以脚本没有错误,决定使用哪个子条目:

图片:$GetFolder = HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm\State\DisplayDatabase\

PowerShell 如何在注册表中找到必要的条目

这是一个随机人的同一路径的屏幕截图。我想在他的情况下,唯一的显示标识符是 ACI27EC 。但出于某种原因,我的脚本在他的个人电脑上不起作用。

PowerShell 如何在注册表中找到必要的条目

我完全没有主意,很乐意得到任何形式的帮助,谢谢。

解决方案

  • 您必须处理以下特殊情况:
    • 只可能有一个默认监视器。
    • 可能有多个非默认监视器。
  • Select-Object Name 替换为 Select-Object -ExpandProperty Name 或更简单的 ForEach-Object Name
    • Select-Objectselect )默认返回 [pscustomobject] 实例,该实例具有所请求的属性 – 即使您只要求一个属性。建议的更改只返回 Name 属性的值。有关详细信息,请参见 此答案

因此:

$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()方法。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程