Powershell für den einfachen Webzugriff um Dienste im Web aufzurufen oder XML-Dokumente zu laden


Bei einem Kunden sollte in regelmäßigen Abständen eine bestimmte Webseite aufgerufen werden um einen bestimmten Prozess anzustoßen. Gleichzeitig sollte später hin und wieder ein XML-Dokument abgeholt werden. Dank Powershell und dem .Net-Framework lässt sich die Aufgabe sehr einfach realisieren.

Serverdienst aufrufen, einfache Methode

$url = "http://www.service-site-im-internet.de/blabla?usw"
# Endlosschleife
do {
  $html = "";
  $html = (New-Object  System.Net.WebClient).DownloadString($url);
  Write-Host($html.Replace("<BR>", "`n"));
  Start-Sleep –Seconds 360
} while ($true)

Der Aufruf bei Replace ersetzt einen HTML-Umbruch durch einen Zeilenumbruch in Powershell. Näheres zu den Escape-Sequenzen und Zeichen in Powershell findet man unter

get-help about_escape_charachters

und

get-help about_special_characters

Serverdienst aufrufen, mit mehr Kontrolle

Ein Problem mit der einfachen Methode über die WebClient-Klasse http://msdn.microsoft.com/de-de/library/tt0f69eh.aspx ist, dass man nicht so einfach bestimmte sinnvolle Parameter setzen kann. Es gibt noch eine bessere Möglichkeit den Dienst aufzurufen. Mittels WebRequest-Klasse: http://msdn.microsoft.com/de-de/library/5t9y35bd(v=VS.80).aspx

$request = [System.Net.WebRequest]::Create($url)

Jetzt bekommt man jede Menge Infos in $request zurück. Wichtig: $request ist vom Typ HttpWebRequest und nicht mehr WebRequest! Genauso bekommt man FtpWebRequest, wenn man anstatt http: eben ftp: verwendet. Nun kann man zusätzlich jede Menge Parameter für den Aufruf setzen, wie UserAgent oder Passwörter usw.

Mittels

$response = $request.GetResponse()

erfolgt der eigentliche Aufruf. In $response gibt das Property Statuscode den HTTP-Statuscode zurück. Allerdings ist jetzt OK nicht so prickelnd, also verwendet man [int] vorneweg um den Code in einem schönen Zahlenwert zu bekommen.

$response.Statuscode
[int]$response.Statuscode

Hinweis: Wenn es Probleme gibt und das Script scheint zu hängen, bitte den $request.Timeout Wert beachten, dieser ist in der Vorgabe auf 100 Sekunden eingestellt! Also Geduld oder den Wert vor dem Aufruf runtersetzen.

Noch etwas mehr Kontrolle bei Fehlern

Tja leider ist das aber nur die halbe Wahrheit, denn wenn nun die durch $url angesprochene Ressource nicht verfügbar ist, dann wirbelt einem eine WebException entgegen und dann sieht ein Script schnell alt aus. Dies betrifft übrigens auch die erste einfache Variante.

Aus diesem Grund kapselt man den Aufruf von GetResponse() oder DownloadString() in einen try-catch Block.

Somit könnte obiger Aufruf so aussehen:

try {
  $response = $request.GetResponse()
}
catch [System.Net.WebException] {
  if ($_.Exception.Response.StatusCode –eq "404")
        {Write-Host "Seite nicht gefunden " + $_.Exception.Status}
}

#wichtig mit Close die Verbindung wieder freigeben!
$response.Close()

Nicht offensichtlich aber doch vorhanden, kann man die Response- sowie Status-Eigenschaften http://msdn.microsoft.com/de-de/library/system.net.webexception.response(v=VS.80).aspx bzw. http://msdn.microsoft.com/de-de/library/system.net.webexception.status(v=VS.80).aspx abfragen. Damit hat man die volle Kontrolle und kann auf alles reagieren.

XML-Dokument abholen

Ein XML-Dokument aus dem Internet abzuholen ist genauso einfach und erlaubt sogar den direkten Zugriff auf die einzelnen Elemente des XML-Dokuments.

$url = "http://www.infos-aus-dem-internet.de/hole-mir-die-datei.xml"
[xml]$xmldoc=(Net-Object System.Net.WebClient).DownloadString($url)

Wenn man z. B. folgendes XML-Dokument hat

<?xml version="1.0"?>
<COMPUTERNAME>
    TESTER
    <IP-ADDRESS>91.12.31.250</IP-ADDRESS>
    <PUBLISHED>
        <DATE>20.05.2011</DATE>
        <TIME>14:55:16</TIME>
    </PUBLISHED>
</COMPUTERNAME>

kann nachdem das Dokument geladen wurde, mittels

$xmldoc.COMPUTERNAME

auf das Element COMPUTERNAME zugegriffen werden. Auf die Ip-Adresse kann man mittels

$xmldoc.COMPUTERNAME.’IP-ADDRESS‘

zugreifen. Ein Zugriff auf

$xmldoc.COMPUTERNAME.IP-ADDRESS

ist nicht möglich, da der Bindestrich von Powershell anders interpretiert wird und sozusagen -ADDRESS als Parameter gesehen wird.

Daten zum Leben erwecken

Da die Daten aus der XML-Datei einfach nur leblose Daten, also Strings sind, kann man sie mittels einfachen Konvertierungsfunktionen zur vollen Blüte bringen.

Mittels

[DateTime]::Parse($xmldoc.COMPUTERNAME.PUBLISHED.DATE)

oder gleich

[DateTime]::Parse($xmldoc.COMPUTERNAME.PUBLISHED.DATE + " " + $xmldoc.COMPUTERNAME.PUBLISHED.TIME)

bekommt man ein Datumsobjekt geliefert, mit dem man nach Herzenslust danach arbeiten kann. Info zu Parse: http://msdn.microsoft.com/en-us/library/1k1skd40.aspx

Das gleiche Spiel kann man auch mit der IP-Adresse anstellen:

[IPAddress]::Parse($xml.COMPUTERNAME.’IP-ADDRESS‘)

Weitere Infos zu IPAddress.Parse() http://msdn.microsoft.com/de-de/library/system.net.ipaddress.parse(v=VS.80).aspx

Eine Antwort to “Powershell für den einfachen Webzugriff um Dienste im Web aufzurufen oder XML-Dokumente zu laden”

  1. Quirel Says:

    IIS7(.5) Statuscodes findet man alle hier beschrieben: http://support.microsoft.com/kb/943891

    Ansonsten die allgemeine Beschreibung als RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s


%d Bloggern gefällt das: