bommi1961
Goto Top

Mit Powershell in der Reg. auslesen um den UninstallString zu bekommen

Hallo zusammen,

wir brauchen ein PS Skript mit dem man die Reg. auf (WIN 7, 8 und 10 32/64Bit) System durch suchen kann um her raus zubekommen ob ein Bestimmtes Programm installiert ist. z.B. Adobe Acrobat Professional oder Standard.

Wir haben folgendes Problem:

Auf vielen Systemen sind viele verschiedene Version von einem Programm installiert z. B. Adobe Acrobat damit wir nicht immer erst auf dem System suchen müssen ob eine Bestimmt Version installiert ist, brauchen wir ein Skript das die Reg nach z. B. Adobe Acrobat* durch sucht. Wenn es unter dem DisplayName Adobe Acrobat* gefunden hat, muss es dann den Wert unter UninstallString auslesen und die Deinstallation Silent ausführen oder den Wert in eine Datei ausgeben.

Geht so etwas mit PS?

VG
Thilo

Content-Key: 379249

Url: https://administrator.de/contentid/379249

Printed on: April 25, 2024 at 12:04 o'clock

Member: Kraemer
Kraemer Jul 05, 2018 at 05:53:19 (UTC)
Goto Top
Moin,

Zitat von @Bommi1961:
Geht so etwas mit PS?

ja das geht.

Gruß
Member: erikro
erikro Jul 05, 2018 at 07:08:53 (UTC)
Goto Top
Moin,

Zitat von @Bommi1961:
Geht so etwas mit PS?

Ja. Du hast auf der PS direkten Zugriff auf die Registrykeys HKLM und HKCU. Das sind Pseudolaufwerke. Tipp einfach mal auf der Shell z. B.:

get-childitem HKLM:\Software

So kannst Du, entsprechende Rechte vorausgesetzt, direkt die Registry auslesen und auch reinschreiben.

hth

Erik
Member: sabines
sabines Jul 05, 2018 at 07:37:16 (UTC)
Goto Top
Moin,

mal nebenbei:
Wenn Du Software per GPO verteilst, kannst Du die "alte" Version entfernen lassen und so sicher stellen, dass immer nur die aktuelle Version installiert wird. Außerdem hast Du oft beim Paketieren oder Anpassen für den GPO Rollout Optionen wie " alte Versionen deinstallieren" o.ä.

Für Abobe und co kannst Du auf den UninstallString verzichten, bei Adobe Air u. ä. allerdings nicht.

Gruss
Member: Penny.Cilin
Penny.Cilin Jul 05, 2018 at 08:37:02 (UTC)
Goto Top
Hallo,

was hast Du bisher mittels PowerShell eruiert?
Was hast Du bisher überhaupt eruiert?

Du weißt schon, daß Installationen in der Registry in der Regel unter
HKLM\Software
zu finden ist?
Manche Softwareinstallationen findest Du in der Registry auch unter
HKCU\Software
. Zumindest die Enstellungen.
Wie sind Deine PowerShellkenntnisse?

Gruss Penny
Member: colinardo
colinardo Jul 05, 2018 updated at 08:58:40 (UTC)
Goto Top
Das das heutzutage noch jemand fragt, das ist doch schon lange alter Käse und es gibt millionenfache Infos dazu ... face-smile
# Function to get installed Software (Method Remote-WMI)
function Get-InstalledSoftware {
    param(
        [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$Computer
    )
    $all = @();$hklm = 2147483650; $hkcu = 2147483649
    # Subkeydefinition for Uninstallinformation
    $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"  
    $key64 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"  
    try{
        # connect to StdRegProv via Remote-WMI
        $reg = gwmi -List "StdRegProv" -ComputerName $Computer -Namespace root\Default  
        # scriptblock function to get desired Information
        $getnodedata = {
            param($section,$k)
            $reg.EnumKey($section,$k).sNames | %{
                [pscustomobject] @{
                    Name=$reg.GetStringValue($section,"$k\$_","DisplayName").sValue  
                    Version=$reg.GetStringValue($section,"$k\$_","DisplayVersion").sValue  
                    InstallLocation=$reg.GetStringValue($section,"$k\$_","InstallLocation").sValue  
                    InstallSource=$reg.GetStringValue($section,"$k\$_","InstallSource").sValue  
                    UninstallString=$reg.GetStringValue($section,"$k\$_","UninstallString").sValue  
                    InstallDate=$reg.GetStringValue($section,"$k\$_","InstallDate").sValue  
                }
            }
        }
        # call scriptblock function 
        $all += .$getnodedata $hklm $key
        $all += .$getnodedata $hkcu $key
        # call scriptblock function for 64bit section if available
        if ((gwmi Win32_OperatingSystem -ComputerName $computer).OSArchitecture -eq '64-Bit'){  
            $all += .$getnodedata $hklm $key64
            $all += .$getnodedata $hkcu $key64
        }
    }catch{
        throw $_.Exception.Message
    }
    # return sorted and unique object data
    return ($all | ?{$_.Name -ne $null} | sort Name | select Name,Version,InstallLocation,InstallSource,UninstallString,InstallDate -Unique)
}

$result = Get-InstalledSoftware $env:COMPUTERNAME
$result | select Name,UninstallString
Grüße Uwe
Member: colinardo
Solution colinardo Jul 09, 2018 at 14:46:08 (UTC)
Goto Top
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.
Member: Bommi1961
Bommi1961 Jul 09, 2018 at 18:56:17 (UTC)
Goto Top
Sorry, bin krank geworden und hab es dann vergessen.

Vielen Dank noch für die tolle Lösung.

Viele Grüße
Member: PeterleB
PeterleB Jun 20, 2020 at 09:14:56 (UTC)
Goto Top
Hallo Uwe / colinardo,

gibt es eine Möglichkeit, die im pscustomobject festgelegten Variablen bei der Ausgabe umzuformatieren?
Also zum Beispiel "InstallDate" statt "20200612" dann "12.06.2020".

Gruß
Peter
Member: colinardo
colinardo Jun 20, 2020 updated at 10:20:16 (UTC)
Goto Top
Servus Peter,
ja klar, man muss nur mehr Datums-Varianten berücksichtigen da das Format hier keinen Vorgaben entsprechen muss.
function Get-InstalledSoftware {
    param(
        [parameter(mandatory=$true)][ValidateNotNullOrEmpty()][string]$Computer
    )
    $all = @();$hklm = 2147483650; $hkcu = 2147483649
    # Subkeydefinition for Uninstallinformation
    $key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"  
    $key64 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"  
    try{
        # connect to StdRegProv via Remote-WMI
        $reg = gwmi -List "StdRegProv" -ComputerName $Computer -Namespace root\Default  
        # scriptblock function to get desired Information
        $getnodedata = {
            param($section,$k)
            $reg.EnumKey($section,$k).sNames | %{
                # raw install date
                $installdate = $reg.GetStringValue($section,"$k\$_","InstallDate").sValue  
                $idate = [datetime]::MinValue
                # try parse different date formats
                if (![datetime]::TryParseExact($installdate,'yyyyMMdd',[cultureinfo]::InvariantCulture,[System.Globalization.DateTimeStyles]::None,[ref]$idate)){  
                    [datetime]::TryParse($installdate,[ref]$idate)
                }
                # when date could not converted set to reg value
                if ($idate -eq [datetime]::MinValue){$idate = $installdate}
                [pscustomobject] @{
                    Name=$reg.GetStringValue($section,"$k\$_","DisplayName").sValue  
                    Version=$reg.GetStringValue($section,"$k\$_","DisplayVersion").sValue  
                    InstallLocation=$reg.GetStringValue($section,"$k\$_","InstallLocation").sValue  
                    InstallSource=$reg.GetStringValue($section,"$k\$_","InstallSource").sValue  
                    UninstallString=$reg.GetStringValue($section,"$k\$_","UninstallString").sValue  
                    InstallDate=$idate
                }
            }
        }
        # call scriptblock function 
        $all += .$getnodedata $hklm $key
        $all += .$getnodedata $hkcu $key
        # call scriptblock function for 64bit section if available
        if ((gwmi Win32_OperatingSystem -ComputerName $computer).OSArchitecture -eq '64-Bit'){  
            $all += .$getnodedata $hklm $key64
            $all += .$getnodedata $hkcu $key64
        }
    }catch{
        throw $_.Exception.Message
    }
    # return sorted and unique object data
    return ($all | ?{$_.Name -ne $null} | sort Name | select Name,Version,InstallLocation,InstallSource,UninstallString,InstallDate -Unique)
}

$result = Get-InstalledSoftware $env:COMPUTERNAME
$result | select Name,InstallDate
Das Feld ist anschließend vom Typ [DateTime] und damit kann dann wie gewohnt weiterverarbeitet werden
Grüße Uwe
Member: PeterleB
PeterleB Jun 20, 2020 updated at 10:27:35 (UTC)
Goto Top
Hallo Uwe,

vielen Dank.
Ich hatte auch schon diese Umwandlungssache [datetime]::TryParseExact..... ausprobiert.
Da ich jedoch direkt im pscustumobjekt herumgecodet hab, gab's immer wieder Fehler.

Geht jetzt noch die Datumsausgabe ohne Uhrzeit?

Habe jetzt nur noch die Ausgabe geändert:
$fName = "$env:COMPUTERNAME-InstalledApps.txt"  
$result | select Name,Version,InstallDate > $fName

Vielen Dank nochmal.
Member: colinardo
colinardo Jun 20, 2020 updated at 10:27:48 (UTC)
Goto Top
$result | select Name,Version,InstallDate > $fName
Besser gleich als CSV ausgeben, so ist das unsicher (bzw. führt sonst bei langen Strings zum Abschneiden dieser oder fehlenden Spalten).
$result | select Name,Version,InstallDate | export-csv .\installed_progs.csv -Delimiter ";" -NoType -Encoding UTF8  
Du hast ja ein Object face-wink
Member: PeterleB
PeterleB Jun 20, 2020 updated at 10:33:28 (UTC)
Goto Top
Oh, gute Idee.

Danke.
Gruß
Peter

Sorry: Ich hatte meinen Beitrag nochmal nach deiner Antwort bearbeitet.
Member: mazze77
mazze77 Mar 16, 2021 at 12:11:02 (UTC)
Goto Top
Hallo,
wie kann ich das Script auf einen Domänencomputer remote ausführen?

mazze
Member: colinardo
colinardo Mar 16, 2021 updated at 12:50:05 (UTC)
Goto Top
Zitat von @mazze77:

Hallo,
wie kann ich das Script auf einen Domänencomputer remote ausführen?

mazze
Servus,
ganz einfach , stelle sicher das Remote WMI Verwaltungsausnahme in der Firewall aktiviert wurde (auf den Rechner also per WMI zugegriffen werden kann). Dann einfach das Skript mit entsprechend berechtigten Account und dem Ziel-Computernamen als Parameter (also Get-InstalledSoftware "Computername") ausführen, fertig.

Grüße Uwe