【问题标题】:Trouble getting properties and object structured correctly无法正确获取属性和对象结构
【发布时间】:2017-05-24 04:18:23
【问题描述】:

我正在尝试创建一个属性与以下代码相同的对象。以下代码创建了 $TempValueICM 对象,并添加了 2 个 NoteProperties:

$TempValueICM = Invoke-Command -ComputerName $computer -ScriptBlock {
                $AppPull = Get-ItemProperty HKLM:\software\Microsoft\Windows\CurrentVersion\Uninstall\* |
                    Select-Object DisplayName, DisplayVersion}

它将 $temptValueICM 创建为一个数组对象,其 NoteProperties 为 DisplayName 和 Display version,如下所示:

显示版本:4.92.12.0

显示器名称:科胜讯 20561 SmartAudio HD

显示版本:

显示名称:连接管理器

显示版本:

显示名称:MouseSuite98

...

我正在尝试使用 .NET 拉取相同的数据,并使用以下代码:

$Hive = [Microsoft.Win32.RegistryHive]::LocalMachine
$AppAddressMain = "software\Microsoft\Windows\CurrentVersion\Uninstall\"
$AppAddressWOW = "software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"



Function Get-InstalledApps {
    param ($MainHive, $Computer, [string[]]$RegAddress)

    Foreach($Address in $RegAddress) {
        $RegBaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($MainHive, $computer)
        $RegSubKey= $RegBaseKey.OpenSubKey($Address)
        foreach($Subkey in $RegSubKey.GetSubKeyNames()){
            $AppAddress = $Address + $Subkey

            $DisplayName = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayName")
            $DisplayVersion = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayVersion")
            Write-Output  @{
                DisplayName = $DisplayName
                DisplayVersion = $DisplayVersion
                }
             }
        }

这会生成一个哈希表数据,我可以获取一些信息并使用点表示法访问它(例如 - “$TempValue.DisplayName”),但是在查看对象时它只显示“键”和“值”作为 $TempValue 对象的对象属性,而不是我想要的属性名称(例如 - DisplayName 和 DisplayVersion)。

我尝试在函数中创建一个临时变量以将数据保存为属性,例如-

 $Temp = "" | select DisplayName, DisplayVersion
     $Temp.DisplayName += ,$DisplayName
     $Temp.Publisher += ,$Publisher
     $Temp.DisplayVersion += ,$DisplayVersion

但是这样不行……

具体来说,我最终将不得不对其进行排序对象属性,并且需要两个函数的逻辑相同(即 - 数据可以来自相同格式的任一“逻辑”,因此它可以以同样的方式对待。

如何格式化对象,以便以与上面的 $TempValueICM 相同的方式提供相同的信息(即 - 如何获取哈希表中的项目以填充对象的属性)?谢谢,

【问题讨论】:

    标签: .net powershell object properties remote-registry


    【解决方案1】:
    $Hive = [Microsoft.Win32.RegistryHive]::LocalMachine
    $AppAddressMain = "software\Microsoft\Windows\CurrentVersion\Uninstall\"
    $AppAddressWOW = "software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
    
    Function Get-InstalledApps
    {
        param ($MainHive,
            $Computer,
            [string[]]$RegAddress)
    
        Foreach ($Address in $RegAddress)
        {
            $RegBaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($MainHive, $computer)
            $RegSubKey = $RegBaseKey.OpenSubKey($Address)
            $output = @()
            foreach ($Subkey in $RegSubKey.GetSubKeyNames())
            {
                $AppAddress = $Address + $Subkey
                $DisplayName = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayName")
                $DisplayVersion = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayVersion")
                $output += [PSCustomObject]@{ DisplayName = $DisplayName; DisplayVersion = $DisplayVersion }
            }
        }
        return $output
    }
    
    Get-InstalledApps -MainHive $Hive -Computer "MyPC" -RegAddress $AppAddressMain | sort DisplayName
    

    【讨论】:

    • 是的,我可以让它工作,它只是提供了一个与顶部代码不同的对象。这两个对象最终都是 System.arrays,但顶部会生成一个属性与“Select”语句中的项目匹配的项目,而底部则不会(它将“Keys”和“Values”列为属性而不是“DisplayName”。
    • 我忘了在上面提到,我最终将不得不对其进行排序对象属性,并且需要两个函数的逻辑相同。
    • 编辑了返回对象数组的答案。我希望我正确理解了您的目标。
    【解决方案2】:

    虽然看起来有点笨拙,但以下似乎可以工作:

     Function Get-InstalledApps {
        param ($MainHive, $Computer, [string[]]$RegAddress)
    
        Foreach($Address in $RegAddress) {
            $RegBaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($MainHive, $computer)
            $RegSubKey= $RegBaseKey.OpenSubKey($Address)
            $ReturnTotal = foreach($Subkey in $RegSubKey.GetSubKeyNames()){
                $ReturnInd = "" | Select-Object DisplayName, DisplayVersion
                $AppAddress = $Address + $Subkey
                $DisplayName = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayName")
                $DisplayVersion = $($RegBaseKey.OpenSubKey($AppAddress)).GetValue("DisplayVersion")
    
                $ReturnInd.DisplayName = $DisplayName
                $ReturnInd.DisplayVersion = $DisplayVersion
                Write-Output $Return
            }
            Write-Output $ReturnTotal
        }
    } 
    

    基本上我添加了一个单独的变量 ($ReturnInd) 来收集每个子键运行的每个拉动。然后我创建了另一个变量来包含 foreach 子键循环 ($ReturnTotal) 的全部结果,然后将其写入输出。

    结果与另一种方法不完全一样 - 第一种方法产生“Deserialized.Selected.System.Management.Automation.PSCustomObject” 而这会产生一个“Selected.System.String”,但它们都有我需要的属性。

    我可以使用以下命令对两者进行排序:

    $TempValue | Sort-Object -Property DisplayName
    

    如果有人能找到更好的方法来获得这个(或更好/更干净/更易于阅读的代码),请这样做...

    【讨论】:

      猜你喜欢
      • 2016-02-14
      • 2020-02-08
      • 2023-03-28
      • 2018-12-19
      • 2016-11-08
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多