Home PowerShell Grundlagen PowerShell eigene Objekte erstellen Custom Objects
formats

PowerShell eigene Objekte erstellen Custom Objects

Eine Goldene Regel in PowerShell ist es: Das eine Funktion oder ein Cmdlet immer ein Objekt zurückgeben sollte!

 

Wenn man kein fertiges Objekt hat und Daten aus verschiedenen Quellen zusammen sammelt, dann muss man sich ein eigenes Objekt zusammen bauen!

 

PowerShell ist eine Dynamische Sprache und hat das so genannte Extended Type System (ETS).

Durch das Extended Type System kann man Objekte um zusätzliche Eigenschaften und Methoden erweitern auch wenn diese Objekte schon vorhanden sind (Instanziiert).

Man kann Objekte in der PowerShell auf sehr viele Arten erstellen und Modifizieren.

Ich stelle hier mehrere Möglichkeiten vor, ein so genanntes PSCustom Objekt zu erstellen und es mit NoteProperties zu versehen.

 

New-Object und Hashtable

 

Am einfachsten wäre es natürlich die Daten in einer Hashtable zu sammeln. Nur leider mögen einige Cmdlets keine Hashtables direkt verarbeiten!

Es ist aber leicht aus einer Hashtable ein Objekt zu erstellen.

 

Beispiel:

# Hashtable mit Inhalt erstellen

$Hash= @{ Wert1 = 1;Wert2 = 2;Wert3 = 3}

 

$Obj=New-Object-TypeNamePSObject-Property$Hash

 

# Oder So: Ohne Umweg über die Variable der Hashtable:

$Hash=New-Object-TypeNamePSObject-Property @{ Wert1=1;Wert2=2;Wert3=3}

 

Nun könnte man Werte so aus einzeln  zusammen sammeln:

 

$Hash= @{} # leere Hashtable erstellen

$Hash+= @{Wert1 = 1} # Wert an die Hashtable anfügen

$Hash+= @{Wert2 = 2} # Wert an die Hashtable anfügen

$Hash+= @{Wert3 = 3} # Wert an die Hashtable anfügen

# Objekt aus Hashtable erstellen

$Obj=New-Object-TypeNamePSObject-Property$Hash

 

New-Object mit Add-Member

 

Dies ist der in PowerShell Version 2.0 vorgesehene Weg um PCCustonObjects zu erstellen.

Ein leeres Objekt erstellen und dann die NoteProperties nachträglich mit dem Cmdlet Add-Member anfügen:

 

# Neues leeres Objekt erstellen

$Obj=New-object-TypeNamePSObject

 

# Wert an das Objekt anfügen

Add-Member-InputObject$Obj-NameWert1-Value 1 -MemberTypeNoteProperty

# Wert an das Objekt anfügen

Add-Member-InputObject$Obj-NameWert2-Value 2 -MemberTypeNoteProperty

# Wert an das Objekt anfügen

Add-Member-InputObject$Obj-NameWert3-Value 3 -MemberTypeNoteProperty

# CSV Export der Daten

Export-Csv-InputObject$Obj-Path‘C:\Temp\test.csv’–NoTypeInformation

 

Welchen Weg man mit New-Object geht, spielt glaube ich letztendlich keine Rolle, da beide Wege eine ähnliche Performance haben.
Nwe-Object ist leider nicht sehr Performant. Warum das so ist beschreibt dieser Blog von cjoprey:

Custom object gotchas

http://cjoprey.wordpress.com/archived/custom-object-gotchas/

 

 

[PSCustomObject] ab PowerShell Version 3.0

 

Wesentlich performanter als der weg mit dem Cmdlet New-Object ist der mit PowerShell V. 3.0 eingeführte TypeAccelerator [PSCustomObject]

 

$Obj= [pscustomobject]@{Wert1=1; Wert2=2; Wert3=3}

 

Select-Object

 

Es gibt einen schnellen Trick um mit der Hilfe von den Cmdlet Select-Object ein vorhandenes Objekt mit neuen NoteProperties zu erweitern. Dieser Trick hat auch schon in der PowerShell Version 1.0 funktioniert.

 

Der folgende Code Benutzt einen leeren String “” , um diesem leeren String NoteProperties anzufügen. Aus diesem Grund ist das resultierende Objekt auch ein String und kein PSCustom Objekt:

 

# Objekt aus einem leeren String erstellen

$StrObj=“” | Select-Object Wert1,Wert2,Wert3

 

# Werte an die NoteProperties zuweisen

$StrObj.Wert1= 1

$StrObj.Wert2= 2

$StrObj.Wert3= 3

 

Select-Object und berechnete Eigenschaften

 

Wie das Select-Object Beispiel von oben schon zeigt, kann man Select-Object ähnlich wie Add-Member benutzen. Dies geht eleganter mit so genannten berechneten Eigenschaften (“calculated properties”.  ). Berechnete Eigenschaften bestehen aus einer Hashtable, die einen Namen für das Property angibt und einen Wert der in einem Skriptblock berechnet wird.

Ich benutze diese Möglichkeit gerne, Objekten in einer Pipeline neue Informationen anzufügen.

Beispiel einer berechneten Eigenschaft als Hashtable:

@{Name=”SamAccountName”; Expression = {$_.SamAccountName}}

 

 

Exkurs: Objekt Typen verändern

 

Viele Befehle in der PowerShell erkennen den Typ eines Objektes anhand seines Typnamens. Nun kann man bei den hier erstellten Objekten den Typ Namen so verändern das dieses Objekt auch wie dieser Typ behandelt wird. Die Properties müssen aber dem Ziel-Objekttypen entsprechen, sonst gehen viele Zugriffe auf dieses Objekt schief! Ebenso fehlen die Objekttypischen Methoden. Man kann also nicht einfach aus einem Objekt z.B. eine Hashtable erstellen. Dies muss über die dafür vorgesehenen Wege geschehen (Casting).

Das umbenennen des Objekttypen funktioniert bei Objekten die mit New-Objekt und Select-Objekt erstellt wurden.

Die folgende Codezeile macht aus unserem String Objekt $StrObj ein PSCustom Objekt:

 

$StrObj.pstypenames.insert(0,‘System.CustomObject.PSObject’)

Das ganze Beispiel:

 

$Obj=“” | Select-Object Wert1,Wert2,Wert3

$Obj.Wert1= 1

$Obj.Wert2= 2

$Obj.Wert3= 3

# Das Objekt mit Get-Member abfragen. Der TypeName ist von Interresse

$Obj | Get-Member# Ergebnis ist: TypeName: Selected.System.String !

# Den Objekt TypeName verändern

$Obj.pstypenames.insert(0,‘System.CustomObject.PSObject’)

# Das Objekt mit Get-Member abfragen. Der Typename ist von Interresse

$Obj | Get-Member# Ergebnis ist: TypeName: System.CustomObject.PSObject !

 

New-Module –asCustomObject

 

Da alles in PowerShell ein Objekt ist, ist auch ein Modul “nur” ein Objekt mit Methoden (Function) und Feldern (Property).

Deshalb kann man mit dem Cmdlet New-Module dem Parameter –asCustomObject und einem Scriptblock ein Objekt erstellen.

Der Vorteil hierbei ist, dass es viel leichter ist diesem Objekt neuen Methoden (Functions) oder neue Properties anzufügen.

 

Die bisher gezeigten NoteProperties können jeden Typen annehmen. Die Properties des Objektes, das über New-Modul erstellt wird, können stark Typisiert werden. So dass die Zuweisung eines falschen wertes in einer Fehlermeldung enden.

 

# Erstellung des Objektes mit einem Int Parameter

$Obj=New-Module-AsCustomObject-ScriptBlock {

      [int]$Wert1=$null; # Objekt Property als Integer definieren

      Export-ModuleMember-Variable*# Variablen Public machen

}

 

$Obj.Wert1= 4 # Zuweisung einer Integer-Zahl ist OK!

$Obj.Wert1=“Hallo”# Das geht nicht! Fehlermeldung.

 

Da wir hier ein komplettes PowerShell Modul als Objekt im Speicher erstellen, können wir auch Methoden (Function) in dem Objekt erstellen.

 

# Erstellung des Objektes mit 2 Int Parametern und einer Function

$Obj=New-Module-AsCustomObject-ScriptBlock {

      [int]$Wert1=$null; # Objekt Property als Integer definieren

      [int]$Wert2=$null; # Objekt Property als Integer definieren

     

      # Methode definieren

      FunctionAdd {

            $Wert1+$Wert2# Zahlen Addieren

      }

 

      Export-ModuleMember-Variable*-Function*  # Variablen und Funktionen Public machen

}

# Werte füllen

$Obj.Wert1 = 4

$Obj.Wert2 = 4

 

$Obj.Add() # Funktion ausführen

 

Add-Type (.NET Programmierung)

 

Innerhalb der PowerShell können Programmierer ebenfalls Objekte erstellen. Dazu muss eine von PowerShell unterstützten .NET Programmiersprache (C#, Visual Basic etc) genutzt werden.

Hierzu nutzt man das Cmdlet Add-Type.

Dadurch bekommt man mit der Hilfe von so genannten P/Invoke aufrufen, auch Zugriff auf die tieferliegenden Windows API (Win32).

 

# Eine Klasse mit C# Code und Add-Type definieren

Add-Type@”

    using System;

    public class myClass{

        public Double number=0;

        public Double Sqr()

        {

            return Math.Pow(number,2.0);

        }

    }

“@

 

# Das vorher definierte Objekt erstellen

$obj=New-ObjectmyClass

# Der Property des Objektes einen Wert zuweisen

$obj.number = 5

# Methode des Objektes ausführen

$obj.Sqr(

 

James Brundage: How to Create an Object in PowerShell

http://blogs.msdn.com/b/powershell/archive/2009/03/11/how-to-create-an-object-in-powershell.aspx

 

Windows API

http://de.wikipedia.org/wiki/Windows_Application_Programming_Interface

 

P/Invoke

http://www.codeplanet.eu/tutorials/csharp/6-pinvoke-grundlagen.html

 

 

Verweise:

 

Jeffrey Hicks

Creating Custom Objects in Windows PowerShell : Part 1-4

http://www.petri.co.il/custom-objects-windows-powershell-part-1.htm

http://www.petri.co.il/creating-custom-objects-windows-powershell-part-2.htm

http://www.petri.co.il/creating-custom-objects-in-windows-powershell-part-3.htm

http://www.petri.co.il/creating-custom-objects-windows-powershell-part-4.htm

.

http://technet.microsoft.com/en-us/magazine/hh750381.aspx

http://mjolinor.wordpress.com/2011/10/08/new-object-from-a-hash-table-in-a-script-block

http://mjolinor.wordpress.com/2012/01/31/creating-objects-from-ordered-hash-tables-in-powershell-v3

http://learn-powershell.net/2010/09/19/custom-powershell-objects-and-performance

http://blogs.msdn.com/b/mediaandmicrocode/archive/2008/11/26/microcode-powershell-scripting-tricks-select-object-note-properties-vs-add-member-script-properties.aspx

http://www.jonathanmedd.net/2011/09/powershell-v3-creating-objects-with-pscustomobject-its-fast.html

 
 Share on Facebook Share on Twitter Share on Reddit Share on LinkedIn
Kommentare deaktiviert  comments