Herausforderung: Wie liest man eigentlich mit PowerShell Eigenschaften einer Assembly (DLL) aus dem Global-Assembly-Cache (GAC) aus?
Hintergrundwissen: Schaut man sich die im GAC befindlichen Assemblies mittels Windows-Explorer an, so wird man schnell zu der Überzeugung gelangen, dass dies ein besonderer Dateiordner ist. Die Ansicht wird mittels dem “Assembly Cache Viewer” dargestellt, wodurch die physische Verzeichnisstruktur verborgen wird. So liegt bspw. die Assembly “Microsoft.SharePoint.dll” im Verzeichnis
C:\Windows\assembly\GAC_MSIL\Microsoft.SharePoint\14.0.0.0__71e9bce111e9429c\Microsoft.SharePoint.dll
Diesen Dateipfad kann man nun aber nicht einfach in die Adressleiste des Windows-Explorer kopieren (der “Assembly Cache Viewer” zeigt dann wieder die Standard-Sicht an). Nutzt man aber Shell-basierte Skriptsprachen wie PowerShell, dann lässt sich schon einiges mit einer Assembly machen.
Wie kopiert man Dateien aus dem GAC heraus? Mit Hilfe des physischen Pfades können die Assemblies des GAC herauskopiert werden. Bspw. wird die Assembly Microsoft.SharePoint.dll wie folgt aus dem GAC kopiert.
Get-ChildItem “C:\Windows\Assembly” -Recurse -Filter “Microsoft.SharePoint.dll” | foreach { copy $_.FullName C:\_tmp\gac }
Wie liest man Eigenschaften einer Assembly aus? Hierzu nutzt man am besten System.Reflection. Mit Hilfe von 4 Kern-Eigenschaften einer Assembly lassen sich alle weiteren Eigenschaften auslesen.
[String]$assInfo = [String]::Format(“{0},Version={1},Culture={2},PublicKeyToken={3}”, $AssemblyNameWithoutExtension, $AssemblyVersion, $AssemblyCulture, $AssemblyPublicKeyToken);
[System.Reflection.Assembly]$ass = [System.Reflection.Assembly]::Load($assInfo);
Der Kommentar lässt sich bspw. wie folgt auslesen:
[System.Diagnostics.FileVersionInfo]::GetVersionInfo($ass.Location).Comments
Die Information der physischen Dateiablage ist hier gespeichert:
$ass.Location
Weitere Attribute lassen sich über spezielle Assembly-Attribut-Klassen auslesen. Bspw. das Copyright-Attribut:
[System.Reflection.AssemblyCopyrightAttribute]$attrCopyright = $ass.GetCustomAttributes([System.Type]::GetType(“System.Reflection.AssemblyCopyrightAttribute”), $false)[0];
$attrCopyright.Copyright
In einem Beispiel-Skript sieht das dann bspw. so aus.
Mehrwert: Mittels eines PowerShell-Skriptes lassen sich alle Eigenschaften von Assemblies auslesen. Damit eignet sich PowerShell, um den Zustand des GACs zu kontrollieren. Bspw. könnte man regelmäßig prüfen, welche Assemblies im GAC vorhanden sind (aktuell installierte Version einer eigenen Lösung checken) und ggf. automatisiert Maßnahmen ergreifen (Email senden).
Da PowerShell selbst in .NET geschrieben wurde kann man mit der PowerShell nichts machen was nicht auch mit .NET (C# usw.) gehen würde.
Für mich kiegt der mehrwert in solchen fäallen immer in der interaktivität.
So spart man sich die .NET Entwicklungsumgebung (IDE) und das Kompilieren.
Hallo Peter Kriegel,
es ist korrekt, dass das im Beitrag gezeigte PowerShell-Skripting ziemlich .Net-lastig ist. Und der von Dir/Ihnen genannte Mehrwert ist natürlich generell nicht von der Hand zu weisen. Danke für die Hinweise.
Axel
Info: Ab .Net 4.5 kann man die vielen typisierten Assembly-Attribute aus .Net 2.0-Zeiten (AssemblyCopyrightAttribute, AssemblyCompanyAttribute,…) durch das generische Assembly-Attribute AssemblyMetadataAttribute ersetzen. Für SharePoint-Umgebungen heißt dies jedoch, dass man auf SharePoint 2013 warten muss, da SharePoint 2010 noch mit .Net 3.5 SP1 arbeitet.