Wer gehört zum wem? (Module zu einem Prozess lokalisieren)

Die PowerShell 1.0 richtet sich definitiv nicht an Entwickler, sondern an den „normalen“ Anwender bzw. Systemadministrator, auch wenn Entwickler mit Begriffen wie Objekt, Typ, .NET-Klassenbibliothek oder Shared-Methode wie selbstverständlich umgehen, die einem „normalen“ Anwender reichlich abstrakt vorkommen. Dennoch sind Vorkenntnisse in diesem Bereich nicht immer förderlich, da sich (.NET-) Entwickler eine Denkweise angewöhnt haben, die bei der Einarbeitung in die PowerShell nicht immer förderlich ist:

1) Entwickler suchen instinktiv im .NET-Framework nach einer Lösung, statt nach geeigneten Cmdlets zu suchen (die es häufig gibt)

2) Entwicklern tun sich noch schwer mit dem „Extensible Type System“ derPowerShell und denken häufig noch in den Kategorien eines statischen Type Systems, wo ein Typ einen „in Stein gemeiselten“ Satz an Members besitzt (die PowerShell ist in diesem Punkt flexibler).

3) Entwickler ignorieren gerne die Möglichkeiten der Pipeline.

Ich hoffe, ich schließe mit diesen Behauptungen nicht zu sehr von mich auf andere, aber wie schwierig es ist, ausgetretene Denkpfade zu verlassen wurde mir neulich wieder an einer relativ einfachen Aufgabenstellung deutlich:

Liste alle Prozesse auf, die ein bestimmtes Modul, wie z.B. Comctl32.dll, laden.

Dazu eine kleine Hintergrundinfo. Jeder Prozess lädt unter Windows eine oder mehrere Systemdateien (sie tragen in der Regel die Erweiterung .Dll), die in diesem Zusammenhang auch als Module bezeichnet werden. Ein

get-process | select-object -expandproperty modules

listet die Namen aller Prozesse und der von ihnen geladenen Module auf. Da das Resultat in dieser Rohform praktisch unbrauchbar ist, sollte man sich die Mühe machen und per select-object ein neues Objekt anzulegen, das den Prozessnamen und die Namen der Module, die der Prozess geladen hat, etwas „netter“ auflisten:

get-process | select-object -property @{Name=“Prozess“;Expression={$_.Name}} -expandproperty Modules

oder

get-process | select-object -property @{Name=“Prozess“;Expression={$_.Name}}, @{Name=“Module“;Expression={$_.Modules}}

oder, wenn man die Prozesse nach der Anzahl ihrer Module sortiert auflisten möchte

get-process | select-object -property @{Name=“Prozess“;Expression={$_.Name}},@{Name=“Anzahl-Module“;Expression={@($_.Modules).Length}} | sort-object „Anzahl-Module“ -desc

(dabei stellt sich z.B. heraus, dass Outlook 2007 ganze 190 Module lädt).

Leider bietet der ExpandProperty-Parameter keine Möglichkeit, einen Hashtable-Ausdruck folgen zu lassen, wie es beim Property-Parameter möglich ist, was die Möglichkeit einschränkt, die zu einem Prozess gehörenden Module auf einfache Weise ein wenig hübscher formatiert anzuzeigen.

100% befriedigend sind die Resultate daher nicht, da einfach zu viele Informationen nicht gerade übersichtlich angezeigt werden. Wer das alles in „Report-Qualität“ sehen möchte, müsste sich die Mühe machen und ein kleines Skript entwerfen. Nach dem Motto „Das kann theoretisch jeder“, soll eine solche Lösung im Folgenden nicht in Betracht gezogen werden. Gesucht ist vielmehr ein typischer Einzeiler, der das Ergebnis halbwegs übersichtlich präsentiert.

Etwas kniffliger wird es bei einer Adhoc-Abfrage, wenn man z.B. nur jene Prozesse sehen möchte, die ein bestimmtes Modul laden. Die folgende Lösung entspricht der typischen „Entwicklerdenkweise“, bei der solange Schleifen und Bedingungen kombiniert werden, bis das Ergebnis passt.

Der folgende Befehl gibt die Namen aller Prozesse aus, die z.B. das Modul Comctl32.dll geladen haben:

foreach($P in (get-process)) { if(@($P | select -expandproperty Modules -errorAction SilentlyContinue | where { $_.ModuleName -eq „comctl32.dll“ }).Length-gt 0){$P.Name} }

Es funktioniert, auch wenn die Lösung nicht besonders elegant ist. Gibt es vielleicht einen einfacheren Weg? Ich melde mich, wenn ich eine Lösung gefunden habe.

Schreibe einen Kommentar

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s