PowerShell Installations Pfad installierter Software

Piktogramm

Admiral
Registriert
Okt. 2008
Beiträge
8.871
TLDR: Ich suche das "whereis" der Windows & Powershell 7 Welt.

Es muss mit Powershell 7 funktionieren, gern ohne externe cmdlets.

Ich würde gern den Installationsort von Software über die Powershell auslesen. Also Get-CimInstance Win32_Product -Filter "Name like 'Duplicati 2'" | Select InstallLocation. Tja, da steht aber nichts in InstallLocation, wobei dies nicht nur bei Duplicati der Fall ist, sondern bei >2/3 aller installierter Software auf dem Rechner. Selbst wenn die Software von Microsoft selber kommt, klappt es oft nicht.
Die Frage ist nun, wie komme ich (möglichst elegant) an folgendes:
1. Ist Software installiert
2. In Welchem Ordner liegt Software

Beispiel:
Get-CimInstance Win32_Product -Filter "Name like 'Duplicati 2'" | Select *

Name : Duplicati 2
Version : 2.0.5.1
InstallState : 5
Caption : Duplicati 2
Description : Duplicati 2
IdentifyingNumber : {UUID}
SKUNumber :
Vendor : Duplicati Team
AssignmentType : 1
HelpLink :
HelpTelephone :
InstallDate : 20220828
InstallDate2 :
InstallLocation :
InstallSource : C:\Users\bob\AppData\Local\Temp\chocolatey\duplicati\2.0.5.1\
Language : 1033
LocalPackage : C:\windows\Installer\1dc78e.msi
PackageCache : C:\windows\Installer\1dc78e.msi
PackageCode : {UUID}
PackageName : duplicati-2.0.5.1_beta_2020-01-18-x64.msi
ProductID :
RegCompany :
RegOwner :
Transforms :
URLInfoAbout :
URLUpdateInfo :
WordCount : 0
PSComputerName :
CimClass : root/cimv2:Win32_Product
CimInstanceProperties : {Caption, Description, IdentifyingNumber, Name…}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

Klar auf Verdacht alle Laufwerke durchsuchen wäre möglich, das ist nur nicht elegant und Imho ist Suche unter Windows absurd langsam. Schon das Get-CimInstance dauert ja ewig (<10s) auf einem flotten Notebook und mit warmen Caches -.-
 
Versuch das hier mal - ist natürlich nur ein Anstoß, kein fertiges Script für deinen Fall.

PowerShell:
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Sort Displayname | Select-Object DisplayName, DisplayVersion, InstallDate, Publisher, InstallLocation
 
@derlorenz
Die Datenquelle ist in beiden Fällen die Selbe..

Get-Property auf die Registrypfade ist aber immerhin bedeutend schneller als mein Ansatz :)
 
Piktogramm schrieb:
Die Datenquelle ist in beiden Fällen die Selbe..
Sorry stehe gerade auf dem Schlauch, meinst du die beiden Pfade? Ist einmal quasi x86 bzw x64.
 
@derlorenz
Get-CmiInstance Win32_Product fragt die Registry ebenso ab wie dein Get-ItemProperty mit der Angabe der Registrypfade. In den Registrypfaden muss nach x32 und x64 unterschieden werden, was in deiner Abfrage passiert, wobei CmiInstance zwar nach Win32_Product fragt, die Win32_Product Klasse enthält jedoch alle Einträge, egal ob 32 oder 64bit.

Edit, Quelle:
https://docs.microsoft.com/en-us/windows/win32/wmisdk/requesting-wmi-data-on-a-64-bit-platform
unter Accessing the Default Registry Hive
Ist zwar für WMI Objects, aber unter Powershell 7 ist Cmi quasi das Selbe, also außer an den Stellen wo es das nicht ist..


PS: Mir geht Windows echt mal richtig auf den Sack, inkonsistente Scheiße alles -.-
 
  • Gefällt mir
Reaktionen: derlorenz
Mehr als die zwei Möglichkeiten gibt’s soweit ich weiß aber leider nicht. Selbst irgendwelche inventarisierungstools bedienen sich ja auch nur dessen. 😩

Kann ich verstehen, stand heute zufälligerweise vor dem selben Problem.
 
  • Gefällt mir
Reaktionen: Piktogramm
Piktogramm schrieb:
Klar auf Verdacht alle Laufwerke durchsuchen wäre möglich, das ist nur nicht elegant und Imho ist Suche unter Windows absurd langsam.
Es ist weniger fehleranfällig und das "langsam" kann ich nicht bestätigen. Zum einen kannst du gegen indizierte Daten arbeiten und parallele Anfragen gehen auch.
 
Zuletzt bearbeitet:
Danke Micke, aber..

Die pure Suche mittels Get-ChildItem ist absurd langsam, damit mehrere Laufwerke zu beackern ist selbst mit ForeachObject -Parallel ein Ding von ~10min[1] und bei Namenskollisionen liegt es an meinem Script diese abzufangen mit allen möglichen Vermurksungen die seitens der Nutzenden möglich sind.
Selbst wenn es über den Index geht, der muss aktiv sein, muss die gesuchten Pfade beinhalten und als Fallback wäre es sinnvoll sowieso eine reguläre suche zu implementieren.

Das ist Alles, nur nicht elegant, dafür das Windows eine zentrale Registry "pflegt" :/

[1] Vor allem, Get-ChildItem ist extrem CPU limitiert statt I/O, dass muss man erstmal hinbekommen eine Suche über das Dateisystem zu bauen, die nicht I/O-bound ist. Auch die 10min, das ist ein TigerLake mit ner 980Pro SSD und wenig Daten. Die 10min sind also das untere Limit -.-
 
Zuletzt bearbeitet:
Piktogramm schrieb:
Vor allem, Get-ChildItem ist extrem CPU limitiert statt I/O,
Hast du zufällig Get-ChildItem mit -Recurse und -Path genutzt? Das ist langsam, schau mal hier. Nimm stattdessen -LiteralPath. Das sollte deutlich schneller sein.
 
@Evil E-Lex
Wow, das ist wirklich ein Unterschied wie Tag und Nacht und entspricht in etwa dem, was ich von einer Suche auf einer SSD erwarte. Danke!

Das Verhalten und der Bug-Report sind aber auch lustig. Da wird noch fröhlich auf ein Bugreport von 2017 verwiesen, wo das Verhalen quasi auch schon kiritisiert wird und es endet quasi mit einem "won't fix, too much work needed".
 
  • Gefällt mir
Reaktionen: Evil E-Lex
Zurück
Oben