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-ID: 379249

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

Ausgedruckt am: 21.11.2024 um 23:11 Uhr

Kraemer
Kraemer 05.07.2018 um 07:53:19 Uhr
Goto Top
Moin,

Zitat von @Bommi1961:
Geht so etwas mit PS?

ja das geht.

Gruß
erikro
erikro 05.07.2018 um 09:08:53 Uhr
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
sabines
sabines 05.07.2018 um 09:37:16 Uhr
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
Penny.Cilin
Penny.Cilin 05.07.2018 um 10:37:02 Uhr
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
colinardo
colinardo 05.07.2018 aktualisiert um 10:58:40 Uhr
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
colinardo
Lösung colinardo 09.07.2018 um 16:46:08 Uhr
Goto Top
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.
Bommi1961
Bommi1961 09.07.2018 um 20:56:17 Uhr
Goto Top
Sorry, bin krank geworden und hab es dann vergessen.

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

Viele Grüße
PeterleB
PeterleB 20.06.2020 um 11:14:56 Uhr
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
colinardo
colinardo 20.06.2020 aktualisiert um 12:20:16 Uhr
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
PeterleB
PeterleB 20.06.2020 aktualisiert um 12:27:35 Uhr
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.
colinardo
colinardo 20.06.2020 aktualisiert um 12:27:48 Uhr
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
PeterleB
PeterleB 20.06.2020 aktualisiert um 12:33:28 Uhr
Goto Top
Oh, gute Idee.

Danke.
Gruß
Peter

Sorry: Ich hatte meinen Beitrag nochmal nach deiner Antwort bearbeitet.
mazze77
mazze77 16.03.2021 um 13:11:02 Uhr
Goto Top
Hallo,
wie kann ich das Script auf einen Domänencomputer remote ausführen?

mazze
colinardo
colinardo 16.03.2021 aktualisiert um 13:50:05 Uhr
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