DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019

Die Seite wird erstellt Katrin Thomas
 
WEITER LESEN
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
DIGITAL WORKSPACE WORLD
2019

HANDS-ON-LAB
SASM Public API
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Beschreibung                   In diesem Lab lernen Sie, wie Sie über die seit Version 9.1
                                verfügbare Public API auf die Daten des Matrix42 Software
                                Asset- und Service-Management (SASM) zugreifen können.

 Lernziele                      Am Ende dieses Hands-On-Labs wissen Sie, wie Sie ein
                                PowerShell Script anhand von Beispielen erstellen und
                                anpassen um über die SASM Public API
                                    •   Daten zu lesen,
                                    •   zu schreiben
                                    •   und eine Störung zu erstellen

 Hinweise                       Die Inhalte dieses Labs werden Ihnen im Rahmen einer kurzen
                                Präsentation erläutert.
                                Das Lab führt Sie Schritt für Schritt an das Lernziel heran.
                                Bitte nutzen Sie die Lab-Anleitung auf den nächsten Seiten.
                                Das Lab ist für etwa 45 Minuten konzipiert, kann
                                gegebenenfalls schneller absolviert werden. Sie bestimmen
                                die Geschwindigkeit.
                                Bitte stellen Sie Ihre Fragen den Moderatoren Ihrer Lab-
                                Session.

                                Danke, dass Sie sich für dieses Lab entschieden haben.
                                Viel Spaß!

Vorbereitung
Melden Sie sich zuerst mit diesen Daten am Server an, den Client benötigen wir nicht:

    •   SRVWSM001       Benutzername: imagoverum\vvogel            Passwort: Matrix42

                                                                                               2
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Ablauf
Starten Sie die UUX Konsole über das Desktop-Icon „Unified User Experience“:

Starten Sie folgenden Anwendungen über das Starmenü:
             • Microsoft SQL Server Management Studio 17 (einfach „Connect“ klicken zur
                 Anmeldung) und die
             • Windows Powershell ISE

                                                                                     3
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Aufgabe 1: Setzen des Garantieauslaufs an einem Computer

Anforderung: Wir haben ein Drittsystem, in dem die Garantieabläufe aller Computer
gespeichert sind. Dort sind auch die internen ObjectIDs aller Assets in unserer SASM
Datenbank gespeichert so dass wir einfach auf die Objekte zugreifen können. Wir wollen nun
das Garantiedatum eines Computers aus dem Drittsystem heraus im SASM aktualisieren.

Wir nutzen als Drittsystem hier PowerShell, da es den meisten Kunden bekannt und nicht zu
spezifisch ist. Im Prinzip kann aber jede Anwendung verwendet werden, die über WebServices
auf andere Systeme zugreifen kann oder ein solches PowerShell Script als Vermittler nutzen
kann.

Zunächst brauchen wir dafür einen Funktionsblock um uns an der Public API anzumelden. Bitte
übernehmen Sie die folgenden Zeilen per Zwischenablage in das PowerShell ISE in das
automatisch beim Start eröffnete Script „unbenannt.ps1“:

#! /usr/bin/pwsh
# Variables required to access the API
$baseurl = ""
$apitoken = ""
function Get-Accesstoken {
    param (
        [Parameter(Mandatory=$true)][string]$apitoken
    )
    $header = @{
        Authorization="Bearer $apitoken"
    }
    Invoke-RestMethod -Method Post -Uri
"$baseurl/api/ApiToken/GenerateAccessTokenFromApiToken/" -Headers $header |
Select-Object -ExpandProperty RawToken
}
$accesstoken = Get-Accesstoken -apitoken $apitoken

Tragen Sie nun als Wert für die BaseURL in Zeile 3 folgende URL zu unserem API-Service ein:
$baseurl = "https://srvwsm001.imagoverum.com/M42Services"

Das API Token müssen wir mit einem Wert aus unserem Server füllen. Wir bekommen damit
Zugang zur API. Die nachfolgenden Script-Zeilen ab „function Get-Accesstoken“ erstellen aus
diesem API Token ein Access Token, das dann an den Server zusammen mit dem Befehl
übermittelt wird.

                                                                                         4
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Um das API Token zu erstellen, wechseln Sie in die UUX Konsole, gehen Sie in die Anwendung
„Administration“…

…dann links „Integration“ und „Web Services Tokens“. Dann „Erstelle API-Token“ in der
Kopfzeile klicken und den Dialog rechts wie dargestellt ausfüllen:

Damit geben wir diesem API Token die gleichen Rechte wie dem Service Account User (AD-
Konto imagoverum\wsmservices). Wir können die Rechte über die normalen Benutzerrollen
einschränken.
Zum Abschluss noch „Erstelle API-Token“ klicken und das Ergebnis (den langen
Zahlen/Buchstaben-String) in die Zwischenablage kopieren:

                                                                                        5
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Anschließend das Token aus der Zwischenablage in das Powershell Script als Wert bei
APIToken eintragen. Beachten Sie die Anführungszeichen vor und hinter dem Token.

Starten Sie mal testweise das Script in der Powershell ISE indem Sie den grünen Pfeil in der
Tool-Leiste anklicken oder  drücken. Es dürften keine roten Fehlermeldungen erscheinen.
Sonst ist wahrscheinlich bei der Übernahme des Tokens etwas schiefgelaufen.

Nun müssen wir dem Script noch etwas zu tun geben – bisher haben wir ja nur die Anmeldung
am API Service. Kopieren Sie dafür diese Zeilen als Vorlage an das Ende des PowerShell-Scripts
gleich unter die Zeile $accesstoken=…:

$body = @{
   "ID"="";
   "GuarantyEndDate"="2020-12-31 00:00:00"
    }

$header = @{
    Authorization="Bearer $accesstoken"
}
Invoke-RestMethod -Method Put -Uri
"$baseurl/api/data/fragments/SPSAssetClassBase" -Headers $header -Body
($body|ConvertTo-Json) -ContentType "application/json"

Im Body wird die ObjectID unseres Ziel-Assets definiert – wie das geht wird gleich erklärt.
GuarantyEndDate können Sie bei Bedarf anpassen. Als Beispieldatum haben wir den
31.12.2020 gewählt.

Danach kommt im Header unserer Anfrage, die wir an die API schicken werden, der oben
generierte AccessToken damit wir die Berechtigung auf die API bekommen.

Schließlich wird über den Invoke-Befehl die Kombination aus Header und Body and die API im
für WebServices üblichen JSON Format geschickt. An die URL wird dabei /api/data/fragments
angehängt um zu definieren, welchen Service genau wird ansprechen wollen.

/data/fragments ist zur Bearbeitung von Datendefinitionen vorgesehen. Eine Beschreibung
aller Services finden Sie direkt in der UUX wenn Sie auf Administration/ Integration/
WebServices gehen und dort dann auf einen Service klicken:

Wenn Sie dann im rechten Fenster auf die verfügbaren Transaktionen klicken, erhalten Sie
weitere Informationen und auch Beispiele.

Wie schon geschrieben werden wird im ersten Schritt auf den Computer im SASM über die
interne ObjectID zugreifen – später werden Sie noch sehen wie man den Computernamen
ermittelt.

                                                                                              6
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Gehen Sie dafür in das MS-SQL Management-Studio klicken Sie auf den Toolbar-Knopf „New
Query“ und geben Sie folgendes Script ein:

Use M42Production
select id,name,GuarantyEndDate from SPSAssetClassBase where name like '%pcd%'

Klicken Sie dann auf „Execute“. Das listet uns einige Computer deren Name mit „PCD“ beginnt
und deren Garantieauslaufdaten auf:

Nehmen Sie sich einen der Computer wo „NULL“ bei GuarantyEndDate steht und kopieren Sie
die ID in Spalte 1 in die Zwischenablage.

Fügen Sie den Wert in das PowerShell-Script bei „ID“ im Body ein.
Ihr fertiges Script sollte nun ungefähr so aussehen:

#! /usr/bin/pwsh
# Variables required to access the API
$baseurl = "https://srvwsm001.imagoverum.com/M42Services"
$apitoken =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImltYWdvdmVydW0uY29t
XFx3c21zZXJ2aWNlcyIsIm5hbWVpZCI6ImltYWdvdmVydW0uY29tXFx3c21zZXJ2aWNlcyIsImlzcy
I6Imh0dHBzOi8vc3RzLm1hdHJpeDQyLmNvbSIsImF1ZCI6InVybjptYXRyaXg0MkFwaSIsImV4cCI6
MTU5NjYzNjQyMSwibmJmIjoxNTY1MTAwNDIxfQ.aUY5uiEc_WFOJLAGC2lR7e1QazX_Bh4kS0oJflP
MBv0"
function Get-Accesstoken {
    param (
        [Parameter(Mandatory=$true)][string]$apitoken
    )
    $header = @{
        Authorization="Bearer $apitoken"
    }
    Invoke-RestMethod -Method Post -Uri
"$baseurl/api/ApiToken/GenerateAccessTokenFromApiToken/" -Headers $header |
Select-Object -ExpandProperty RawToken
}
$accesstoken = Get-Accesstoken -apitoken $apitoken

$body = @{
   "ID"="EE5BFAB3-7C33-E511-80F6-0050562F9516";

                                                                                       7
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
"GuarantyEndDate"="2020-12-31 00:00:00"
    }

$header = @{
    Authorization="Bearer $accesstoken"
}
Invoke-RestMethod -Method Put -Uri
"$baseurl/api/data/fragments/SPSAssetClassBase" -Headers $header -Body
($body|ConvertTo-Json) -ContentType "application/json"

Wenn Sie es starten, sollten keine Fehler erscheinen und wenn Sie hinterher noch einmal
„Execute“ im SQL Management Studio klicken sollte das Garantiefeld des Computers gefüllt
sein:

Sie können den Wert auch im Asset Management in der UUX am Computer prüfen.
Er ist am Computer im Reiter „Beschaffung“ zu finden:

Sollte es Probleme geben können, Sie einfach den Codeblock oben 1:1 in Ihre Umgebung
übernehmen. Der verwendete API Token ist bereits auf dem Server definiert.

Speichern Sie Ihr Script mit „Datei\Speichern unter“ in der PowerShell ISE z.B. als
„c:\Garantie.ps1“.

                                                                                       8
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Aufgabe 2: Auslesen der Seriennummer eines Computers

Als nächste Aufgabe wollen wir via PowerShell die Seriennummer eines Computers im SASM
auslesen. Diesmal wollen wir auch den Namen angeben, nicht die ObjectID. Dies kann man z.B.
verwenden um eine externe Datenbank zu aktualisieren oder Daten in einem anderen
Helpdesk-System anzuzeigen.

Speichern Sie das Script aus Aufgabe 1 noch mal unter einem anderen Namen (z.B.
„c:\Seriennummer.ps1“

Löschen Sie alles unterhalb der Zeile

$accesstoken = Get-Accesstoken -apitoken $apitoken

und fügen Sie dann ans Ende folgenden neuen Codeblock via Zwischenablage hinzu:
function GetFragment{
       param(
       [STRING]$WebURI,
       [STRING]$RawAccessToken,
       [STRING]$ObjectDataService,
       [STRING]$APIOperation,
       [STRING]$DataDefinition,
       [STRING]$Columns,
       [STRING]$WhereClause
       )
       $FinalUrl =
"$WebURI$ObjectDataService$DataDefinition$Columns$WhereClause"
       $ContentType = 'application/json'
       $RequestHeader = @{Authorization = "Bearer $RawAccessToken"}
       $APIReturnGet = Invoke-RestMethod -Method $APIOperation -Uri $FinalUrl
-ContentType $ContentTyp -Headers $RequestHeader
       Write-Output $APIReturnGet
}
$WebURI = $baseurl + '/api/data/'
$ObjectDataService = 'fragments/'
$APIOperation = 'Get'
$DataDefinition = 'SPSAssetClassBase'
$AssetName = 'PCD1000'
$Columns =
'?Columns=ID%2CT(SPSComputerclassBase).Name%20as%20ComputerName%2CSerialnumber
%20as%20AssetSerialNumber%2CT(SPSComputerclassBase).NT4DomainName%20as%20NT4Do
main%2CAssignedUser%20as%20AssignedUserID%2C%5BExpression-
ObjectID%5D%20as%20ObjectId'
$WhereClause =
"&Where=UsedInTypeSPSComputerType%20IS%20NOT%20NULL%20AND%20T(SPSComputerclass
Base).Name%20like%20%27$AssetName%27"
$GetAssetData = GetFragment -WebURI $WebURI -RawAccessToken $AccessToken -
ObjectDataService $ObjectDataService -APIOperation $APIOperation -
DataDefinition $DataDefinition -Columns $Columns -WhereClause $WhereClause
$SerialNumber=$GetAssetData.AssetSerialNumber

Write-Output "Die Seriennummer von Computer $AssetName ist $SerialNumber"

      Viel zunächst verwirrender Code - was passiert da im Detail?

Starten wir mal von unten:
Da gibt es eine Variable „SerialNumber“ die per write-output ausgegeben wird.

                                                                                      9
www.matrix42.com | © Matrix42
DIGITAL WORKSPACE WORLD - 2019 HANDS-ON-LAB SASM Public API - Digital Workspace World 2019
Diese Variable wird in der Zeile darüber definiert über die Variable „GetAssetData“ mit dem
Parameter „AssetSerialNumber“. Die Variable „GetAssetData“ ist in der Zeile darüber definiert
und ruft eine Funktion „GetFragment“ auf.

Man kann also in der vorletzten Zeile einfach durch Ersetzen von „AssetSerialNumber“ durch
ein anderes Feld in der Datenbank auf alle Daten zugreifen, dafür sind Funktonen sehr
praktisch. Sie sind eine Sammlung von Anweisungen, die parametrisiert aufgerufen werden.
Der Ergebniswert der Funktion nach Abfrage der API wird in die Variable geschrieben.

In der Zeile, die mit „$GetAssetData=“ startet, werden diverse Variablen an die Funktion
übergeben. Die Werte dazu finden wir direkt darüber. Diesmal verwenden wir die API
Operation „GET“ statt „PUT“ weil wir ja nun Daten lesen wollen.

Die Datendefinition SPSAssetClassBase wird in der Variable $DataDefinition eingetragen. Dies
entspricht dem Namen der Tabelle in der SQL-Datenbank von SASM wo die von uns gesuchten
Daten stehen.

Den Namen des Assets (=Computers) können Sie bei der Variablen $AssetName frei wählen
oder das Beispiel PCD1000 behalten.

Bei $Columns finden Sie eine ASQL Abfrage, die uns die ObjectID des Computers zurückliefert.
Sie sieht etwas speziell aus, weil Sonderzeichen wegen der WebServices konvertiert wurden.
Sie können selbst ASQL-Abfragen z.B. mit dem Matrix42 Query Analyzer erstellen. Sie finden
die QueryAnalyzer.exe im BIN Verzeichnis Ihres Servers unterhalb des
Installationsverzeichnisses von SASM (also z.B. C:\Program Files (x86)\Matrix42\Matrix42
Workplace Management\bin\QueryAnalyzer.exe).

Dann muss die ASQL Abfrage webservice-kompatibel encodet werden damit Sonderzeichen,
Umlaute, etc. bei der API ankommen. Nützlich ist dafür diese Website:
https://meyerweb.com/eric/tools/dencoder/
Wenn Sie den o.a. Wert bei Columns durch den Decoder laufen lassen, kommt eine normale
ASQL Abfrage heraus die uns die ID des Computers und einige Attribute liefert:

ID,T(SPSComputerclassBase).Name as ComputerName,Serialnumber as
AssetSerialNumber,T(SPSComputerclassBase).NT4DomainName as NT4Domain,AssignedUser
as AssignedUserID,[Expression-ObjectID] as ObjectId

Die WHERE-CLAUSE darunter filtert den Rückgabewert auf genau den einen Computer mit
dem definierten Asset-Namen. Im dekodierten Klartext sieht die Abfrage so aus:

UsedInTypeSPSComputerType IS NOT NULL AND T(SPSComputerclassBase).Name like
'$AssetName'

                                                                                           10
www.matrix42.com | © Matrix42
Testen Sie das Script ob es fehlerfrei durchläuft und Ihnen die korrekte Seriennummer liefert.
Die Gegenprüfung können Sie mit den Informationen aus dem Asset Management in der UUX
Konsole vornehmen (Klickpfad: Anwendung „Assets“ starten, dann links „Endgeräte“, dann via
Suchtext in der oberen Zeile nach dem Computer suchen):

Speichern Sie Ihr Script.

                                                                                          11
www.matrix42.com | © Matrix42
Aufgabe 3: Erstellen einer Störung

Zum Abschluss noch ein einfacheres aber sehr praktisches Beispiel. Diesmal arbeiten wir nicht
direkt mit Daten sondern nutzen eine API Funktion die uns eine Störung erstellt. Das ist
besonders praktisch um aus einem Drittsystem heraus eine Störung zu melden z.B. aus einem
Monitoring-Tool wenn ein Server nicht erreichbar ist oder ein Virenausbruch festgestellt
wurde.

Speichern Sie wieder Ihr bestehendes Script unter einem anderen Namen, z.B.
„c:\Störung.ps1". Dann wie in Aufgabe 2 alles unter der Zeile „%accesstoken=“ löschen.

Dann diesen Codeblock an das Ende des Scripts kopieren:

$body = @{
        "Subject"="";
        "Description"="";
        "EntryBy"="4";
    }
$header = @{
    Authorization="Bearer $accesstoken"
}
Invoke-RestMethod -Method Post -Uri "$baseurl/api/incident/create" -Headers
$header -Body ($body|ConvertTo-Json) -ContentType "application/json"

Wie Sie sehen, ist das Script sehr schlank im Vergleich zur Aufgabe 2.

In der letzten Zeile wird das Kommando an die API geschickt, wieder im JSON Format und mit
dem AccessToken im Header zur Anmeldung. Diesmal wird die API-Operation /incident/create
statt /data/fragments wie in den anderen Aufgaben verwendet.

Die Parameter für die neuen Störung müssen im Body gleich darüber eingetragen werden.

Denken Sie sich ein interessantes Subject (Zusammenfassung) und eine Description
(Beschreibung) aus. Sie können bei der Description auch mehrere Zeilen eingeben.

Die EntryBy Variable definiert was in der Störung bei „Erstellt per“ eingetragen wird.

Starten Sie das Script. In der Powershell-Konsole erhalten Sie eine Zahlen- und
Buchstabenfolge angezeigt. Das ist die Expression Object ID von der Störung die angelegt
wurde.

                                                                                           12
www.matrix42.com | © Matrix42
Wechseln Sie in die UUX-Konsole gehen Sie in das Service Desk Modul und prüfen Sie unter
„Störungen“ ob Ihre neue Störung erstellt wurde:

Wahrscheinlich habe Sie gesehen, dass rot „Initiator wurde nicht angegeben“ oben erscheint.
Das kommt, weil wir keinen Benutzer mitgegeben haben unter dem die Störung eröffnet wird.
Das können wir über die optionale Uservariable nachholen.

Besorgen Sie sich dafür über das SQL Server Management Studio aus der Datenbank
M42Production, Tabelle SPSUserClassBase über Rechtsklick auf dbo.SPSUSerClassBase und
dann „Select Top 1000 Rows“…

                                                                                       13
www.matrix42.com | © Matrix42
…die ID eines Users aus der ersten Spalte, z.B. vom User „Service Account“:

Fügen Sie nun eine weitere Zeile in den Body unseres Scripts ein. Das Feld heißt User und der
Wert ist die UserID. Nach der Zeile ein Semikolon eingeben. Komplett mit Anmeldung sieht es
dann so z.B. aus:

#! /usr/bin/pwsh
# Variables required to access the API
$baseurl = "https://srvwsm001.imagoverum.com/M42Services"
$apitoken =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImltYWdvdmVydW0uY29t
XFx3c21zZXJ2aWNlcyIsIm5hbWVpZCI6ImltYWdvdmVydW0uY29tXFx3c21zZXJ2aWNlcyIsImlzcy
I6Imh0dHBzOi8vc3RzLm1hdHJpeDQyLmNvbSIsImF1ZCI6InVybjptYXRyaXg0MkFwaSIsImV4cCI6
MTU5NjYzNjQyMSwibmJmIjoxNTY1MTAwNDIxfQ.aUY5uiEc_WFOJLAGC2lR7e1QazX_Bh4kS0oJflP
MBv0"
function Get-Accesstoken {
    param (
        [Parameter(Mandatory=$true)][string]$apitoken
    )
    $header = @{
        Authorization="Bearer $apitoken"
    }
    Invoke-RestMethod -Method Post -Uri
"$baseurl/api/ApiToken/GenerateAccessTokenFromApiToken/" -Headers $header |
Select-Object -ExpandProperty RawToken
}
$accesstoken = Get-Accesstoken -apitoken $apitoken

$body = @{
        "Subject"="Subject 123";
        "Description"="Description 123";
        "User"= "bfecb19e-cc09-e511-d380-0050562f9516";
        "EntryBy"="4";
    }
$header = @{
    Authorization="Bearer $accesstoken"
}
Invoke-RestMethod -Method Post -Uri "$baseurl/api/incident/create" -Headers
$header -Body ($body|ConvertTo-Json) -ContentType "application/json"

                                                                                         14
www.matrix42.com | © Matrix42
Weitere Parameter finden Sie in der In-App-Dokumentation zum WebService:

Ende
Sie haben dieses Hands on Lab erfolgreich abgeschlossen. Wir hoffen, Sie hatten Spaß dabei
und konnten etwas Hilfreiches lernen.

                                                                                        15
www.matrix42.com | © Matrix42
Wenn Sie noch Zeit haben…

Wenn Sie nach diesem HandsOnLab noch Zeit haben hier ein paar Extra-Ideen:

Modifizieren Sie das Script aus Aufgabe 2 so, dass andere Werte aus der SASM Datenbank
ausgelesen werden.

Fügen Sie weitere Parameter bei der Erstellung der Störung in Aufgabe 3 hinzu, z.B. einen
Computer.

Passen Sie bei Aufgabe 1 das Script so an, dass auch ein Computername zum Setzen des
Garantieauslaufs statt der ObjectID verwendet werden kann.

Vielleicht wollen Sie sich auch mit dem Tool Postman https://www.getpostman.com/
beschäftigen. Damit kann man sehr schön Schritt für Schritt API Abfragen bauen und bekommt
noch mehr Rückmeldungen vom Webservice angezeigt.

Wenn Sie wissen wollen, welche JSON Strukturen und Attribute unsere Oberfläche nutzt,
können Sie auch mal in die UUX Konsole wechseln, dann drücken Sie  und wählen
Network, XHR. Dann klicken Sie verschiedene Objekte in der UUX an. Sie werden sehen, dass
im Fenster rechts erscheinen in der Preview die entsprechenden Attribute, so dass Sie sie in
Ihren Scripts verwenden können:

Vielleicht ist Ihnen auch aufgestoßen, dass API-Tokens unverschlüsselt im Script stehen? Das
können Sie ändern, indem Sie den Token verschlüsseln und an sicherer Stelle als Datei ablegen.
Googeln Sie mal nach „powershell api token encrypt“ und Sie werden viele Treffer mit
Beispielen finden!

                                                                                            16
www.matrix42.com | © Matrix42
Sie können auch lesen