【问题标题】:Get-ChildItem filtered and sortedGet-ChildItem 过滤和排序
【发布时间】:2020-05-27 23:22:14
【问题描述】:

我正在尝试选择注册表中具有 DisplayName 属性的所有卸载键,按 Displayname 排序。我原以为这会起作用。

$uninstall32 = 'HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
$uninstall64 = 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall'
$uninstallKeys = (Get-ChildItem "Registry::$uninstall32" | Where-Object {$_.DisplayName} | sort DisplayName) +
                 (Get-ChildItem "Registry::$uninstall64" | Where-Object {$_.DisplayName} | sort DisplayName)

foreach ($uninstallKey in $uninstallKeys) {
    $uninstallKey
}

但这并没有返回任何东西。如果我删除 Where-Object 我会得到结果,但没有排序。我哪里错了?

【问题讨论】:

  • 我什至不认为 DisplayNameMicrosoft.Win32.RegistryKey 对象的属性。 $uinstallKeys[0] | Get-Member 不显示。
  • 是的,它看起来应该是可能的,但感觉就像微软从未实现过这样的东西,唯一真正的选择是获取所有内容,然后有条件地将其添加到具有 DisplayName 的哈希表中作为键,然后对哈希表进行排序。对于像微软这样的 SEEMS 应该提供的东西来说,这是一项艰巨的工作。
  • @AdminOfThings 再检查几个,比如$uninstallKeys[0..9] 或类似的,你可能会遇到一个。这是我从未真正习惯的注册表的怪癖之一。对我来说,当您只是为文件系统提供商编写代码时,我一直觉得必须从 pandas、天气预报和失望的概念中捕捉到偶尔的异常——试图找到一个文件、文件夹或其他东西。
  • 这只是Sort-Object 的一些奇怪行为。 Sort-Object 单独根据特定对象类型的默认属性集进行排序如果没有向命令提供任何属性。但是Sort-Object DisplayNameSort-Object RandomString 的排序方式相同,这与根本不提供任何属性不同。这会导致三种不同的排序方案:默认、实际属性或假属性的不同视图。我认为实际看到DisplayName 属性值需要额外的Get-ItemProperty
  • Get-ItemProperty 是此处用于获取 DisplayName 属性和其他的 cmdlet...话虽如此,由于程序注册了他的密钥,我遇到了“指定的强制转换无效”类型的问题那里有它不应该有的东西。为了避免这种情况,遍历每个项目然后从 try catch 中获取项目属性将完美地工作。唯一的缺点是当前方法会跳过(如果有的话)格式无效的密钥。

标签: powershell sorting filtering get-childitem


【解决方案1】:

get-childitem 的输出是一种错觉。它实际上在格式文件中调用 get-itemproperty。您需要使用 get-itemproperty 来查看值和数据。您可能想改用 get-package 命令。请注意,Netbeans 在安装时会生成一个无效的注册表 dword 条目“NoModify”,这会在 get-itemproperty 中创建一个异常。

这是一种使用 get-itemproperty 的方法:

get-itemproperty hklm:\software\microsoft\windows\currentversion\uninstall\* | 
  where displayname | sort displayname

【讨论】:

    【解决方案2】:

    如果我正确理解了这个问题,您要么希望将键 PATHS 作为字符串数组返回,要么将键作为对象返回,包括所有属性:

    $uninstall = 'HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
                 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    
    $uninstallKeys = $uninstall | ForEach-Object {
        Get-ItemProperty "Registry::$_" | 
        Where-Object {$_.DisplayName} | 
        Sort-Object DisplayName | 
        # if you want the Keys Paths returned as string properties:
        Select-Object @{Name = 'RegistryKey'; Expression = {($_.PSPath -split '::')[1]}}
    
        # if you want the Keys returned with all properties as objects:
        # Select-Object $_.PSPath
    }
    
    $uninstallKeys
    

    【讨论】:

      【解决方案3】:

      您只需将Get-ChildItem 命令通过管道传输到| Get-ItemProperty 即可获得所需的结果。

      话虽如此,我遇到了一个问题,我的注册表中有一个无效的键。 为了规避这个可能的问题,我迭代了每个项目并单独获取了属性。

      $uninstall32 = 'HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
      $uninstall64 = 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall'
      $uninstallKeys = (Get-ChildItem "Registry::$uninstall32") +
      (Get-ChildItem "Registry::$uninstall64")
      
      $AllKeys = `
        Foreach ($key in $uninstallKeys) {
        try {
          $Value = $Key | Get-ItemProperty -ErrorAction Stop
          $Value
        }
        catch {
          Write-Warning $_
        }
      }
      $AllKeys  = $AllKeys  | WHere DisplayName -ne '' | sort displayname
      

      参考

      Regarding the potential Specified cast is not valid error with Get-ItemProperty & uninstall registry location

      【讨论】:

      • 是的,这个。我注意到排序的一个小怪癖是`Tools for .Net 3.5`的显示名称确实以空格开头。去图吧。
      • Netbeans 在注册表中生成了一个无效的 dword 值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多