Behandelte Themen

0.  Formatieren mit .NET

1.  Schnelleinstieg in die Formatierung   
     Beispiel 1a: {0} ist {1:D}
     Beispiel 1b: ToString('D')
     Beispiel 2: {0,-10:#.###}
     Beispiel 3: {0,10:00.000}
     Beispiel 4: {0:#.00#}
     1.1 Datum und Uhrzeit
          1.1.1 Standardformatierung von Datum und Uhrzeit
                  Beispiel 1: StandardFormatierung des heutigen Datums mit ToString und Formatoperator
          1.1.2 Individuelle Formatierung von Datum und Uhrzeit
                  Beispiel 1: Individuelle Formatierung des heutigen Datums
          1.1.3 Länderspezifische Formatierung von Datum und Uhrzeit (CultureObject)
     1.2 Zahlen
          1.2.1 Standardformatierung von Zahlen
                  Beispiel 1: Unterschied zwischen "en-US" und "de-DE"
          1.2.2 Individuelle Formatierung von Zahlen
                   Beispiel 1: Zahlen mit Formatbezeichnern und dem Cultureinfo-Objekt formatieren
          1.2.3 Mathematisches Runden und andere mathematische Funktionen
                   Beispiel 1: Anzeige der mathematischen Funktionen
                   Beispiel 2: Anwenden der Klasse [math] - mathematisches Runden einer Zahl - Potenzieren 

2.  Ausgabe filtern
     2.1 Select-Object
          Beispiel 1: Anzeige aller aktiven Netzwerkadapter mit SettingID und IPAdresse
          Beispiel 2: die drei ältesten Dateien eines Ordners anzeigen

3. Formatierte Tabellen
    3.1 Selbstdefinierte Spalten zu format-table/ select-object hinzufügen
         Beispiel 1: "Format-Table" um eine selbstdefinierte Spalten ergänzen
         Beispiel 2: "Format-Table" mit mehreren selbstdefinierten Spalten ergänzen
    3.2 Tabellen aus formatierten Strings erstellen
         Beispiel 1a: Eine Tabelle aus  .Net formatierten Strings erstellen
         Beispiel 1b: Eine Tabelle mit Spalten aus zwei verschiedenen Quellen erstellen
    3.3 Tabellen mit "Out-GridView"

4. Die Console anpassen
    Beispiel 1: Welche Farben bieten Powershell und .Net an
    Beispiel 2: Zeilen farblich hervorheben
    Beispiel 3: die ganze Konsole verändern
    Beispiel 4: Farben zurücksetzen

******************************************************************************************************

0 Formatieren mit .NET

Die Powershell bietet mit der Methode ToString unter .Net und mit dem FormatOperator -f zwei Formatierungsmöglichkeiten an. Beide Methoden nutzen dieselben Parameter.
Informationen können entweder nach von .Net definierten Formaten oder mit individuellen Formaten ausgegeben werden. Wichtig zu verstehen ist, dass eine Formatierung die Informationen selbst nicht verändert, sondern quasi nur den Blickwinkel darauf.
Anders wirken sich mathematische Funktionen wie das "Runden auf eine bestimmte Stellenanzahl" auf die Variablen aus. Hier werden Nachkommastellen nach bestimmten Vorgaben tatsächlich abgeschnitten und Informationen gehen verloren. In Kapitel 1.2.3  Mathematisches Runden und andere mathematische Funktionen gehe ich darauf ein.

1 Schnelleinstieg in die Formatierung

Kryptische Formatierungsanweisungen der Art "{0,-10:##.###}" -f $var1,$var2" begegnen einem in der Powershell relativ häufig. Um möglichst rasch einen Einstieg zu ermöglichen, zeige ich in diesem Kapitel 5 einfache, prinzipielle Beispiele.
Wenn man die Schreibweise dieser Beispiele verstanden hat, ist es nicht mehr schwierig anhand der nachfolgenden Kapitel oder anhand der MSDN-Tabellen die Bedeutung der verschiedenen Kürzel nachzuschlagen.


Beispiel 1a: {0} ist {1:D} - Datum und Uhrzeit

"{0} ist {1:D}" -f "Heute",(get-date)

#Ausgabe

Heute ist Donnerstag, 27. Januar 2011

{0} und {1} sind die Platzhalter für die Variablen, die nach dem Formatierungsoperator -f aufgelistet sind. {0} steht für den String "Heute" und {1} für das Ergebnis von (get-date). Man könnte auch zuerst die {1} angeben, oder die {1} mehrfach im String benützen.

Das "D" in {1:D} formatiert {get-date} zu einem "Long Pattern Date", siehe Kapitel 1.1

 
Beispiel 1b: ToString('D')
- Datum und Uhrzeit

Dasselbe Beispiel aus 1a) mit der ToString-Methode umgesetzt

$a=get-date
"Heute ist $($a.tostring('D'))"
"Heute ist $((get-date).tostring('D'))"

#Ausgabe

Heute ist Freitag, 28. Januar 2011
Heute ist Freitag, 28. Januar 2011


Beispiel 2: {0,-10:#.###} - Zahlen

$a="die Zahl PI auf drei NachkommaStellen mit dem `"Digit placeholder formatiert lautet"
"{0}: {1,-10:#.###}" -f  $a,([Math]::Pi)

#Ausgabe

die Zahl PI auf drei NachkommaStellen mit dem "Digit placeholder" gerundet lautet: 3,142

Die "{0}" ist der Plathalter der Variable a

Das ": " ist derString zwischen den Platzhaltern

Die "1" in "{1,-10:#.###}" ist der Platzhalter für ([Math]::Pi).

Die "-10" in "{1,-10:#.###}" definiert die Breite des Feldes an. Das Minus bedeutet linksbündig.  Ein Wert für die Breite ist optional.

#.### in "{0,-10:#.###}" formatiert die Zahl mit maximal zwei Vorkomma und rundet auf drei Nachkommastellen. Führende Nullen oder Nullen am Ende werden nicht angegeben.


Beispiel 3: {0,10:00.000} - Zahlen

"die Zahl PI auf drei NachlkommaStellen mit dem `"Zero placeholder`" formatiert lautet {0,10:00.000}" -f  ([Math]::Pi)

#Ausgabe

die Zahl PI auf drei NachlkommaStellen mit dem "Zero placeholder" formatiert lautet     03,142

Text kann natürlich auch zwischen die Anführungszeichen vor, hinter und zwischen die Platzhalter gesetzt werden.

Die "0" in "{0,10:00.000}" ist der Platzhalter für ([Math]::Pi).

Die "10" in "{0,10:00.000}" definiert die Breite des Feldes an. Das fehlende Minus (=Plus) bedeutet rechtsbündig. Ein Wert für die Breite ist optional.

"00.000" in "{0,10:00.000}" formatiert die Zahl mit genaul zwei Vorkomma und rundet auf drei Nachkommastellen. Führende Nullen oder Nullen am Ende werden aber auf jeden Fall angezeigt.

 
Beispiel 4
: {0:#.00#} - Zahlen

"#" und "0" kann man natürlich auch Mischen, 

"{0:#.00#}" -f 32.4004

#Ausgabe

32,40

Mit {0:#.00#} werden auf jeden Fall mindestens zwei Nachkommastellen angezeigt, aber nicht mehr als drei.

Welche Formatierungsvarianten, besonders nach dem Positionsparameter und der Feldbreite, es noch gibt, stelle ich in den nächsten Kapiteln dar.


Beispiel 4
: {0:n2} - Zahlen

"{0:n2}" -f 32,4084

#Ausgabe

32,41

die einfachste Möglichkeit zum Schluss:
Mit der Formatierung "n2" wird die Zahl 32,4084 auf zwei Stellen gerundet. Hat man außer der Anzahl der angezeigten Nachkommastellen keine weiteren Anforderungen an die Formatierung, so ist dies eine einfache Möglichkeit.

 

1.1 Datum und Uhrzeit

In der .Net Datums- und Uhrzeit Formatierung kann man sich entweder aus einem gut sortierten Angebot an Standardformaten eine passendes aussuchen (siehe Kapitel 1.1.1), oder man formatiert seinen String frei nach eigenen Wünschen (siehe Kapitel 1.1.2).

1.1.1 StandardFormatierung von Datum und Uhrzeit

Beispiel 1: StandardFormatierung des heutigen Datums mit ToString und Formatoperator

$a = get-date

$text="`nFormatierung nach ISO-Norm 8601 mit dem Formatspecifier`"s`" "
write-host -BackgroundColor darkyellow -foregroundcolor darkred $text
$a.ToString("s")
"{0:s}" -f $a  

$text="`nFormatierung im Langen Datumsformat mit dem Formatspecifier `"D`" "
write-host -BackgroundColor darkyellow -foregroundcolor darkred $text
$a.ToString("D")
"{0:D}" -f $a  

#Ausgabe

Formatierung nach ISO-Norm 8601 mit dem Formatspecifier"s"
2011-09-17T22:47:32
2011-09-17T22:47:32

Formatierung im Langen Datumsformat mit dem Formatspecifier "D"
Samstag, 17. September 2011
Samstag, 17. September 2011

Die Schreibweise {0:s} habe ich prinzipiell im Kapitel "1 Schnelleinstieg in die "Formatierung" weiter oben beschrieben. Die Bedeutung der Formatspecifier "s" oder "D" in "{0:s}" oder "{0:D}" erfahrt ihr in den nächsten Zeilen.
Hier leider nicht zu sehen, aber die Textzeilen werden durch das cmdlet write-host farbig formatiert.


Weitere Beispiele:
 MSDN: Standard DateTime Format Strings Output Examples


Die Standard Formatbezeichner für Datum und Zeit finden sich unter
 MSDN: Standard DateTime Format Strings

einige Beispiele an Formatbezeichnern haben ich hier kopiert, der Rest liegt auf der eben genannten MSDN-Seite

Format specifier

Name  

Description


d

Short date pattern

Displays a pattern defined by the  DateTimeFormatInfo.ShortDatePattern property associated with the current thread or by a specified format provider.


D

Long date pattern

Displays a pattern defined by the  DateTimeFormatInfo.LongDatePattern property associated with the current thread or by a specified format provider.


t

Short time pattern

Displays a pattern defined by the  DateTimeFormatInfo.ShortTimePattern property associated with the current thread or by a specified format provider.


 

 

1.1.2 Individuelle Formatierung von Datum und Uhrzeit

Beispiel 1: Individuelle Formatierung des heutigen Datums mit Standardpatterns

#Skript

$a = get-date

#mit der Methode ToString
$a.ToString("dddd, \der dd-\te MMMM") #bestimmte Buchstaben müssen mit '\' maskiert werden

#mit dem Formatoperator -f
"{0:dddd}, der {0:dd}-te {0:MMMM}" -f $a #identische Formatierung

#mit dem Parameter -Format
get-date -Format("dddd, \der dd-\te MMMM") 

#Ausgabe

Samstag, der 20-te Februar
Samstag, der 20-te Februar
Samstag, der 20-te Februar

Die Bedeutung von "dddd", "dd" und "MMMM" habe ich weiter unten in einer Tabelle beschrieben. Alle Formatspecifier findet man in der MSDN

 Weitere Beispiele: MSDN: Custom DateTime Format Strings Output Examples

Wenn die Standardformate nicht das gewünschte Format mitbringen, kann man mit der individuellen Formatierung jedwede Ausgabe erzeugen. Die möglichen Formatbezeichner findet man unter MSDN:  DateTimeFormatInfo Class

einige Formatbezeichner habe ich hierher kopiert, der Rest liegt auf der eben genannten MSDN-Seite.

Format specifier

Description

dd

Displays the current day of the month, measured as a number between 1 and 31, inclusive. If the day is a single digit only (1-9), it is formatted with a preceding 0 (01-09).

dddd (plus any number of additional "d" characters)

Displays the full name of the day for the specified DateTime. If a specific valid format provider (a non-null object that implements IFormatProvider with the expected property) is not supplied, then the  DayNames property of the DateTimeFormat and its current culture associated with the current thread is used. Otherwise, the DayNames property from the specified format provider is used.

MMMM

Displays the full name of the month for the specified DateTime. If a specific valid format provider (a non-null object that implements IFormatProvider with the expected property) is not supplied, then the  MonthNames property of the DateTimeFormat and its current culture associated with the current thread is used. Otherwise, the MonthNames property from the specified format provider is used.

 

Beispiel 2: Kobination von Custompattern und Standardpattern

([datetime]::now).ToString("d")   # returns the DateTime  value; "d" is the standard short date pattern.
([datetime]::now).ToString("%d")  # returns the day of the month; "%d" is a custom pattern.
([datetime]::now).ToString("d ")  # returns the day of the month followed by a white-space character; "d " is a custom pattern.

#Ausgabe

08.08.2011
8
8

("d") hat also eine andere Bedeutung als ("%d")

1.1.3 Länderspezifische Formatierung mit dem CultureInfo-Object

Möchte man die Datumsausgabe oder auch Uhrzeiten nicht mit den Regionseinstellungen seines Systems formatieren, so steht die CultureInfo-Klasse zur Verfügung

#Skript
$culture = New-Object System.Globalization.CultureInfo("en-US")
$a = get-date
 
$a.ToString("dddd, dd-\t\h o\f MMMM",$culture)
$a.ToString("D",$culture)

#Ausgabe auf einem Deutschen Windows 7
Saturday, 20-th of February
Saturday, February 20, 2010

Die Verwendung der Klasse CultureInfo mit dem -f Operator habe ich nicht hinbekommen und auch in der Klassenbeschreibung nicht gefunden.

weitere Erklärungen findet man unter
 Technet Windows PowerShell Tip of the Week:  Formatting Numbers and Dates Using the CultureInfo Object

eine Auflistung aller Culturen findet man unter  MSDN: CultureInfo Class

 

1.2 Formatierung von Zahlen

Auch bei der Formatierung von Zahlen gibt es -wie bei Datum und Uhrzeit- die Möglichkeiten der Standardformatierung und der individuellen Formatierung

1.2.1 Standardformatierung von Zahlen

Beispiel 1: Unterschied zwischen "en-US" und "de-DE"

$cultureUS = New-Object System.Globalization.CultureInfo("en-US")
$cultureDE = New-Object System.Globalization.CultureInfo("de-DE")
$value=123.456
"`n"

'"C",$cultureDE:  ' + $Value.ToString("C",$cultureDE)
'"C",$cultureUS:  ' + $Value.ToString("C",$cultureUS)
'"E2"          :  '  +$Value.ToString("E2")

#Ausgabe

"C",$cultureDE:  123,46 €
"C",$cultureUS:  $123.46
"E2"          :  1,23E+002

weitere Beispiele: MSDN: Standard Numeric Format Strings Output Examples

Einige Formatbezeichner habe ich unten kopiert. Die vollständige Liste der Standardformatbezeichner für Zahlen findet man unter
 MSDN: Standard Numeric Format Strings

Format specifier

Name               

Description

C or c

Currency

The number is converted to a string that represents a currency amount. The conversion is controlled by the currency format information of the NumberFormatInfo object used to format the number. The precision specifier indicates the desired number of decimal places. If the precision specifier is omitted, the default currency precision given by the NumberFormatInfo is used.

D or d

Decimal

This format is supported for integral types only. The number is converted to a string of decimal digits (0-9), prefixed by a minus sign if the number is negative. The precision specifier indicates the minimum number of digits desired in the resulting string. If required, the number is padded with zeros to its left to produce the number of digits given by the precision specifier.

E or e

Scientific (exponential)

The number is converted to a string of the form "-d.ddd...E+ddd" or "-d.ddd...e+ddd", where each 'd' indicates a digit (0-9). The string starts with a minus sign if the number is negative. One digit always precedes the decimal point. The precision specifier indicates the desired number of digits after the decimal point. If the precision specifier is omitted, a default of six digits after the decimal point is used. The case of the format specifier indicates whether to prefix the exponent with an 'E' or an 'e'. The exponent always consists of a plus or minus sign and a minimum of three digits. The exponent is padded with zeros to meet this minimum, if required.



1.2.2 Individuelle Formatierung von Zahlen

Beispiel 1: Zahlen mit Formatbezeichnern und dem Cultureinfo-Objekt formatieren

#Skript

$cultureUS = New-Object System.Globalization.CultureInfo("en-US")
$cultureDE = New-Object System.Globalization.CultureInfo("de-DE")
$value=123.456
"`n"

$Value.ToString("#.#")  #der Unterschied zwischen # und 0 ist in der nachfolgenden Tabelle beschrieben
$Value.ToString("0.0",$cultureDE) # Der CultureInfo-Parameter ist optional
$Value.ToString("0000.0000",$cultureUS)

#Ausgabe

123,5
123,5
0123.4560 # Man beachte den Punkt als Trennzeichen wg. des CultureInfoParameters

weitere Beispiele:  MSDN: Custom Numeric Format Strings Output Examples

Einige Formatbezeichner habe ich unten kopiert. Die vollständige Liste der individuellen Formatcharacter für Zahlen findet man unter:
 MSDN: Custom Numeric Format Strings

Format character

Name

Description

0

Zero placeholder

If the value being formatted has a digit in the position where the '0' appears in the format string, then that digit is copied to the result string. ....

#

Digit placeholder

If the value being formatted has a digit in the position where the '#' appears in the format string, then that digit is copied to the result string. ...

.

Decimal point

The first '.' character in the format string determines the location of the decimal separator in the formatted value; any additional '.' characters are ignored. ...

 

 

1.2.3 Mathematisches Runden und andere mathematische Funktionen

Diese Unterkapitel passt zugegeben nicht ganz unter "Formatierung des Outputs", andererseits will man oft nicht nur Zahlen optisch runden (=formatieren) sondern tatsächlich mathematisch runden (=Stellen abschneiden)

Powershell selbst besitzt keine cmdlets für diese Aufgabe, dafür bietet .Net eine einfache Klasse [system.math] mit den passenden statischen Methoden an.

MSDN:  System.Math

Beispiel 1: Anzeige der mathematischen Methoden und Eigenschaften

[math] | get-member -static

#Ausgabe - Manche Definitions habe ich wegen besserer Lesbarkeit abgekürzt

   TypeName: System.Math

Name            MemberType Definition             
----            ---------- ----------             
Abs             Method     static System.SByte Abs(System.SByte value), static System.Int16 
Abs(System.Int16 value), static int Abs(int value), static long Abs(long value), static float Abs(fl
Acos            Method     static double Acos(double d)           
Asin            Method     static double Asin(double d)           
Atan            Method     static double Atan(double d)           
Atan2           Method     static double Atan2(double y, double x)
BigMul          Method     static long BigMul(int a, int b)       
Ceiling         Method     static decimal Ceiling(decimal d), static double Ceiling(double a)     
Cos             Method     static double Cos(double d)            
Cosh            Method     static double Cosh(double value)       
DivRem          Method     static int DivRem(int a, int b, 
Equals          Method     static bool Equals(System.Object objA, System.Object objB)             
Exp             Method     static double Exp(double d)            
Floor           Method     static decimal Floor(decimal d), static double Floor(double d)         
IEEERemainder   Method     static double IEEERemainder(double x, double y)        
Log             Method     static double Log(double d), static double Log(double a, double newBase)               
Log10           Method     static double Log10(double d)          
Max             Method     static System.SByte Max(System.SByte val1, System.SB val2), 
Min             Method     static System.SByte Min(System.SByte val1, System.SByte val2), static 
Pow             Method     static double Pow(double x, double y)  
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)    
Round           Method     static double Round(double a), 
Sign            Method     static int Sign(System.SByte value), static int Sign(System.Int16 value), 
Sin             Method     static double Sin(double a)            
Sinh            Method     static double Sinh(double value)       
Sqrt            Method     static double Sqrt(double d)           
Tan             Method     static double Tan(double a)            
Tanh            Method     static double Tanh(double value)       
Truncate        Method     static decimal Truncate(decimal d), static double Truncate(double d)   
E               Property   static System.Double E {get;}          
PI              Property   static System.Double PI {get;}   

Hier ist alles an mathematischen Funktionen dabei, was ein normaler Taschenrechner auch hergibt. 

Alle Methoden sind statisch und arbeiten ohne Instanzen der Klasse. Für statische Methoden muss man die Schreibweise "[Klasse]::Methode(Parameter)" benützen. Eine Instanzierung mit dem cmdlet New-Object schlägt fehl.
Technet:  about_operators -> ::-Operator für statische Elemente

Unterschiede zwischen Instanzklassen und statischen Klassen habe ich anhand der Stringklasse hier etwas genauer beschrieben.


Beispiel 2: Anwenden der Klasse [math] - mathematisches Runden einer Zahl - Potenzieren

Radius = 4
$Area = [math]::pi * [math]::pow($Radius,2)
"Die Fläche eines Kreise mit Radius 4 beträgt ungerundet: $Area" 

$Area_rounded= [math]::round($Area,2)
"Die Fläche eines Kreise mit Radius 4 beträgt auf zwei Stellen gerundet: $Area_rounded" 

#Ausgabe

Die Fläche eines Kreise mit Radius 4 beträgt ungerundet: 50.2654824574367
Die Fläche eines Kreise mit Radius 4 beträgt auf zwei Stellen gerundet: 50.27

 

2 Ausgabe filtern

Die Ausgabe eines Skriptes lässt sich in Powershell auf vielfältige Art kontrollieren, filtern und formatieren.

 

2.1 Ausgabe einschränken

Mit dem cmdlet "Select-Object" lassen sich einfach Ausgaben sowohl in der Anzahl der Spalten (Beispiel 1), als auch in der Anzahl der Zeilen (Beispiel 2) einschränken.

 Technet: Select-Object


Beispiel 1a: Anzeige aller aktiven Netzwerkadapter mit SettingID und IPAdresse (select-object)

#Skript
$qry= "select IPAddress,SettingID from win32_networkadapterconfiguration where IPenabled='true'"
 
gwmi  -query $qry | Select-Object SettingID,Ipaddress | format-table
# das | format-table kann weggelassen werden

#Ausgabe
SettingID                                                   IPaddress
---------                                                   ---------
{746C4685-11EC-4AC3-ABA1-70FC4AB496C0}                      {0.0.0.0}
{4DCA670C-1E42-4524-9B88-88A0A13E7E82}                      {0.0.0.0}
{459EFFE8-F4E2-467F-B9F4-44247EC581E7}                      {192.168.235.1}
{4B1C2490-68AB-4378-A658-3DB95E2EA604}                      {192.168.18.1}  

$qry ist ein in WQL (=WMI Query Language) geschriebenes Statement, das über die WMI-Klasse win32_networkadapterconfiguration die Eigenschaften  IPAddress und SettingID von den Netzwerkkarten ausliest, deren Eigenschaft IPenabled='true' ist.

Man kann die ausgegebenen Eigenschaften mit select-object einschränken. Vielmehr Einfluß auf die Ausgabe wie den Spaltenabstand kann man leider nicht mehr nehmen. Mehr Möglichkeiten ohne größeren Mehraufwand auf das Ausgabeformat hat man, wenn man jedes Element des Arrays über eine foreach-Schleife ausgibt. Im folgenden Beispiel ost das gezeigt.


Beispiel 1b: Anzeige aller aktiven Netzwerkadapter mit SettingID und IPAdresse (foreach-object)

$qry= "select IPAddress,SettingID from win32_networkadapterconfiguration where IPenabled='true'"
gwmi  -query $qry | foreach{
  "{0}  {1}  {2}" -f $($_.SettingID),$($_.Ipaddress[0]),$($_.Ipaddress[1])}

#Ausgabe

{A358329B-91EA-4E55-8956-098AAF118EF7}  192.168.178.22  fe80::810c:77bd:b204:937a

noch mehr Einflussmöglichkeiten auf den Output zeige ich im gleich folgendenden Kapitel 3


Beispiel 2: die drei ältesten Dateien eines Ordners anzeigen

$folder="c:\test"
Get-ChildItem $folder | Sort-Object lastwritetime -descending | `
        Select-Object -last 3

#Ausgabe
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\windows

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        18.02.2007     13:00      26680 River Sumida.bmp
-a---        18.02.2007     13:00      17362 Rhododendron.bmp
-a---        18.02.2007     13:00     224768 regedit.exe


Für einfache, einmalige Übrsichten ist die Ausgabe so sicher schon ausreichend. Mehr Möglichkeiten Tabellen zu formatieren, zeige ich im nächsten Kapitel 3.

 

3 Ausgabe in Tabellenform

 

3.1 Selbstdefinierte Spalten zu format-table/ select-object hinzufügen

Den Output vieler cmdlets kann man sehr einfach filtern und verschieden darstellen, in dem man die Ausgabe an cmdlets wie format-table, format-list, sort-object, group-object oder select-object weiterpiped.
Wenn aber die durch diese cmdlets erstellten Tabellen etwas individueller formatiert oder berechnete Werte als Spalten hinzugefügt werden sollen, muss man sich etwas genauer mit diesen cmdlets beschäftigen.

Beispiel 1: "Format-Table" um eine selbstdefinierte Spalten ergänzen

siehe auch  Technet: Format-Table Beispiele 5 und 6

get-process notepad | format-table ProcessName,
@{
Label="TotalRunningTime"
Expression={(get-date) - $_.StartTime}},
StartTime -autosize

#Ausgabe

ProcessName TotalRunningTime StartTime         
----------- ---------------- ---------         
notepad     00:55:13.3478457 26.01.2011 21:28:26
notepad     00:55:09.3634707 26.01.2011 21:28:30
notepad     00:07:18.9146166 26.01.2011 22:16:20

Die erste Spalte "Processname" und dritte Spalte  "Starttime", sowie die Option "-autosize" sind nichts Außergewöhnliches.
Interessant ist hingegen die zweite Spalte "TotalRunningTime", da "get-process" eine solche Eigenschaft nicht anbietet.
Hilfe bringt hier eine Hashtabelle @{}, die in diesem Beispiel die Schlüssel "Expression" mit dem Scriptblock {(get-date) - $_.StartTime}} und den Schlüssel "Label" mit dem String "TotalRunningTime" enthält. 

Richtig schön sieht die Ausgabe oben weder mit der Option "-autosize", noch ohne diese aus. In der Hashtabelle für Format-Table gibt es daher noch die Schlüssel "width", "alignment" oder "align" und "formatstring", um die Ausgabe optisch weiter zu optimieren

Beispiel 2: "Format-Table" mit mehreren selbstdefinierten Spalten ergänzen

gwmi win32_logicaldisk | format-table `
    @{Label="ID";
      Expression={"{0}" -f ($_.DeviceID)}
      width=3;
      Align="Right";
     },

    @{Label=$(" "*2) +  "Free in MB";
      Expression={"{0:0.0}" -f ($_.Freespace/1MB)};
      width=13;
      Align="Right";
     },

     @{Label=$(" "*2) +  "Size in MB";
      Formatstring="{0:0.00}"
      Expression= {$_.Size/1MB}
      width=13;
      Align="Right";
     }

#Ausgabe

ID    Free in MB    Size in MB
 --  ------------  ------------
 C:       80950,3     152624,85
 E:           0,0       2414,53
 I:       48186,0      51191,46
 K:      614301,7     614392,09
 S:       78860,5    1638400,00

Man ist wahlfrei, ob man, wie in der zweiten Spalte "Free in MB" den Formatoperator -f oder den Formatstring wie in der dritten Spalte Size in MB" benützt. Siehe Kapitel 1

- Der Schlüssel "width" gibt die Feldbreite an, die eine Spalte belegt.
- Der Schüssel "align" oder "alignment" legt die Ausrichtung fest ("left","right","center")

Damit lassen sich jetzt schon ansehlich formatierte Tabellen erstellen

Je nach verwendetem cmdlet stehen verschiedene Schlüssel für die Hashtabellen zur Verfügung:  thepowershellguy.com - New-CustomColumn function

 

3.2 Tabellen aus formatierten Strings erstellen

Beispiel 1a: eine Tabelle aus  .Net formatierten Strings erstellen

$drives=[system.io.driveinfo]::getdrives()

$computername=get-content env:computername
$width_0=3
$width_1=15
$width_2=20
$width_3=13
$width_4=6+$computername.length
$headline= "{0,$width_0}   {1,$($width_1):0.00}    {2,$($width_2):0.00} {3,$($width_3):0.0%} {4,$width_4}" -f `
      "Drive","Totalsize in GB","Totalfreespace in GB","Percentfree","Computername"

write-host -BackgroundColor darkyellow -foregroundcolor darkred "$headline`n"
    
$drives | foreach {
  if ($_.totalsize -gt 0){  #damit unverbundene LW nicht angezeigt werden
     $Drivename=$_.name
     $Totalsize=$($_.totalsize)/1GB
     $TotalFreeSpace=$($_.totalfreespace)/1GB
     $PercentFree=$($_.totalfreespace)/$($_.totalsize)
     
         "{0,$width_0} {1,$($width_1):0.00} {2,$($width_2):0.00}    {3,$($width_3):0.0%}   {4,$width_4}" -f `
              $Drivename,$totalsize,$TotalFreeSpace,$PercentFree,$computername
  }else{
     $Drivename=$_.name
     $computername=get-content env:computername
      "{0} {1,55}" -f $Drivename,$computername
  }

#Ausgabe

Drive   Totalsize in GB    Totalfreespace in GB   Percentfree     Computername

C:\          149,05                79,20            53,1%         DOM2DC01
E:\            2,36                 0,00             0,0%         DOM2DC01
I:\           49,99                47,06            94,1%         DOM2DC01
U:\         1560,00                45,58             2,9%         DOM2DC01


Beispiel 1b: Eine Tabelle mit Spalten aus zwei verschiedenen Quellen erstellen

Das cmdlet "Get-Process" zeigt nicht den Besitzer eines Prozesses an. Diesen kann man über die wmi-Klasse "Get-Process" erfragen. Das Beispiel zeigt, wie mit Hilfe einer Hashtablle die Informationen aus beiden Quellen in einer Tabelle darstellen kann.

$Benutzer = @{}
gwmi win32_process |foreach {$Benutzer[$_.handle] = $_.getowner().user}

$headline=  "{0,-15} {1,5} {2,15}" -f "Processname","ID","Benutzer"
write-host -BackgroundColor darkyellow -foregroundcolor darkred "$headline`n"

get-process m* | foreach {
  $processname=$_.processname
  $id=$_.id
  "{0,-15} {1,5} {2,15}" -f $processname,$id,$Benutzer[$_.id.tostring()]
  }

#Ausgabe

Processname        ID        Benutzer  #die Farbe lässt sich leider hier nicht darstellen

Mcshield          588          SYSTEM
McTray           4508         j184710
MDM              1300          SYSTEM
MobileChecker    2096          SYSTEM
mstsc            4780         j184710


3.3 Tabellen mit "Out-GridView"

Liefern cmdlets grössere Tabellen zurück, kann auch das cmdllet "out-gridview" eine interessante Möglichkeit sein, Daten einfach und trotzdem ansprechend darszustellen.

Beispiel 1: Inhalte eines Verzeichnisse

(get-childitem -path c:\windows ) | out-gridview

 

4 Die Console anpassen

Manchmal möchte man seine Konsolenausgabe durch den Einsatz von Farbe etwas aufwerten. In begrenztem Maße ist dies mit der Powershell recht einfach möglich.

Beispiel 1: Welche Farben bieten Powershell und .Net an

[system.enum]::GetNames([system.consolecolor])

# alternativ
# [system.consolecolor] | get-member -static -membertype property

#Ausgabe

Black
DarkBlue
DarkGreen
DarkCyan
DarkRed
DarkMagenta
DarkYellow
Gray
DarkGray
Blue
Green
Cyan
Red
Magenta
Yellow
White

 

Beispiel 2: Zeilen farblich hervorheben

Falls gewisse Werte einen Schwellwert über- oder unterschreiten, könnte man diese Werte farblich hervorheben.

$a=5
if($a -le 10){
   write-host -backgroundcolor red $a
   }else{
   write-host $a
   }

Technet:  Write-Host


Beispiel 3: die ganze Konsole verändern

Im Kapitel MyPowershell -> 3.3.1.2 Beispiele für Profile haben wir folgendermaßen auf die Konsoleneigenschaften zugegriffen und diese verändnert

$h=get-host

$win = (Get-Host).UI.RawUI
$win.BackgroundColor = "gray"
$win.ForegroundColor = "DarkBlue"

$win_size=$win.windowsize
$win_size.height=45
$win_size.width=110
$h.ui.rawui.set_windowsize($win_size)
clear-host

Die Klassen hinter get-host "System.Management.Automation.Internal.Host.InternalHost" finde ich nicht so richtig übersichtlich aufgebaut.

Natürlich können wir auch alternativ mit .Net Klassen die Konsole verändern. 

[System.Console]::BackgroundColor="Gray"      #Property
[System.Console]::ForegroundColor="DarkBlue"  #Property
[System.Console]::Title="Karl Napf"           #Property
[System.Console]::SetWindowsize(110,45)       #Methode
[System.Console]::Beep()                      #Methode    
[System.Console]::Clear()                     #Methode

Wenn wir uns die statischen Eigenschaften der Klasse "Console" ansehen, finde ich den Weg über die .Net Klasse verständicher.

[system.console] | Get-Member -Static  | Format-Table name,membertype -autosize

#Ausgabe gekürzt

Name                 MemberType
----                 ----------
Beep                     Method
Clear                    Method
Read                     Method
ReadKey                  Method
ReadLine                 Method
ResetColor               Method
SetBufferSize            Method
SetCursorPosition        Method
SetError                 Method
SetIn                    Method
SetOut                   Method
SetWindowPosition        Method
SetWindowSize            Method
Write                    Method
WriteLine                Method
BackgroundColor        Property
BufferHeight           Property
BufferWidth            Property
CapsLock               Property
CursorLeft             Property
CursorSize             Property
CursorTop              Property
CursorVisible          Property
Error                  Property
ForegroundColor        Property
LargestWindowHeight    Property
LargestWindowWidth     Property
Title                  Property
WindowHeight           Property
WindowLeft             Property
WindowTop              Property
WindowWidth            Property

Technet - ScriptingGuy:  Use .NET Classes to Configure the Windows PowerShell Console


Beispiel 4: Farben zurücksetzen

Hat man eine zu grausame Farbkombination - etwa grüne Schrift auf cyan Hintergrund - gewählt, hilft

[Console]::ResetColor()
[Console]::Clear()

Und alle Farben sind wieder im Ausgangszustand