4
votes

I have pieced together the following script which lists all installed applications on a local system and writes it into a logfile, but I am unaware how to get this same output when using PSRemoteRegistry, the actual input list I need this against will be all remote targets.

Does anyone have experience with fitting this same code into the cmdlets available through PSRemoteRegistry? Specifically I need it to enumerate the displayname of every installed app found in the key HKLM:\Software\Microsoft\CurrentVersion\Uninstall

The piece I am needing help with getting into the PSRemoteRegistry cmdlets is:

Get-ChildItem 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object {Log (Get-ItemProperty $_.pspath).DisplayName}

and this is the entire script:

    clear
    #$ErrorActionPreference = "silentlycontinue"

    $Logfile = "C:\temp\installed_apps.log"

    Function Log
    {
        param([string]$logstring)

        Add-Content $Logfile -Value $logstring
    }

    $target_list = Get-Content -Path c:\temp\installed_apps_targets.txt

    foreach ($system in $target_list){

        if (test-connection $system -quiet) 
        {
           Log "---------------Begin $system---------------"
           Get-ChildItem 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object {Log (Get-ItemProperty $_.pspath).DisplayName}
           Log "---------------End $system---------------"
        }
        else 
        {
            Log "**************$system was unreachable**************"
        }

}
2
Why not deploy the script using PowerShell Remoting, and get the results back in your host session? I'd recommend returning objects from your function instead of writing text to a log file. That will help you work with the results more effectively. - user189198
My only problem there is we are talking about 26 domains and over 3,000 servers. I can't rely on manual configuration modifications at a host level to accommodate executing the script. Wouldn't PowerShell Remoting require touching each to ensure powershell and the proper configuration are in place on the target systems? - Turtle_in_a_Powershell

2 Answers

1
votes

You can adapt something like this:

$Computer = "ComputerName"

$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$RegKey= $Reg.OpenSubKey('Software\Microsoft\Windows\CurrentVersion\Uninstall')

$Keys = $RegKey.GetSubKeyNames()

$Keys | ForEach-Object {
   $Subkey = $RegKey.OpenSubKey("$_")
   Write-Host $Subkey.GetValue('DisplayName')
}
1
votes

Have you met Invoke-Command?

$Logfile = "C:\temp\installed_apps.log"

Function Log() {
    param([string]$logstring)

    Add-Content $Logfile -Value $logstring
}

$scriptbock = {Get-ChildItem 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object {Log (Get-ItemProperty $_.pspath).DisplayName}}

Get-Content -Path c:\temp\installed_apps_targets.txt | % {
    if (test-connection $_ -quiet) {
       Log "---------------Begin $system---------------"
       Log $(Invoke-Command -ComputerName $_ -ScriptBlock $scriptblock)
       Log "---------------End $system---------------"
    }
    else 
    {
        Log "**************$system was unreachable**************"
    }

}