powershell to get installed software

powershell to get installed software

Jeder Administrator kennt den Moment, in dem die manuelle Suche in der Systemsteuerung zur Qual wird. Du sitzt vor einem Server, die Zeit drängt, und du musst sofort wissen, welche Versionen von Java oder Chrome auf dreißig verschiedenen Maschinen laufen. Die grafische Oberfläche von Windows ist für solche Aufgaben schlicht zu langsam und unhandlich. Wer effizient arbeiten will, greift zur Konsole und nutzt PowerShell To Get Installed Software, um präzise Daten ohne unnötiges Klicken zu extrahieren. Es geht hier nicht nur um Bequemlichkeit. Es geht um Compliance, Sicherheit und saubere Inventarisierung in einer Welt, in der veraltete Software-Stände ein enormes Sicherheitsrisiko darstellen.

Ich habe über die Jahre unzählige Skripte gesehen, die versuchen, diese Liste auszulesen. Viele scheitern an der Komplexität der Windows-Registry oder an den Unterschieden zwischen 32-Bit und 64-Bit Anwendungen. Windows speichert Informationen über installierte Programme an verschiedenen Orten, was die Sache kompliziert macht. Wenn du einfach nur wissen willst, was auf der Kiste drauf ist, reicht ein einfacher Befehl oft nicht aus. Du musst verstehen, wo das System diese Daten versteckt.

Die Suchintention hinter diesem Thema ist klar: Du suchst eine schnelle, zuverlässige Lösung, um Softwarelisten zu generieren. Du willst keine Theorie hören, sondern Code sehen, der funktioniert. Gleichzeitig gibt es Fallstricke bei der Performance und der Vollständigkeit der Daten, die wir uns jetzt ansehen.

Warum die Registry oft besser als WMI ist

Viele greifen instinktiv zu WMI (Windows Management Instrumentation), wenn sie Software abfragen wollen. Der Befehl Get-WmiObject -Class Win32_Product ist berühmt-berüchtigt. Er ist langsam. Er ist unzuverlässig. Schlimmer noch: Dieser Befehl löst im Hintergrund oft eine Konsistenzprüfung jedes einzelnen MSI-Pakets aus. Das kann dazu führen, dass Dienste kurzzeitig hängen oder Event-Logs mit Warnungen geflutet werden. In einer Produktionsumgebung ist das ein No-Go.

Der direkte Weg über die Registry ist deutlich schneller. Die Informationen liegen dort in Pfaden wie HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall. Hier trägt fast jedes Programm seinen Namen, die Version und den Deinstallations-String ein. Wenn du ein 64-Bit System hast, musst du zusätzlich den Pfad für 32-Bit Anwendungen unter Wow6432Node berücksichtigen. Das macht die Abfrage etwas komplexer, aber die Geschwindigkeit belohnt dich dafür.

Ein professioneller Ansatz nutzt das Get-ItemProperty Cmdlet. Damit navigierst du durch die Registry-Pfade wie durch ein Dateisystem. Du liest die Eigenschaften aus und filterst die Ergebnisse nach Namen, die nicht leer sind. Das spart Zeit und Nerven.

Der WMI-Mythos und seine Gefahren

Ich warne dich ausdrücklich vor Win32_Product. Es gab Fälle, in denen dieser Befehl Reparaturinstallationen angestoßen hat, die Konfigurationen überschrieben haben. Wenn du für ein Unternehmen arbeitest, das strenge Change-Management-Prozesse hat, willst du nicht derjenige sein, der durch eine einfache Abfrage einen Server-Reboot provoziert.

Nutze stattdessen lieber Get-CimInstance, wenn du unbedingt über die Management-Schnittstellen gehen musst. Es ist die modernere, auf Standards basierende Version von WMI. Aber selbst hier gilt: Die Liste ist oft unvollständig, da sie nur Programme zeigt, die per Windows Installer (MSI) installiert wurden. Portable Apps oder per Executable installierte Tools fehlen hier komplett.

Professionelle Nutzung von PowerShell To Get Installed Software

Um wirklich alle Anwendungen zu erfassen, müssen wir mehrere Quellen kombinieren. Ein cleveres Skript schaut in den 64-Bit Registry-Zweig, den 32-Bit Zweig und idealerweise auch in das Benutzerprofil des aktuell angemeldeten Users. Viele moderne Apps, wie etwa Microsoft Teams (die klassische Version) oder VS Code, installieren sich oft nur für den aktuellen Benutzer unter AppData.

Hier ist ein konkretes Beispiel, wie du die Registry effizient abfragst:

$paths = @("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*") Get-ItemProperty $paths | Select-Object DisplayName, DisplayVersion, Publisher | Where-Object { $_.DisplayName -ne $null }

Diese zwei Zeilen erledigen das, was die Windows-Oberfläche in Minuten macht, in Bruchteilen einer Sekunde. Du kannst das Ergebnis direkt in eine CSV-Datei exportieren. Das ist Gold wert für Audits. Ein einfacher Befehl wie Export-Csv -Path C:\Inventur.csv -NoTypeInformation am Ende der Pipeline genügt.

Filtern und Sortieren für den schnellen Überblick

Oft suchst du nur nach einem bestimmten Tool. Vielleicht geht es um eine Sicherheitslücke in einer alten Version von Log4j oder einer speziellen Browser-Erweiterung. Hier glänzt die PowerShell. Mit dem Operator -like und Platzhaltern wie * findest du sofort, was du brauchst.

Willst du zum Beispiel alle Adobe-Produkte finden, hängst du einfach | Where-Object { $_.DisplayName -like "*Adobe*" } an deinen Befehl an. Das ist intuitiv. Es ist schnell. Und es lässt sich wunderbar automatisieren. Wenn du hunderte Rechner verwaltest, kannst du diesen Befehl über Invoke-Command auf einer ganzen Liste von Computern gleichzeitig ausführen.

Remote-Abfragen im Firmennetzwerk

In einer Domänenstruktur willst du nicht zu jedem PC laufen. Du nutzt PowerShell Remoting. Das muss natürlich aktiviert sein. In den meisten modernen Unternehmen ist das über Gruppenrichtlinien bereits erledigt. Der Vorteil hier ist, dass die Rechenlast auf dem Zielsystem liegt. Dein lokaler Rechner sammelt nur die fertigen Objekte ein.

Wenn du PowerShell To Get Installed Software auf entfernten Systemen einsetzt, achte auf die Berechtigungen. Du brauchst Administratorrechte auf den Zielmaschinen. Ohne diese Rechte bleibt die Registry für dich teilweise verschlossen. Die Fehlermeldungen in der Konsole können dann kryptisch sein, aber meistens liegt es schlicht am fehlenden Zugriff.

Performance-Optimierung bei großen Netzwerken

Stell dir vor, du fragst 500 Clients ab. Wenn du das sequenziell machst, dauert es ewig. Hier kommen "Jobs" oder das Konzept der Parallelisierung ins Spiel. Seit PowerShell 7 gibt es den Parameter -Parallel bei ForEach-Object. Das ist ein echter Gamechanger. Du kannst damit 20 oder 30 Abfragen gleichzeitig starten.

Was früher eine Kaffeepause lang dauerte, ist jetzt fertig, bevor du den ersten Schluck genommen hast. Du musst jedoch darauf achten, das Netzwerk nicht zu fluten. Eine zu hohe Anzahl paralleler Abfragen kann die Bandbreite belasten oder den Domänencontroller unter Stress setzen, wenn viele Authentifizierungen gleichzeitig einschlagen.

Die Rolle von Paketmanagern wie Winget und Chocolatey

Wir bewegen uns weg von der rein manuellen Installation. Microsoft hat mit Winget endlich einen eigenen Paketmanager am Start. Das verändert die Art, wie wir installierte Software betrachten. Mit dem Befehl winget list erhältst du eine extrem saubere Liste, die sogar anzeigt, ob Updates verfügbar sind.

Winget erkennt Anwendungen, die über den Store, über MSI oder über klassische Installer auf das System kamen. Es ist die modernste Art, den Software-Bestand zu prüfen. Wenn du eine aktuelle Windows 10 oder 11 Version nutzt, ist Winget meist vorinstalliert. Es bietet eine konsistente Ausgabe, die sich leicht parsen lässt.

Integration von Winget in Skripte

Man kann Winget-Befehle direkt in PowerShell-Skripte einbauen. Da die Ausgabe von Winget jedoch Text und kein Objekt ist, muss man manchmal etwas tricksen, um die Daten weiterzuverarbeiten. Es gibt Community-Module, die Winget-Output in echte Objekte umwandeln. Das macht die Arbeit damit wesentlich angenehmer.

💡 Das könnte Sie interessieren: diesen Beitrag

Ein großer Vorteil von Tools wie Winget oder auch Chocolatey ist die Standardisierung. Du weißt genau, wo die Software liegt und wie sie benannt ist. Das Ende des "Wilden Westens" der Installationen ist nah. Für dich als Admin bedeutet das weniger Kopfschmerzen bei der Inventur.

Häufige Fehlerquellen und wie du sie vermeidest

Einer der größten Fehler ist die Annahme, dass "Programme und Features" in der Systemsteuerung alles anzeigt. Das stimmt nicht. Es gibt Treiber, Updates und Frameworks, die dort oft ausgeblendet werden, um den Nutzer nicht zu verwirren. In der Registry sind sie aber vorhanden.

Ein weiteres Problem sind 32-Bit Anwendungen auf 64-Bit Systemen. Wenn du nur den Pfad HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall prüfst, fehlen dir alle 32-Bit Programme. Diese landen im WOW6432Node. Das ist ein historisches Überbleibsel von Windows, das uns wohl noch lange begleiten wird. Wer diesen Pfad vergisst, liefert einen unvollständigen Bericht ab.

Umgang mit leeren DisplayNames

Manche Registry-Keys haben keinen DisplayName. Das sind oft Komponenten von Windows selbst oder kleine Hilfsprogramme, die keine eigene Oberfläche haben. In deinem Skript solltest du diese herausfiltern, um die Liste sauber zu halten. Ein einfacher Filter auf $_.DisplayName sorgt dafür, dass deine Liste nur "echte" Software enthält, mit der ein Mensch etwas anfangen kann.

Achte auch auf das Feld InstallDate. Das Format in der Registry ist oft YYYYMMDD. PowerShell erkennt das nicht automatisch als Datumsobjekt. Wenn du nach dem Installationsdatum sortieren willst, musst du diesen String erst manuell in ein echtes Datum umwandeln. Das ist ein wenig Fleißarbeit, aber es lohnt sich für die Übersichtlichkeit.

Automatisierung für regelmäßige Berichte

Einmaliges Abfragen ist gut. Automatisiertes Reporting ist besser. Du kannst ein Skript schreiben, das jeden Montagmorgen die installierte Software aller Server scannt und die Ergebnisse in einer SQL-Datenbank oder einer einfachen JSON-Datei speichert. So siehst du Veränderungen über die Zeit.

Warum hat Server B plötzlich eine alte Java-Version? Wer hat Software X auf dem Domain Controller installiert? Solche Fragen lassen sich nur beantworten, wenn du historische Daten hast. Ein kleiner Task im Task-Scheduler reicht oft schon aus, um diese Transparenz zu schaffen.

Exportformate: CSV vs. JSON vs. HTML

Die Wahl des Formats hängt davon ab, was du mit den Daten vorhast. CSV ist perfekt für Excel und schnelle Analysen. JSON ist super, wenn du die Daten in eine Web-App oder eine Datenbank einspeisen willst. PowerShell unterstützt beide Formate nativ mit ConvertTo-Json und Export-Csv.

HTML ist toll, wenn du den Bericht direkt per E-Mail an deinen Chef schicken willst. Mit ConvertTo-Html und ein wenig CSS-Code sieht die Liste professionell aus und kann von jedem im Browser geöffnet werden. Das spart Zeit beim Erklären von Konsolenausgaben.

Sicherheit und Compliance durch Software-Inventur

In Zeiten von Ransomware ist es lebenswichtig zu wissen, welche Software auf den Rechnern läuft. Ungepatchte Anwendungen sind die Einfallstore Nummer eins. Ein PowerShell-Skript, das gezielt nach bekannten problematischen Versionen sucht, ist eine mächtige Waffe in deinem Sicherheits-Arsenal.

Du kannst zum Beispiel eine Blacklist definieren. Dein Skript gleicht die installierte Software mit dieser Liste ab und schlägt sofort Alarm, wenn verbotene Programme gefunden werden. Das ist proaktive Systemsicherheit, die nichts kostet außer ein paar Zeilen Code. Organisationen wie das BSI empfehlen regelmäßig solche Audits der installierten Basis.

Der Weg zur "Single Source of Truth"

Es gibt teure Asset-Management-Lösungen auf dem Markt. Aber oft können diese auch nicht mehr als das, was du mit PowerShell selbst bauen kannst. Für kleine und mittelständische Unternehmen ist ein gut geschriebenes Skript oft die flexibelste und günstigste Lösung. Du behältst die volle Kontrolle über deine Daten und bist nicht von einem Drittanbieter abhängig.

Das Wissen darüber, wie man Informationen aus dem System kitzelt, macht dich als IT-Experten wertvoll. Es zeigt, dass du die Interna von Windows verstehst und nicht nur bunte Knöpfe drücken kannst. Die PowerShell ist das Schweizer Taschenmesser für jeden, der Windows professionell verwaltet.

Praktische nächste Schritte

Damit du direkt loslegen kannst, solltest du folgende Punkte umsetzen. Es bringt nichts, nur darüber zu lesen – du musst es im Terminal ausprobieren.

  1. Öffne die PowerShell ISE oder VS Code mit Administratorrechten.
  2. Kopiere den Registry-Abfrage-Befehl von oben und führe ihn aus. Schau dir die Ergebnisse genau an.
  3. Versuche, die Liste nach dem Publisher zu filtern, um nur Software eines bestimmten Herstellers zu sehen (z.B. Microsoft oder Adobe).
  4. Erstelle einen Export in eine CSV-Datei und öffne diese in Excel. Überprüfe, ob alle Spalten korrekt übernommen wurden.
  5. Wenn du mutig bist: Probiere Winget aus. Tippe winget list und vergleiche das Ergebnis mit deiner Registry-Abfrage. Du wirst feststellen, dass beide Ansätze ihre Daseinsberechtigung haben.
  6. Überlege dir, wie du diesen Prozess automatisieren kannst. Ein Skript, das die Ergebnisse auf einem Netzlaufwerk ablegt, ist ein hervorragender Start für eine eigene Inventarisierung.

Jedes System ist anders. Manche Programme schreiben ihre Daten an völlig unübliche Orte. Aber mit der Kombination aus Registry-Scans und modernen Tools wie Winget deckst du 99% aller Fälle ab. Es gibt keinen Grund mehr, sich auf manuelle Listen zu verlassen. Die Werkzeuge liegen bereit – du musst sie nur benutzen. Wer einmal die Macht der Automatisierung gespürt hat, kehrt nie wieder zur Systemsteuerung zurück.

JS

Julia Schmitt

Im Fokus von Julia Schmitt stehen verlässliche Quellen, nachvollziehbare Daten und eine ausgewogene Darstellung.