如何通过powershell脚本在注册表中找到必要的条目?

问题描述 投票:0回答:1

我制作了一个小型 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 的图片 vlddmkm\状态\显示数据库\

这是一个随机人的相同路径的屏幕截图。我想在他的例子中,唯一的显示标识符是ACI27EC。但由于某种原因,我的脚本无法在他的电脑上运行。

我完全没有主意,很高兴收到任何形式的帮助,谢谢

windows powershell registry nvidia
1个回答
1
投票
  • 您必须处理以下边缘情况:

    • 可能只有一个默认监视器。
    • 可能有多个非默认监视器。
  • Select-Object Name
    替换为
    Select-Object -ExpandProperty Name
    ,或更简单地说,
    ForEach-Object Name

    • Select-Object
      (
      select
      ) 默认情况下会返回 a
      [pscustomobject]
      实例
      ,它具有 请求的属性 - 即使您只请求 单个 属性。建议的更改仅返回
      Name
      属性的 value。请参阅此答案了解背景信息。

因此:

$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(核心)在 registry 提供者方面不再受到它们的困扰,但不幸的是,它仍然是在 文件系统提供者方面;请参阅这个答案的底部部分,下面的解决方案借用了其技术。

$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({ $_ + '*' })
    可能会创建包含模式的 array,通过使用
    内在 
    '*'
     方法
    $nonDefaultMonitorNames
    附加到
    .ForEach()

    的每个元素的值
© www.soinside.com 2019 - 2024. All rights reserved.