0

I am trying to create an object with properties identical to the code below. The following bit of code creates the $TempValueICM object with 2 added NoteProperties:

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

It creates $temptValueICM as an array object with NoteProperties of DisplayName and Display version which appear like this:

DisplayVersion : 4.92.12.0

DisplayName : Conexant 20561 SmartAudio HD

DisplayVersion :

DisplayName : Connection Manager

DisplayVersion :

DisplayName : MouseSuite98

...

I am trying to pull the same data using .NET pull with the following code:

$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
                }
             }
        }

This produces a Hash table data and I can get some information out and access it by using dot notation (e.g. - "$TempValue.DisplayName") but when looking at the object it is showing only "keys" and "values" as object properties for $TempValue object instead of what I would want to be the property names (e.g. - DisplayName and DisplayVersion).

I have tried creating a temporary variable within the function to hold the data as properties e.g. -

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

But that doesn't do it...

Specifically I will eventually have to do a sort-object -properties on it and need for the logic for both functions to be the same (i.e. - so that data can come from either "logic" in the same format so it can be treated the same way.

How do I get the object formatted so the same information is available in the same way as the $TempValueICM above above (i.e. - how do I get the items in the hash table to fill in properties on the object)? Thanks,

J.C.
  • 143
  • 1
  • 8

2 Answers2

0
$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
  • Yep, I can get it to work, it just gives an object which isn't like the code at the top. Both objects end up being System.arrays but the top produces an item with properties matching the items in the "Select" statement and the bottom doesn't (It lists "Keys" and "Values" as properties instead of "DisplayName". – J.C. Jan 09 '17 at 21:38
  • I forgot to mention above that specifically I will eventually have to do a sort-object -properties on it and need for the logic for both functions to be the same. – J.C. Jan 09 '17 at 21:39
  • Edited the answer to return an array of objects. I hope I understood your goal correctly. – user6530384 Jan 12 '17 at 20:20
0

The following appears to work although it looks a little clunky:

 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
    }
} 

Essentially I added an individual variable ($ReturnInd) to gather each pull from each Subkey run. Then I made another variable to contain the entire results of the foreach subkey loop ($ReturnTotal) and then wrote that to output.

The result isn't exactly like the other method - the first produces a "Deserialized.Selected.System.Management.Automation.PSCustomObject" whereas this produces a "Selected.System.String" but they both have the properties I need.

I am able to sort both with the following command:

$TempValue | Sort-Object -Property DisplayName

If someone can figure out a better way of getting this (or better/cleaner/easier-to-read code), please do...

J.C.
  • 143
  • 1
  • 8