SharePoint 2010 Management Shell Ausgaben anpassen

Die “SharePoint 2010 Management Shell”, welches im Grunde eine PowerShell-Instanz ist, welche das PSSnapin mit dem Namen Microsoft.SharePoint.PowerShell geladen hat, ist extrem flexibel.

Ich könnte jetzt eine seitenweise Huldigung über die PowerShell schreiben, werde mich aber am Riemen reißen und nur einen der vielen Erweiterungspunkte der PowerShell ansprechen.

Die Erweiterungspunkte welche ich ansprechen möchte sind in der Hilfe von PowerShell dokumentiert.
Die beiden man-pages (wenn man die Linux-kompatible Bezeichnung für die Hilfe verwendet) nennen sich about_Types.ps1xml und about_Format.ps1xml:

man about_Types.ps1xml
man about_Format.ps1xml

Was mit diesen beiden XML-Dateien möglich ist, ist zum Einen das Typsystem der PowerShell zu erweitern (Types.ps1xml) und zum Anderen die Ausgabe auf dem Host zu beeinflussen (Format.ps1xml).

Types.ps1xml

Eines der wohl promintesten Beispiele für eine Erweiterung des Typsystems ist wohl das Count AliasProperty des Array-Objektes. .NET-Programmierer wissen, dass die Länge eines Arrays über das Length-Property ermittelt wird. Andere Collections benutzen dafür aber das Count-Property. Um diese Inkonsistenz zu vermeiden führt die PowerShell das Length AliasProperty ein.

Überall in der PowerShell findet man solche Typerweiterungen. Es gib verschiedenste Möglichkeiten einen Typ zu erweitern, AliasProperty ist die simpelste Möglichkeit und ist einfach ein Verweis auf ein bereits bestehendes Property (im Beispiel des Array.Count ist dies ein Verweis auf Array.Length). Es gibt aber auch komplexere, mit welchen Berechnungen möglich sind, wie z.B. das ScriptProperty. Weitere Informationen bitte about_Types.ps1xml entnehmen.

Format.ps1xml

Diese Datei ermöglicht die Ausgabe der Powershell auf dem Host zu beeinflussen. Ein einfaches Beispiel ist die Ausgabe des Verzeichnissinhaltes mit dir: da es sich im Grunde um .NET-Objekte handelt, welche zurückgegeben werden, muss der PowerShell mitgeteilt werden, wie diese schlussendlich dem Benutzer präsentiert werden sollen, da sonst jede einzelne Eigenschaft in einer Liste ausgegeben wird. Lesbarer (und auch vom DOS-Prompt her gewohnt) ist die Ausgabe mit einer eingeschränkten Anzahl von Eigenschaften und einer tabellarischen Ausgabe. Und genau hierfür sorgt die angesprochene Datei. Weitere Informationen bitte about_Format.ps1xmlentnehmen.

Und was bringt’s mir im Zusammenhang mit SharePoint?

Nun, SharePoint bietet leider eine sehr rudimentäre Implementierung dieser beiden Erweiterungspunkte. Zu finden sind die Formatdateien unter: %PROGRAMFILES%Common FilesMicrosoft SharedWeb Server Extensions14CONFIGPOWERSHELLFormat und die Typedateien unter: %PROGRAMFILES%Common FilesMicrosoft SharedWeb Server Extensions14CONFIGPOWERSHELLTypes.

Wie gesagt, diese Format- und Typdefinitionen sind recht rudimentär. Auf einem Produktivsystem sollten diese Definitionen aber ausreichen. Auf einem Entwicklersystem ist es aber manchmal bequemer, wenn man etwas mehr Informationen aus der PowerShell-Ausgabe erhält, als dies standardmäßig der Fall ist.

Weiter unten habe ich zwei Dateien angehängt, welche nach belieben angepasst werden können. Sie sollen lediglich als Ideengeber dienen.

Geladen werden die Dateien mittels den zwei Kommandos:

Update-TypeData -Prepend SharePoint.types.ps1xml
Update-FormatData -Prepend SharePoint.format.ps1xml

Diese beiden Befehle können im Profil hinterlegt werden, sodass sie beim Aufruf der PowerShell automatisch geladen werden.

Die Reihenfolge sollte wie oben sein (Type, dann Format), da die Ausgabe oftmals auf die definierten Typen verweist.

Falls nachträglich Änderungen an den beiden Dateien durchgeführt wurden, können die Definitionen über Update-TypeData und Update-FormatData neu geladen werden (ohne -Prepend).

Beispielausgabe

Standardausgabe von SharePoint:

Nach dem Laden der neuen Typ- und Ausgabedefinitionen:

Beispieldateien

Die Informationen, welche ausgegeben werden sollen, können für jeden Benutzer/Entwickler unterschiedlich sein, deshalb habe ich jeweils ein Beispiel-XML für die Formate und eines für die Types als Ausgangsdateien erstellt. Diese können dann selbst erweitert und angepasst werden:

SharePoint.format.ps1xml

<Configuration>
  <ViewDefinitions>
    <View>
      <Name>Microsoft.SharePoint.SPWeb</Name>
      <ViewSelectedBy>
        <TypeName>Microsoft.SharePoint.SPWeb</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Width>25</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>20</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>9</Width>
          </TableColumnHeader>
          <TableColumnHeader />
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>Title</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>LastItemModifiedDate</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Language2</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Url</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
    <View>
      <Name>Microsoft.SharePoint.SPList</Name>
      <ViewSelectedBy>
        <TypeName>Microsoft.SharePoint.SPList</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader />
          <TableColumnHeader>
            <Width>20</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>10</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>9</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>36</Width>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>Title</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>LastItemModifiedDate</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>FieldCount</PropertyName>
                <Alignment>Right</Alignment>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>ItemCount</PropertyName>
                <Alignment>Right</Alignment>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>ID</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
    <View>
      <Name>Microsoft.SharePoint.SPListItem</Name>
      <ViewSelectedBy>
        <TypeName>Microsoft.SharePoint.SPListItem</TypeName>
      </ViewSelectedBy>
      <TableControl>
        <TableHeaders>
          <TableColumnHeader>
            <Width>8</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>19</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>20</Width>
            <Label>ContentType</Label>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>7</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>20</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>19</Width>
          </TableColumnHeader>
          <TableColumnHeader>
            <Width>19</Width>
          </TableColumnHeader>
        </TableHeaders>
        <TableRowEntries>
          <TableRowEntry>
            <TableColumnItems>
              <TableColumnItem>
                <PropertyName>ID</PropertyName>
                <Alignment>Right</Alignment>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Title</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <ScriptBlock>$_.ContentType.Name</ScriptBlock>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Version</PropertyName>
                <Alignment>Right</Alignment>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Author</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Created</PropertyName>
              </TableColumnItem>
              <TableColumnItem>
                <PropertyName>Modified</PropertyName>
              </TableColumnItem>
            </TableColumnItems>
          </TableRowEntry>
        </TableRowEntries>
      </TableControl>
    </View>
  </ViewDefinitions>
</Configuration>

SharePoint.types.ps1xml

<Types>
  <Type>
    <Name>Microsoft.SharePoint.SPWeb</Name>
    <Members>
      <AliasProperty>
        <Name>LCID</Name>
        <ReferencedMemberName>Language</ReferencedMemberName>
        <TypeName>System.Int32</TypeName>
      </AliasProperty>
      <ScriptProperty>
        <Name>Language2</Name>
        <GetScriptBlock>
          [System.Globalization.CultureInfo]::GetCultureInfo($this.LCID).Name
        </GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
  <Type>
    <Name>Microsoft.SharePoint.SPList</Name>
    <Members>
      <AliasProperty>
        <Name>Url</Name>
        <ReferencedMemberName>DefaultViewUrl</ReferencedMemberName>
        <TypeName>System.Uri</TypeName>
      </AliasProperty>
      <ScriptProperty>
        <Name>FieldCount</Name>
        <GetScriptBlock>
          $this.Fields.Count
        </GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
  <Type>
    <Name>Microsoft.SharePoint.SPListItem</Name>
    <Members>
      <ScriptProperty>
        <Name>Url</Name>
        <GetScriptBlock>
          $this["ServerUrl"]
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>Author</Name>
        <GetScriptBlock>
          $this.Fields.GetFieldByInternalName("Author").GetFieldValueAsText($this["Author"])
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>Created</Name>
        <GetScriptBlock>
          [DateTime]$this["Created"]
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>Modified</Name>
        <GetScriptBlock>
          [DateTime]$this["Modified"]
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>Version</Name>
        <GetScriptBlock>
          if ($this.Versions -and $this.Versions.Count -gt 0) {
          $this.Versions[0].VersionLabel
          }
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>FieldCount</Name>
        <GetScriptBlock>
          $this.Fields.Count
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>WorkflowCount</Name>
        <GetScriptBlock>
          if ($this.Workflows) { $this.Workflows.Count } else { 0 }
        </GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>RunningWorkflowCount</Name>
        <GetScriptBlock>
          if ($this.Workflows -and $this.Workflows.Count -gt 0) {
          @($this.Workflows | ? { !$_.IsCompleted }).Count
          } else { 0 }
        </GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
</Types>
Tagged , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: