Microsoft Windows 2000 - Scripting-Handbuch (Teil 1) Scripting-Konzepte und -Technologien zur Systemadministration: Kapitel 2 - VBScript

Veröffentlicht: 26. Apr 2004

(Engl. Originaltitel: VBScript Overview)

Microsoft Visual Basic Scripting Edition (VBScript) ist eine einfach zu verwendende Scriptsprache, die es Systemadministratoren ermöglicht, hervorragende Tools zur Verwaltung von Windows-Computern zu entwickeln. In der ersten Hälfte dieses Kapitels werden die grundlegenden Prinzipien von VBScript beschrieben. Hierbei wird ein Script erstellt, das den freien Festplattenplatz von Laufwerk C anzeigt. Im Laufe des Kapitels wird das Script zu einem verfeinerten Tool weiter entwickelt, das den freien Festplattenplatz von beliebigen Laufwerken anzeigen kann. Der zweite Teil des Kapitels bespricht die grundlegenden Prinzipien genauer und stellt andere VBScript-Konstrukte dar.

Zurück zur Übersichtsseite

Auf dieser Seite

Links zu verwandten Themen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Übersicht zu VBScript

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arbeiten mit Objekten

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Variablen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Konstanten

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Zeichenketten

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Collections (Sammlungen)

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Schleifen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Entscheidungen treffen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arrays (Felder)

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Eingabe

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Fehlerbehandlung

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png VBScript-Referenz

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arbeiten mit Variablen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Verwendung von Konstanten

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Datentypen unter VBScript

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Mit Datum- und Zeitinformationen arbeiten

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arbeiten mit Strings (Zeichenketten)

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arbeiten mit Zahlen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Befehle mehrfach ausführen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Entscheidungen treffen

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Arrays

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Fehlerbehandlung

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Prozeduren

Dn151187.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png COM-Objekte


Artikel im PDF-Format

Dn151187.8B3D04996314173E7583D7C6B55A6BAC(de-de,TechNet.10).png sas_vbs_overview.pdf

PDF-Datei

Adobe Acrobat Reader downloaden

Microsoft® Visual Basic® Scripting Edition (VBScript) ist eine einfach zu verwendende Scriptsprache, die es Systemadministratoren ermöglicht, hervorragende Tools zur Verwaltung von Windows-Computern zu entwickeln. In der ersten Hälfte dieses Kapitels werden die grundlegenden Prinzipien von VBScript beschrieben. Hierbei wird ein Script erstellt, das den freien Festplattenplatz von Laufwerk C anzeigt. Im Laufe des Kapitels wird das Script zu einem verfeinerten Tool weiter entwickelt, das den freien Festplattenplatz von beliebigen Laufwerken anzeigen kann. Der zweite Teil des Kapitels bespricht die grundlegenden Prinzipien genauer und stellt andere VBScript-Konstrukte dar.

Übersicht zu VBScript

Microsoft® Visual Basic® Scripting Edition (VBScript) wird oftmals als "bloße" Scriptsprache missverstanden. Dies impliziert, dass eine Scriptsprache Systemadministratoren bei der Verwaltung von Hunderten oder Tausenden von Computern wenig nützt. Die Realität sieht jedoch ganz anders aus. In Kombination mit weiteren Technologien - zum Beispiel Windows Script Host (WSH), Windows Management Instrumentation (WMI) und Active Directory Service Interfaces (ASDI) - wird VBScript zu einer mächtigen Sprache zur Erstellung von Werkzeugen zur Systemadministration. Mit VBScript, WMI und ADSI können Sie ein Script von ca. 10.000 Zeilen schreiben, mit dem Sie einen Großteil eines Computers verwalten können.

Was VBScript aber wirklich nützlich macht, ist die Möglichkeit ein Script in wenigen Minuten zu schreiben statt eine komplizierte und umfangreiche Lösung zu entwickeln.

Das dreizeilige Script 2.1 zeigt Ihnen zum Beispiel, wie viel freier Platz noch unter Laufwerk C vorhanden ist.

Script 2.1: Abfragen des freien Speicherplatzes unter einem Laufwerk über VBScript

1

2

3

Set objWMIService = GetObject("winmgmts:")

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

Wscript.Echo objLogicalDisk.FreeSpace

Es kann natürlich sein, dass das Script nicht alle Ihre Wünsche erfüllt. Das Script zeigt Ihnen beispielsweise nur den freien Plattenplatz des lokalen Computers - und hier auch nur für Laufwerk C.

Das Script kann jedoch einfach angepasst werden, ohne neu anfangen zu müssen. Dies ist ein weiterer Vorteil von Scriptsprachen und VBScript: Sie können mit einem eher einfachen Script anfangen und dies dann Ihren Bedürfnissen anpassen. Dieses Kapitel beschreibt einen solchen Vorgang. Sie fangen mit Script 2.1 an, und in den folgenden Abschnitten werden Sie dann zu diesem einfachen dreizeiligen Script weitere Funktionalitäten hinzufügen. Nach diesen Erweiterungen haben Sie dann ein Script, das die folgenden Funktionen zur Verfügung stellt:

  • Abfragen des freien Plattenplatzes von jedem Computer in Ihrer Organisation - auch von Remotecomputern.
  • Abfragen des freien Plattenplatzes von mehreren Computern.
  • Abfragen des freien Plattenplatzes aller Laufwerke eines Computers.
  • Anzeigen einer Benachrichtigung, wenn nur noch wenig Platz auf einen Laufwerk verfügbar ist.
  • Kein Fehler oder Abbruch, wenn der Benutzer einen ungültigen Computernamen angibt, oder wenn auf einen Computer über das Netzwerk nicht zugegriffen werden kann.

Jedes Mal, wenn neue Features zum Script hinzugefügt werden, werden die verwendeten VBScript-Konstrukte ausführlich erklärt. Nachdem das Script vollständig ist, finden Sie einen Referenzabschnitt, der diese Konstrukte (und andere) detaillierter abdeckt.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Arbeiten mit Objekten

Mit VBScript können Sie über Programmiertechniken wie Verzweigungen, Schleifen, Fehlerbehandlung und Funktionsaufrufen sehr komplexe Scripte erstellen. Was Sie jedoch nicht finden werden, sind eingebaute Funktionen zu Systemadministration. VBScript verfügt über Funktionen, mit denen Sie die Wurzel einer beliebigen Zahl ermitteln oder den ASCII-Wert eines Zeichens anzeigen können - es gibt aber keine Funktionen um diesen anzuhalten, Einträge aus dem Systemprotokoll abzurufen oder andere Administrationsaufgaben durchzuführen.

Glücklicherweise gibt es andere Möglichkeiten solche Aufgaben durchzuführen - und zwar primär über Automatisationsobjekte. Automatisationsobjekte sind eine Untermenge von COM (Component Object Model). COM ist eine Möglichkeit für Anwendungen (exe-Dateien) oder Programmbibliotheken (dll-Dateien) ihre Funktionalitäten als Objekte zur Verfügung zu stellen. Diese Objekte und die von ihnen zu Verfügung gestellten Funktionalitäten können dann von Programmierern (oder Scriptautoren) in eigenen Anwendungen oder Scripten verwendet werden. Ein Textverarbeitungsprogramm könnte zum Beispiel seine Rechtschreibprüfung als Automatisationsobjekt zur Verfügung stellen. Ein Scriptautor kann dieses Objekt dann zur Rechtschreibprüfung in seinem Script verwenden.

Die Möglichkeit mit Automatisationsobjekten zu arbeiten, und die Methoden (auch Funktionen genannt) und Attributen (Eigenschaften) dieses Objekte verwenden zu können, macht VBScript zu einem mächtigen Tool in der Systemadministration. Alleine ist VBScript nicht in der Lage auf das Ereignisprotokoll zuzugreifen. Mit der Funktionalität von WMI wird dies jedoch auf einmal möglich. VBScript verfügt über keine eigenen Verfahren, um Benutzerkonten zu erstellen. Sie können jedoch die Funktionalität von ADSI für diese Aufgaben verwenden. Statt also eine riesige Menge von eigenen Funktion zur Verfügung zu stellen, bietet VBScript eher die Rahmenbedingungen, um die Methoden und Attribute von Automatisationsobjekten zu nutzen.

Script 2.2 zeigt die Bedeutung von Automatisationsobjekten in VBScript. Dieses Script gibt wiederum den freien Festplattenplatz von Laufwerk C zurück. Es verwendet nur sehr wenig VBScript-Code. Stattdessen macht es folgendes:

  1. Es baut über die VBScript-Methode GetObject eine Verbindung zu WMI auf (WMI ist ein Automatisationsobjekt).
  2. Es verwendet die Methode Get von WMI, um die Informationen über Laufwerk C abzurufen.
  3. Es verwendet die Methode Echo von WSH (ein weiteres Objekt), um diese Informationen anzuzeigen.

Wie gesagt, es gibt relativ wenig VBScript-Code in diesem Script. Stattdessen wird VBScript primär dazu verwendet, die Funktionalitäten von WMI und WSH zu verbinden.

Script 2.2: Objekte mit VBScript verwenden

1

2

3

Set objWMIService = GetObject("winmgmts:")

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

Wscript.Echo objLogicalDisk.FreeSpace

Mit Objekten verbinden

Bevor Sie die Daten einer Datenbank verwenden können, müssen Sie sich irgendwie mit dieser Datenbank verbinden. Bei Objekten ist das genauso - bevor Sie die Methoden (Funktionen) und Attribute (Eigenschaften) eines Automatisationsobjektes verwenden können, müssen Sie eine Verbindung zu diesem Objekt aufbauen. Dieses Verfahren wird auch als Einbinden von Objekten in ein Script bezeichnet.

Das Einbinden von Objekten kann ein wenig verwirrend sein, da sowohl die Sprache VBScript als auch der WSH (Windows Scripting Host) über eine Methode GetObject und CreateObject für den Zugriff auf Objekte verfügen. Auch wenn die beiden Methoden bei VBScript und bei WSH fast gleich arbeiten, so gibt es doch kleine Unterschiede - und diese werden immer wichtiger, je geübter Sie im Schreiben von Scripten werden. Diese Unterschiede werden später in diesem Kapitel besprochen. Im Moment stellen Sie sich einfach dumm und kümmern sich nicht darum, ob Sie die beiden Methoden über VBScript oder den WSH verwenden (in dem meisten Fällen werden Sie die VBScript-Varianten dieser beiden Methoden verwenden).

  • WMI oder ADSI über GetObject einbinden. Sowohl WMI als auch ADSI ermöglichen Ihnen die Verwendung eines Monikers bei der Einbindung eines Scripts. Ein Moniker ist ein Zwischenobjekt, das die Nutzung von Objekten vereinfacht (das Thema wird weiter unten in diesem Kapitel genauer besprochen). Auch wenn es möglich (und manchmal erforderlich) ist, WMI oder ADSI über die Methode CreateObject einzubinden, ist die Verwendung von GetObject und eines Monikers in dem meisten Fällen schneller und einfacher.
  • WMI oder ADSI über CreateObject einbinden. Im Allgemeinen benötigen Sie die Methode CreateObject, um neue Instanzen eines Objektes zu erstellen (zum Beispiel Instanzen der Objekte FileSystem, Dictionary oder Internet Explorer).

Eine Verbindung zu WSH aufbauen

In Zeile 1 von Script 2.2 wird über den folgenden Ausdruck WMI in das Script eingebunden:

Set objWMIService = GetObject("winmgmts:")

Mit dieser Zeile wird das Script mit dem SWbemServices-Objekt von WMI verbunden.

Um eine Verbindung zu WSH aufzubauen, ist so etwas nicht nötig. Sie sind bereits mit WSH verbunden, da WSH zur Ausführung eines Scriptes benötigt wird. Das WSH-Objekt steht somit also in jedem Script ohne Ihr Zutun zur Verfügung.

Eine Objektreferenz erstellen

In der Automatisation arbeiten Sie nicht direkt mit den Objekten selbst. Stattdessen erstellen Sie eine Referenz mit Hilfe von GetObject oder CreateObject auf das Objekt, und weisen diese Referenz dann einer Variable zu. Nachdem Sie eine solche Referenz erstellt haben, können Sie dann über die Variable statt über das Objekt selbst auf die Methoden und Attribute des Objektes zugreifen.

In Script 2.2 wird die Methode GetObject verwendet, um der Variable objWMIService einen Verweis auf das WMI-Objekt SWbemServices zuzuweisen. Nach der Zuweisung können alle Attribute und Methoden des SWbemServices-Objektesüber die Variable objWMIService abgefragt und aufgerufen werden. In Zeile Zwei des Scripts wird zum Beispiel die Methode Get des Objektes zur Abfrage der Eigenschaften von Laufwerk C aufgerufen.

Jedes Mal, wenn Sie einer Variable eine Referenz (einen Verweis) auf ein Objekt zuweisen, dann müssen Sie das VBScript-Schlüsselwort Set verwenden. Der folgende Code würde zum Beispiel zu einem Laufzeitfehler (einen Fehler bei der Ausführung des Scripts) führen:

objWMIService = GetObject("winmgmts:")

Stattdessen müssen Sie zur Erstellung einer Objektreferenz das Schlüsselwort Set verwenden:

Set objWMIService = GetObject("winmgmts:")

Das Schlüsselwort Set wird in VBScript nur zur Erstellung einer Objektreferenz verwendet. Wenn Sie es für andere Zwecke verwenden, zum Beispiel zum Zuweisen eines Wertes zu einer Variable, dann wird ein Laufzeitfehler auftreten. Der folgende Code wird zum Beispiel zu einem Fehler führen:

Set x = 5

Warum? Set kann nur zum Zuweisen von Objekten zu Variablen verwendet werden. Da 5 jedoch kein Objekt ist, tritt ein Fehler auf.

Methoden aufrufen

Sie können die Funktionalitäten von Automatisationsobjekten in Ihren eigenen Scripten verwenden. So sind Sie in der Lage, viel mächtigere Scripte zu schreiben, als wenn Sie nur auf die Funktionalität einer Scriptsprache eingeschränkt wären. Es ist zum Beispiel mit VBScript nicht möglich, ein Diagramm zu erstellen. Über die Automatisation können Sie sich eine solche Fähigkeit jedoch von Microsoft Excel ausleihen.

Automatisationsobjekte stellen normalerweise sowohl Methoden als auch Attribute zur Verfügung (das muss jedoch nicht immer so sein). Über Methoden können die möglichen Aktionen eines Objektes durchgeführt werden. Script 2.2 verwendet zum Beispiel die Automatisation, um auf die Methoden von zwei unterschiedlichen COM-Objekten zuzugreifen - so führt es zwei unterschiedlichen Aktionen aus. Diese zwei Methoden sind:

  • Die Methode Get - sie steht über das WMI-Objekt SWbemServices zur Verfügung. Diese Methode ruft Informationen über ein bestimmtes Objekt ab.
  • Die Methode Echo - sie steht über das WSH-Objekt zur Verfügung. Diese Methode zeigt Informationen auf dem Monitor an. Wenn ein Script in einer Eingabeaufforderung ausgeführt wird (wenn es also mit CScript.exe ausgeführt wird), dann werden diese Informationen in der Eingabeaufforderung ausgegeben. Wenn das Script mit Wscript.exe ausgeführt wird, dann werden die Informationen in einem eigenen Nachrichtenfenster ausgegeben.

Nachdem Sie eine Referenz auf ein Objekt erstellt haben, können Sie über die Punkt-Schreibweise (Notation) die Methoden des Objektes aufrufen. Die Punkt-Notation wird so genannt, da Sie beim Aufruf einer Methode den Namen der Variable schreiben, die den Verweis (die Referenz) auf das Objekt enthält, und dann einen Punkt und den Namen der gewünschten Methode des Objektes schreiben (abhängig von der Methode müssen Sie möglicherweise noch Parameter anhängen). Im Allgemeinen wird bei der Punkt-Notation die folgende Syntax verwendet:

Objektreferenz.MethodenName

In der folgenden Codezeile sehen Sie ein Beispiel für die Punkt-Notation. Sie ruft die Methode Get des Objektes SWbemServices auf.

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

Die einzelnen Teile des Aufrufes der Methode Get des Objektes SWbemServices sind in Tabelle 2.1 genauer beschrieben.

Tabelle 2.1: Die einzelnen Teile des Methodenaufrufes

Teil

Beschreibung

ObjWMIService

Die Objektreferenz

.

Der Punkt trennt die Objektreferenz vom Namen der aufgerufenen Methode des Objektes.

Get

Der Name der Methode

('Win32_LogicalDisk.DeviceID='c:'')

Parameter der Methode. Im Fall unserer Methode Get bedeutet dieser Parameter so viel wie "gib mir eine Referenz auf die Klasse Win32_LogicalDisk, bei der die DeviceID C: ist'.

Anmerkung:

  • Statt Wscript.Echo kann zur Anzeige von Informationen auch die VBScript-Funktion Msgbox verwendet werden:
  • Msgbox objLogicalDisk.FreeSpace
  • In diesem Buch wird jedoch immer Wscript.Echo statt Msgbox verwendet. Dies liegt daran, dass die Funktion Msgbox die Informationen immer als grafisches Nachrichtenfenster ausgibt. In diesem Nachrichtenfenster muss der Benutzer immer auf den Schalter OK klicken, bevor das Script weiter ausgeführt wird. Bei Scripten zur Systemadministration, die möglicherweise eine große Menge an Informationen anzeigen, könnte dieses Verfahren recht mühsam werden - außerdem könnte das Script nicht automatisch ausgeführt werden. Im Gegensatz dazu zeigt Wscript.Echo die Informationen zeilenweise in der Eingabeaufforderung an (vorausgesetzt, das Script wird unter CScript ausgeführt).

Attribute Abfragen

Die Attribute eines Objektes sind für administrative Scripte sehr wichtig, denn viele Objekte stellen tatsächliche Objekte dar. In Zeile 3 von Script 2.2 wird zum Beispiel das Attribut FreeSpace abgefragt - und zwar über dieselbe Punkt-Notation, wie beim Aufrufen von Methoden.

objLogicalDisk.FreeSpace

Bei WMI verweist das Objekt objLogicalDisk in diesem Fall nicht auf irgendein formloses Programmkonstrukt, sondern auf die tatsächliche Festplatte des Computers. Beim Attribut FreeSpace handelt es daher auch nicht einfach um eine Eigenschaft des Automatisationsobjektes, sondern um eine Eigenschaft von Laufwerk C. In gewissem Sinn erstellt WMI ein virtuelles Abbild eines physikalischen Objektes. Wenn Sie die Attribute dieses Abbilds abfragen, dann fragen Sie tatsächlich die Attribute des physikalischen Objektes ab.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Variablen

Script 2.2 funktioniert exakt so wie erwartet. Wenn es ausgeführt wird, dann zeigt es den freien Speicherplatz von Laufwerk C an. Das heißt jedoch nicht, dass das Script nicht noch verbessert werden kann. Das Attribut FreeSpace gibt den freien Speicherplatz zum Beispiel in Byte zurück. Da Festplattenplatz jedoch typischerweise in Gigabyte angegeben wird, ist die Ausgabe oft schwer zu interpretieren. In Abbildung 2.1 sehen Sie ein Beispiel zur Ausgabe des Scripts, bei dem noch ca. 2,88 GB freier Speicherplatz zur Verfügung steht.

Dn151187.9B9B63F8519F59A3C822F61C315197D6(de-de,TechNet.10).png

Abbildung 2.1: Freier Festplattenplatz in Byte

Auch wenn mit einem Blick zu sehen ist, dass auf Laufwerk C noch genügend Patz zur Verfügung steht, so ist es doch schwer festzustellen, wie viel Platz noch verfügbar ist. Die meisten Systemadministratoren würden es wohl einfacher finden, wenn das Script den Speicherplatz in MB oder GB statt in Byte ausgibt.

VBScript stellt eine große Menge mathematischer Funktionen zur Verfügung, über die Sie solche Aufgaben wie die Konvertierung von Byte in MB durchführen können. Außerdem steht Ihnen mit VBScript ein Konstrukt zur Verfügung, in dem Sie das Ergebnis einer solchen mathematischen Funktion speichern können: die Variable. In Variablen können Sie während der Laufzeit des Scripts jede Form von Daten speichern.

Variablen sind Speichereinheiten, die dem Script während seiner Laufzeit zur Verfügung stehen. Sie können sich den Hauptspeicher des Computers in diesem Zusammenhang als eine Ansammlung von vielen kleinen Fächern vorstellen, die alle mit einem Etikett versehen sind. Eine Variable ist eines von diesen Fächern. Das Etikett dient zur Identifizierung dieses Fachs/der Variable. Sie können beliebige Daten in diesem Fach ablegen, und VBScript kann diese dann bei Bedarf wieder aus dem Fach abholen. Wenn Sie auf die Variable zugreifen (also auf die in ihr enthaltenen Daten), dann sucht VBScript einfach nach der entsprechen Speicheradresse und gibt die unter dieser Adresse gespeicherten Daten an Sie zurück.

In Zeile 3 von Script 2.3 wird die Variable mit dem Namen FreeMegabytes zur Speicherung des Ergebnisses einer Division des Attributes FreeSpace durch 10484576 verwendet (ein MB enthält 10484576 Byte). Nach Zeile 3 enthält die Variable FreeMegabytes also das Ergebnis dieser Division. Wenn Sie nun die freien Megabyte irgendwo anders in Ihrem Script benötigen, dann können Sie auf die Variable zugreifen - Sie müssen die Berechnung nicht neu durchführen. Dies sehen Sie in Zeile 4, hier wird der Inhalt der Variable auf dem Monitor ausgegeben.

Script 2.3: Verwendung von Variablen

1

2

3

4

Set objWMIService = GetObject("winmgmts:")

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

FreeMegaBytes = objLogicalDisk.FreeSpace / 1048576

Wscript.Echo FreeMegaBytes

Die Ausgabe von Script 2.3 sehen Sie in Abbildung 2.2.

Dn151187.400E54A37D759A1BE30E658183F10010(de-de,TechNet.10).png

Abbildung 2.2: Freier Plattenplatz in MB konvertiert

Anmerkung: Beachten Sie, dass der Wert als 2954 statt als 2.954 ausgegeben wird (also ohne Tausender-Trennzeichen). Auch wenn es möglich ist, dieses in der Script-Ausgabe hinzuzufügen, so können Sie dieses intern in VBScript nicht verwenden.

Formatierung der Script-Ausgabe

Der Wert 2954,1328125 (er bedeutet, es gibt ca. 2954 MB freien Plattenplatz) ist für einen Systemadministrator wahrscheinlich viel Aussagekräftiger als der Wert 3098144768 aus unserem vorherigen Script. Die Nachkommastellen verwirren jedoch wahrscheinlich mehr, als das Sie nützen. Glücklicherweise bietet VBScript mehrere verschiedene Wege, um die Ausgabe eines Scripts anzupassen. Die Funktion Int zwingt VBScript zum Beispiel dazu, die Zahl als Integer (Ganzzahl ohne Nachkommastellen) anzuzeigen. Bitte beachten Sie, dass die Nachkommastellen der Varabile FreeMegaBytes in dem folgenden Beispiel nicht verworfen werden - sie werden nur nicht mit angezeigt.

Script 2.4: Formatierung der Ausgabe

1

2

3

4

Set objWMIService = GetObject("winmgmts:")

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

FreeMegaBytes = objLogicalDisk.FreeSpace / 1048576

Wscript.Echo Int(FreeMegaBytes)

In Abbildung 2.3 sehen Sie die Ausgabe von Script 2.4. Die Funktion Int schneidet die Nachkommastellen des Originalwertes ab. Weitere Formatierungsmöglichkeiten, mit denen Sie zum Beispiel ein Tausender-Trennzeichen zur Ausgabe hinzufügen können, lernen Sie später in diesem Kapitel kennen.

Dn151187.3DDCD182588B3E115B73A2020B694C28(de-de,TechNet.10).png

Abbildung 2.3: die Ausgabe mit der Funktion Int formatieren

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Konstanten

In Script 2.3 wird die MB-Zahl durch die Division des Attributes FreeSpace durch den hardcodierten Wert 1048576 errechnet. "Hardcodierter"-Wert bedeutet, dass der Wert direkt im Script enthalten ist (und nicht zum Beispiel dynamisch berechnet wird). Hardcodierte-Werte werden oft auch als Literale bezeichnet, da Sie nichts anderes als diesen Wert repräsentieren.

In einem kleinen Script wie diesem sind hardcodierte Literale kein Problem. In einem großen Script kann es jedoch zu zwei Problemen kommen:

Zum einen mag es in einem kleinen Script klar sein, dass 1048576 der Wert ist, der zur Konvertierung von Byte in MB verwendet wird. In einem größeren Script - zum Beispiel in einem, das viele nicht ganz so eindeutige Berechnungen verwendet - könnte dies weniger klar ersichtlich sein. Und zwar ganz besonders, wenn das Script von mehreren Administratoren verwendet und verändert wird. Sie wissen vielleicht, wofür die Zahl 1048576 steht, aber ein anderer Administrator weiß das möglicherweise nicht.

Wenn ein Script oft geändert werden muss, dann führt dies zu einem zweiten Problem. Literal-Werte können dazu führen, dass eine Änderung mehr Aufwand erfordert. Nehmen wir an, unser Scriptcode zur Konvertierung von Byte in MB wird an fünf oder sechs unterschiedlichen Stellen im Script verwendet. Wenn Sie sich nun später dazu entscheiden eine Konvertierung in GB statt in MB durchzuführen, dann müssen Sie alle fünf oder sechs Stellen im Script ändern.

Ein Weg, um solche Probleme zu umgehen, sind Konstanten. Konstanten speichern ebenso wie Variablen Daten. Im Gegensatz zu Variablen kann eine Konstante jedoch nach ihrer Definition (also nachdem ein Wert zur Konstante zugewiesen wurde) nicht mehr verändert werden. So wird vermieden, dass der Wert der Konstante zum Beispiel versehentlich verändert wird.

In 2.5 wird in Zeile 1 eine Konstante mit dem Namen CONVERSION_FACTOR definiert. Ihr wird der Wert 1048576 zugewiesen. Später in Zeile 4 wird die Bytezahl in MB konvertiert. Statt des Literalwertes 1048576 wird jedoch die Konstante CONVERSION_FACTOR verwendet. Das Ergebnis ist das gleiche wie vorher. Script 2.5 ist jedoch viel einfacher zu lesen und zu verstehen.

Script 2.5: Verwendung von Konstanten

1

2

3

4

5

Const CONVERSION_FACTOR = 1048576

Set objWMIService = GetObject("winmgmts:")

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

Wscript.Echo Int(FreeMegaBytes)

Ein weiterer Vorteil von Konstanten ist deren Wiederverwendbarkeit. Sie werden einmal erstellt, und können dann im gesamten Script so oft wie nötig verwendet werden. In einer erweiterten Version von Script 2.5 könnte es zum Beispiel notwendig sein, mehrmals eine Konvertierung von Byte zu MB durchzuführen. Hierzu können Sie dann jedes Mal die Konstante verwenden. Wenn Sie sich später entscheiden in GB statt in MB zu konvertieren, dann müssen Sie nur noch die Konstante statt jedes einzelnen Literalwertes verändern.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Zeichenketten

Wenn Sie anspruchsvollere Scripte schreiben, dann werden Sie feststellen, dass es unterschiedliche Datentypen gibt (wir werden dies später in diesem Kapitel genauer besprechen). In Zeile 1 von Script 2.5 wird der Konstante CONVERSION_FACTOR zum Beispiel der numerische Wert 1048576 zugewiesen:

Const CONVERSION_FACTOR = 1048576

Diese Zuweisung funktioniert deshalb, weil es sich um einen numerischen Wert handelt. Wenn Sie einen solchen Wert zuweisen möchten, dann reicht es, ein Gleichheitszeichen, gefolgt vom Wert, zu verwenden.

Wenn Sie allerdings versuchen, auf diese Art einen alphanumerischen Wert (eine Zeichenkette, auch String genannt) zuzuweisen, dann kann es zu unvorhergesehenen Problemen kommen. Die folgende Zeile versucht zum Beispiel der Variable Computer die Zeichenkette atl-dc-01 zuzuweisen und den Inhalt der Variable dann auszugeben:

Computer = atl-dc-01
Wscript.Echo Computer

Die Ausgabe des Scripts sehen Sie in Abbildung 2.4.

Dn151187.53900806A95BDFB98445596B3A1FC9C5(de-de,TechNet.10).png

Abbildung 2.4: Falsche Zuweisung einer Zeichenkette zu einer Variable

Wieso wurde der Variable Computer der Wert -1 zugewiesen? Wenn VBScript eine alphanumerische Zeichenkette ohne Anführungszeichen findet, geht es davon aus, dass dieses Zeichenkette einen Variablennamen darstellt. Wenn irgendwo in der Zeichenkette in Bindestrich vorkommt, dann interpretiert VBScript dieses als Minuszeichen. Als Ergebnis interpretiert VBSCript die Zeile Computer = atl-dc-01 als 'Der Variable Computer sollt das Ergebnis der Berechnung Variable atl minus der Variable dc minus 01 zugewiesen werden'. Da atl und dc als neue und nicht initialisierte Variablen (ohne zugewiesenen Wert) angesehen werden, enthalten Sie den Wert 0. VBScript interpretiert die Codezeile also so:

Computer = 0 - 0 - 1

Als Ergebnis steht natürlich in der Variable Computer der falsche Wert-1.

Wenn Sie eine Zeichenkette zu einer Variable oder Konstante zuweisen, dann müssen Sie die Zeichenkette in Anführungszeichen einschließen. So können Sie sicherstellen, dass VBScript die Zeichenkette auch als Zeichenkette und nicht als Zahl oder Variable interpretiert. Die folgende Beispielzeile weist der Variable Computer zum Beispiel korrekt die Zeichenkette atl-dc-01 zu und gibt den Inhalt der Variable dann aus:

Computer = "atl-dc-01"
Wscript.Echo Computer

Die Ausgabe des Scripts sehen Sie in Abbildung 2.5.

Dn151187.F1EB31E430504901BBCD4C90C1AB6DAF(de-de,TechNet.10).png

Abbildung 2.5: Korrekte Zuweisung einer Zeichenkette zu einer Variable

Zeichenketten als Variablen

Zeichenketten werden oft zur Zuweisung von Werten zu Variablen verwendet. Das Beispielscript in diesem Kapitel verwendet zum Beispiel die folgende Zeile zur Bindung an WMI:

Set objWMIService = GetObject("winmgmts:")

Mit dieser Zeile verbinden Sie sich mit dem lokalen Computer. Wenn Sie jedoch für viele Computer zuständig sind, dann möchten Sie wahrscheinlich auch Informationen von den Remotecomputern abfragen.

Wenn Sie WMI verwenden, dann können Sie sich mit einem Remotecomputer verbinden, indem Sie einfach den Computernamen in den an GetObject übergebenen Moniker mit aufnehmen. Die folgende Codezeile bindet den WMI-Dienst zum Beispiel an den Remotecomputer atl-dc-01:

Set objWMIService = GetObject("winmgmts://atl-dc-01")

Diese Codezeile können Sie zwar für ein Script verwenden, das einen Remotecomputer abfragt, in einer Unternehmensumgebung benötigen Sie jedoch möglicherweise eine flexiblere Lösung.

Ein Weg für eine Abfrage mehrerer Computer wäre das Script vor jeder Ausführung zu ändern. Sie ersetzen den hardcodierten Computernamen durch einen anderen. Ein weit besserer Ansatz ist jedoch das Script so zu ändern, dass es bei seinem Start einen Computernamen entgegennimmt - zum Beispiel durch einen Kommandozeilenparameter.

Methoden zur Benutzereingabe werden später in diesem Kapitel besprochen. Vorher sollten Sie jedoch wissen, wie Sie Zeichenketten (zum Beispiel Computernamen) zu Variablen zuweisen und diese dann im Scriptcode verwenden.

In Zeile 2 von Script 2.6 wird zum Beispiel die Zeichenkette 'atl-dc-01' zur Variable Computer zugewiesen. In Zeile 3 wird dieses Variable dann zur Bindung des WMI-Dienstes an Computer atl-dc-01 verwendet. Dies wird hier jedoch nicht über die Hardcodierung der Zeichenkette atl-dc-01 erreicht, sondern indem der Wert in der Variable Computer verwendet wird.

Script 2.6: Verwendung von Zeichenketten

1

2

3

4

5

6

Const CONVERSION_FACTOR = 1048576

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

Wscript.Echo Int(FreeMegaBytes)

In einem kleinen Beispielscript wie diesem erfordert das Zuweisen einer Zeichenkette zu einer Variable mehr Aufwand als eine Hardcodierung dieser Zeichenkette. Das Script zeigt trotzdem ein wichtiges Konzept: Sie können einen Wert zu einer Variable zuweisen und dieses Variable dann an Stelle einer Hardcodierung dieses Wertes verwenden.

Warum ist das wichtig? Stellen Sie sich vor, dass Script wurde zur Abfrage des freien Festplattenplatzes von 100 statt von einem Computer entwickelt. Statt separate Zeichenketten zur WMI-Bindung für jeden Computer fest einzutragen, verwenden Sie jedoch nur eine Zeichenkette mit der Variable Computer. Ihr Script könnte dann die gleiche Codezeile 100 Mal ausführen - und jedes Mal würde die Variable Computer einfach einen unterschiedlichen Computernamen enthalten.

Im Moment müssen Sie sich allerdings nur auf Zeile 3 von Script 2.6 konzentrieren:

Set objWMIService = GetObject("winmgmts://" & Computer)

So interpretiert VBScript diese Codezeile:

  1. Es liest alle bis zum zweiten Anführungszeichen. Mit anderen Worten:

    Set objWMIService = GetObject("winmgmts://"
    
  2. Es erkennt das kaufmännische Und (&) - dieses bedeutet "Hänge alles Folgende an die Zeichenkette an". Dem & folgt in diesem Fall die Variable Computer, der der Wert atl-dc-01 zugewiesen wurde. Für VBScript sieht die Codezeile damit also so aus:

    Set objWMIService = GetObject("winmgmts://atl-dc-01"
    
  3. Es liest die schließende Klammer. In VBScript muss es genauso viele schließende Klammern wie geöffnete Klammern geben. Wenn die schließende Klammer fehlt, gibt VBScript eine Fehlermeldung aus. Die von VBScript gelesene Codezeile sieht nun so aus:

    Set objWMIService = GetObject("winmgmts://atl-dc-01")
    
  4. Da nun das Ende der Codezeile erreicht ist, wird die Anweisung ausgeführt. Das Script verbindet sich mit dem WMI-Dienst von Computer atl-dc-01. Um sich mit dem WMI-Dienst eines anderen Computers zu verbinden, reicht es, den Wert in der Variable Computer zu ändern.

Verketten von Zeichenketten

Verketten heißt zwei oder mehr Zeichenketten zu einer einzelnen Zeichenkette zu verbinden (Sie können auch Zeichenketten mit numerischen Werten und Datumswerten verketten). Mit einer Verkettung erreichen Sie oft eine besser lesbare oder deutlichere Ausgabe. Script 2.4 gibt zum Beispiel den Wert 2953 zurück. Wenn Sie wissen, dass das Script den freien Speicherplatz von Laufwerk C in MB zurückgibt, ist dies eine sehr nützliche Information. Wenn Sie jedoch nicht wissen, was das Script macht, dann ist die Ausgabe völlig sinnfrei.

Neben anderen Dingen kann Ihnen eine Verkettung bei einer besseren Script-Ausgabe helfen. Statt zum Beispiel nur den Wert 2953 zurückzugeben, könnten Sie eine Nachricht wie "Es stehen 2953 MB freier Festplattenplatz zur Verfügung" zurückgeben. Hierzu müssen Sie die folgenden drei Teile kombinieren:

  • 'Es stehen ' - eine einfache Zeichenkette mit dem Anfang der Ausgabe.
  • FreeMegabytes - die Variable, die den freien Speicherplatz in MB enthält.
  • ' MB freier Festplattenplatz zur Verfügung" - eine zweite Zeichenkette mit dem Ende der Ausgabe.

Wie Sie den Zeilen 6 und 7 von Script 2.7 sehen, können Sie in VBScript mehrere Zeichenketten mit dem kaufmännischen Und (&) verketten.

Script 2.7: Verketten von Zeichenketten

1

2

3

4

5

6

7

Const CONVERSION_FACTOR = 1048576

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

Wscript.Echo "Es stehen " & Int(FreeMegaBytes) & _

" MB freier Festplattenplatz zur Verfügung."

Anmerkung:

  • Der Unterstrich (_) am Ende von Zeile 6 wird zum Fortsetzen einer Zeile in der nächsten Zeile verwendet. Das bedeutet für VBScript, dass es die Zeile 6 und 7 wie eine einzige Zeile behandeln soll. Die beiden Zeilen passten nur einfach nicht in eine einzige Zeile.

Alternativ können Sie den Wert "Es stehen" einer Variable mit dem Namen MessageStart und den Wert "MB freier Festplattenplatz zur Verfügung" einer Variable mit dem Namen MessageEnd zuweisen. Sie können die drei Variablen dann so verketten:

Wscript.Echo MessageStart & Int(FreeMegabytes) & MessageEnd

Wenn Sie sich die Zeilen 6 und 7 genau anschauen, dann werden Sie feststellen, dass die Zeichenketten Leerzeichen enthalten. Dies ist notwendig, da vom kaufmännischen Und keine Leerzeichen beim Verketten eingefügt werden. Nehmen wir einmal an, Sie würden die Leerzeichen weglassen:

Wscript.Echo "Es stehen" & Int(FreeMegaBytes) & "MB freier Festplattenplatz zur Verfügung."

In diesem Fall würde die Ausgabe so aussehen:

Dn151187.7C49532DE62D61124D4BB4DC5B61BBA9(de-de,TechNet.10).png

Abbildung 2.6: Falsch verkettete Zeichenketten

Bei einfacheren Verkettungen können Sie dieses Problem umgehen, indem Sie statt des kaufmännischen Und ein Komma zur Verkettung verwenden:

Wscript.Echo "Es stehen", Int(FreeMegaBytes), "MB freier Festplattenplatz zur Verfügung."

Wenn die Zeichenketten durch ein Komma verkettet werden, dann wird jeweils ein Leerzeichen eingefügt. Das Ergebnis sollte dann so wie in Abbildung 2.7 aussehen:

Dn151187.9362FCE55454D6E94871489C1581E46F(de-de,TechNet.10).png

Abbildung 2.7: Korrekt verkettete Zeichenketten

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Collections (Sammlungen)

Bis zu diesem Punkt haben die Scripte nur den freien Festplattenplatz von Laufwerk C auf einem Computer abgefragt. Hierzu wurde das Attribut DeviceID (eine Eigenschaft von der Klasse Win32_LogicalDisk) im Script hardcodiert.

Einige Computer, zum Beispiel Server, verfügen jedoch über mehrere Laufwerke. In einem solchen Fall gibt Ihnen das Script nur einen Teil der benötigten Informationen zurück, da Sie möglicherweise den freien Speicherplatz für alle Laufwerke abfragen möchten.

Hierbei gibt es jedoch ein Problem: Wie viele Laufwerke sind auf dem abgefragten Computer installiert? Theoretisch könnten Sie versuchen, den freien Speicherplatz aller Laufwerke von C bis Z abzufragen. Wenn der Computer aber zum Beispiel kein Laufwerk E verwendet, dann wird das Script fehlschlagen. Auch wenn Sie einen solchen Fehler über eine Fehlerbehandlung abfangen könnten, wäre das Script lang und schwer zu lesen und zu pflegen. Ein solches Script wäre außerdem extrem ineffizient; denn auch wenn ein Computer nur über ein einzelnes Laufwerk verfügt, würde es trotzdem versuchen, alle Laufwerke von C bis Z abzufragen.

Glücklicherweise geben Automatisationsobjekte Informationen oftmals in Form von Collections (Sammlungen) zurück. Wie Briefmarken- oder Münzsammlungen sind Automatisationssammlungen einfach eine Gruppe von Objekten. Script 2.8 verwendet zum Beispiel die WMI-Methode InstancesOf (Zeile 4), um nicht nur ein einzelnes Laufwerk zurückzugeben, sondern eine Sammlung von allen auf dem Computer installierten Laufwerken. Wenn der Computer über vier Laufwerke verfügt (C, D, E und F), dann enthält die Collection vier Einträge - einen für jedes Laufwerk.

Script 2.8: Verwendung von Collections

1

2

3

4

5

6

7

8

Const CONVERSION_FACTOR = 1048576

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

Wscript.Echo objLogicalDisk.DeviceID & " " & Int(FreeMegaBytes)

Next

Wenn Informationen als Collections zurückgegeben werden, dann bedeutet das für Sie, dass Sie nicht raten müssen, wie viele Laufwerke auf einem Computer installiert sind. Stattdessen rufen Sie einfach die Collection ab (alle auf einem Computer installierten Laufwerke). Danach können Sie eine For- Each-Schleife verwenden, um auf jedes einzelne Objekt in der Collection zuzugreifen.

For Each

Der Ausdruck For Each bietet Ihnen einen einfachen Weg, alle Objekte in einer Collection durchzugehen. Im Gegensatz zum Ausdruck For Next, der später besprochen wird, müssen Sie für For Each nicht wissen, wie viele Elemente in der Collection enthalten sind. Stattdessen beginnt For Each einfach mit dem ersten Element der Collection und geht diese durch, bis das letzte Element erreicht ist.

Eine typische For-Each-Schleife sieht so aus:

For Each objLogicalDisk In colLogicalDisk
    Wscript.Echo objLogicalDisk.DeviceID
Next

Die einzelnen Teile einer solchen Schleife werden in Tabelle 2.2 beschrieben.

Tabelle 2.2: Teile von For Each

Teil

Beschreibung

objLogicalDisk

Diese Variable repräsentiert die einzelnen in der Collection enthaltenen Laufwerke

colLogicalDisk

Diese Variable enthält die Collection

For Each objLogicalDisk in colLogicalDisk

Startet die Schleife. Bedeutet so viel wie 'mache etwas mit jedem Element der Collection'.

Wscript.Echo objLogicalDisk.DeviceID

Befehle die in der Schleife für jedes Element der Collection ausgeführt werden (in diesem Fall nur einer).

Next

Das Ende der Schleife

Bei der Arbeit mit Collections gehen Sie normalerweise die gesamte Collection durch, statt nur auf ein einzelnes Element der Collection zuzugreifen. Wenn wir zum Beispiel annehmen, dass die Collection aus den Laufwerken C, D, E, F und G besteht, und Sie möchten nur den verfügbaren Platz von Laufwerk G ausgeben, dann gehen Sie trotzdem die gesamte Collection durch. Bei jedem Durchlauf fragen Sie ab, ob das Element den Laufwerkbuchstaben G verwendet, und wenn dies der Fall ist, dann geben Sie den verfügbaren Plattenplatz für dieses Element aus.

Tipp


Es gibt keinen einfachen Weg, nicht die gesamte Collection durchgehen zu müssen. Sie können Ihre Scripte allerdings effizienter machen, indem Sie die Menge von Elementen in einer Collection einschränken. Ihre WMI-Abfrage könnte zum Beispiel nur die Instanzen der Klasse Win32_DiskDrive zurückgeben, bei denen der Laufwerksbuchstabe G ist. In diesem Fall enthält die Collection nur ein Element. Somit wird das Durchgehen der Collection schneller und effizienter.

Collections ohne Elemente

Es ist möglich, dass eine Collection keine Elemente enthält. Das folgende Bespielscript fragt zum Beispiel alle auf einem Computer installierten Bandlaufwerke ab:

Set objWMIService = GetObject("winmgmts:")
Set colTapeDrives = objWMIService.InstancesOf("Win32_TapeDrive")
For Each objTapeDrive In colTapeDrives
    Wscript.Echo objTapeDrive.Name
Next

Wenn das Script auf einem Computer ohne Bandlaufwerke ausgeführt wird, dann scheint es, als ob nichts passiert. In Wahrheit wird das Script sehr wohl ausgeführt. Da der Computer jedoch über kein Bandlaufwerk verfügt, enthält auch die Collection keine Elemente.

Wenn das Script auf einem Computer ohne Bandlaufwerke ausgeführt wird, passiert folgendes:

  1. Verbindung mit dem WMI-Dienst
  2. Abfrage der Collection mit den installierten Bandlaufwerken
  3. Einrichtung einer For Each-Schleife um die gesamte Collection durchzugehen. Für jedes Element wird der Name ausgegeben.

Da es jedoch keine Elemente in der Collection gibt, wird die For Each-Schleife kein einziges Mal ausgeführt. Stattdessen macht das Script gleich mit der Zeile nach Next weiter. In unserem Beispielscript gibt es allerdings nach Next keine Zeile mehr. Damit ist das Script zu Ende.

Es gibt keinen einfachen Weg um festzustellen, ob ein Script ausgeführt wurde. Ein Weg zur Verbesserung des Scripts wäre die Verwendung des Attributes Count. Mit diesem können Sie feststellen, wie viele Elemente eine Collection enthält. Das folgende Beispielscript verwendet das Attribut Count, um die Zahl der Bandlaufwerke des Computers zurückzugeben:

Set objWMIService = GetObject("winmgmts:")
Set colTapeDrives = objWMIService.InstancesOf("Win32_TapeDrive")
Wscript.Echo colTapeDrives.Count

Wenn Sie die Zahl der Elemente einer Collection über das Attribut Count abgefragt haben, dann können Sie die beiden folgenden Dinge durchführen:

  • Sie können die Eigenschaften der Elemente der Collection ausgeben (wenn es ein oder mehrere Elemente gibt).
  • Wenn es keine Elemente in der Collection gibt, dann können Sie eine Nachricht wie "Es gibt keine Bandlaufwerke" ausgeben.

Ein solches Script könnte wie folgt aussehen (der Ausdruck If-Then-Else wird später in diesem Kapitel besprochen):

Set objWMIService = GetObject("winmgmts:")
Set colTapeDrives = objWMIService.InstancesOf("Win32_TapeDrive")
If colTapeDrives.Count = 0 Then
    Wscript.Echo "Es gibt keine Bandlaufwerke."
Else
    For Each objTapeDrive In colTapeDrives
        Wscript.Echo objTapeDrive.Name
    Next
End If

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Schleifen

Scripte, die Systemressourcen überwachen, müssen typischerweise in bestimmten Intervallen Daten sammeln. Den freien Festplattenplatz möchten Sie zum Beispiel sicher in regelmäßigen Intervallen überwachen - zum Beispiel einmal pro Woche, einmal pro Tag oder einmal pro Stunde.

Wenn der Zeitraum zwischen den Datensammlungen relativ groß ist, können Sie das Script als geplanten Task ausführen.

Wenn Sie aber zum Beispiel alle 10 Sekunden die Prozessorauslastung messen möchten, und zwar so lange, bis Sie 500 Messungen vorgenommen haben, dann möchten Sie wohl kaum 500 Tasks planen. Stattdessen führen Sie ein einzelnes Script aus, das die 500 Messungen für Sie vornimmt.

For Next

Ein Weg, um ein Script die gleichen Aktionen mehrmals durchführen zu lassen, ist es die Aktionen (Befehl) in eine For-Next-Schleife einzuschließen.

Script 2.9 prüft zum Beispiel jede Stunde den freien Plattenplatz eines Computers - und zwar 12 Stunden lang. Hierzu wird das For-Statement aus Zeile 5 verwendet. Es besagt, dass der in der For Next-Schleife eingeschlossene Codeblock 12 Mal ausgeführt werden soll. Die Zeilen 6 bis 10 enthalten den Code, der zum Abfragen des Plattenplatzes notwendig ist, und in Zeile 11 wird das Script für eine Stunde angehalten (über eine Konstante, die das Script für 3.600.000 Millisekunden anhält). Zeile 12 markiert mit dem Next-Statement schließlich das Ende der Schleife.

Wenn das Script ausgeführt wird, dann wird als erstes eine Verbindung zum Remotecomputer atl-dc-01 aufgebaut. Das Script fragt den freien Festplattenplatz ab und hält dann für eine Stunde an. Nach der Stunde springt das Script wieder zum ersten Statement innerhalb der For Next-Schleife und arbeitet den Codeblock in der Schleife ein weiteres Mal ab. Dies geht so weiter, bis die Schleife 12 Mal durchlaufen wurde. Nach der Schleife gibt es keinen weiteren Code mehr, so dass das Script dann beendet ist.

Script 2.9: Befehle mehrfach ausführen

1

2

3

4

5

6

7

8

9

10

11

12

Const CONVERSION_FACTOR = 1048576

Const ONE_HOUR = 3600000

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

For i = 1 to 12

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

Wscript.Echo objLogicalDisk.DeviceID & " " & Int(FreeMegaBytes)

Next

Wscript.Sleep ONE_HOUR

Next

Mit dem For-Next-Statement ist es also möglich, einen bestimmen Codeblock mehrmals ausführen zu lassen. Sie sollten dies nicht mit dem For-Each-Statement verwechseln. For Each wird verwendet, um alle Elemente einer Collection zu durchlaufen. For Next wird verwendet, um einen bestimmten Codeblock mehrmals auszuführen.

Um ein For-Next-Statement zu verwenden, müssen Sie sowohl den Startpunkt als auch den Endpunkt der Schleife festlegen. Da For-Next-Schleifen typischerweise X Mal ausgeführt werden, fangen sie normalerweise mit 1 an und enden mit X. Um eine Schleife 10 Mal auszuführen, fangen Sie daher mit 1 an und enden mit 10.

Anmerkung:

  • Sie können auch einen beliebigen anderen Startpunkt auswählen (zum Beispiel 314 oder 6912 statt 1). Ihr Script wird jedoch besser lesbar und wartbar sein, wenn Sie mit 1 beginnen.

Die For-Next-Schleife benötigt eine Schleifenvariable (auch Zähler genannt). Dieser Zähler speichert, wie oft die Schleife bereits durchlaufen wurde. Im folgenden Beispiel wird zum Beispiel die Variable i als Zähler verwendet. Der Zähler beginnt bei 1 und führt den Codeblock in der For Next-Schleife aus. Nachdem alle Befehle in der Schleife ausgeführt wurden, wird der Zähler automatisch um Eins erhöht. Das bedeutet, dass i nun den Wert 2 hat. Das Script springt nun zurück zum Anfang der Schleife und prüft, ob der Wert 2 noch unterhalb der gewünschten Schleifenzahl ist. Da er das ist, wird der Code in der Schleife ein weiteres Mal ausgeführt. Der Zähler wird wieder um Eins auf 3 erhöht, usw.

For i = 1 to 5
    Wscript.Echo i
Next
Wscript.Echo "For Next-Schleife vollständig."

Was passiert, wenn i gleich 6 ist? Das Script springt zurück zum Anfang der Schleife und prüft, ob 6 noch innerhalb der gewünschten Schleifenzahl liegt. Da dies nicht der Fall ist, wird die Schleife beendet. Das Script wird mit der ersten Zeile hinter der Schleife (die Zeile unter Next) weitergeführt. In unserem Bespielscript wird nun die Nachricht "For-Next-Schleife vollständig" ausgegeben.

Die Ausgabe des Scripts sollte folgendermaßen aussehen:

1
2
3
4
5
For Next-Schleife vollständig.

Anmerkung:

  • Es gibt Fälle, in denen Sie den gleichen Befehlsblock immer wieder ausführen möchten - ohne dass Sie vorher wissen, wie oft der Block genau ausgeführt werden soll. Stellen Sie sich zum Beispiel vor, Sie möchten den freien Festplattenplatz so lange prüfen, bis dieser unter einen bestimmen Wert fällt. In solchen Situationen sollten Sie eine Do-Loop-Schleife verwenden, die später in diesem Kapitel besprochen wird.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Entscheidungen treffen

Einer der primären Gründe für den Einsatz von Scripten in der Systemadministration ist, dass sie die Notwendigkeit für einen Eingriff durch die Administratoren verringern sollen. Das bis jetzt entwickelte Script kann zwar schon eine ganze Menge, aber der Systemadministrator muss noch immer die Ausgabe des Scripts interpretieren. Er muss weiterhin selbst entscheiden, ob der Plattenplatz zu gering wird oder nicht. Das Script kann jedoch so verbessert werden, dass es nur dann eine Benachrichtigung ausgibt, wenn der Plattenplatz unter eine bestimmte Grenze fällt. Mit einem solchen Ansatz werden die Administratoren benachrichtigt, wenn der Plattenplatz zur Neige geht. Wenn sie keine Benachrichtigungen erhalten, dann ist alles in Ordnung.

VBScript bietet Ihnen einige Programmierkonstrukte, die es Scripten ermöglichen "Entscheidungen zu treffen". Das Script kann bestimmte Daten analysieren und dann auf Basis dieser Daten eine bestimmte Aktion durchführen.

Die einfachste Form eine Entscheidung ist das If-Then-Statement. Es vergleicht einen bestimmten Wert mit einen anderen Wert (zum Beispiel, ob der freie Speicherplatz kleiner als 100 MB ist). Wenn der Vergleich wahr ist (zum Beispiel, wenn nur noch 99 MB freier Platz zur Verfügung steht), dann führt das Script eine bestimmte Aktion durch. Wenn der Vergleich nicht wahr ist, dann passiert nichts.

Script 2.10 ist ein Beispiel für einen solchen Vorgang. In Zeile 8 prüft das Script ob der freie Speicherplatz kleiner als 100 MB ist (indem es den Wert mit der Konstante WARNING_THRESHOLD vergleicht). Wenn diese Bedingung wahr ist, dann wird der Befehl hinter dem If-Then-Statement ausgeführt. Diesen finden Sie in Zeile 9. Er gibt eine Nachricht aus.

Wenn die Bedingung falsch ist, dann wird Zeile 9 nicht ausgeführt. Stattdessen wird mit Zeile 10, dem Ende des If-Then-Blocks, weitergemacht.

Script 2.10:Entscheidungen treffen

1

2

3

4

5

6

7

8

9

10

11

Const CONVERSION_FACTOR = 1048576

Const WARNING_THRESHOLD = 100

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

If FreeMegaBytes < WARNING_THRESHOLD Then

Wscript.Echo objLogicalDisk.DeviceID & " hat wenig freien Speicherplatz."

End If

Next

Mehre Aktionen mit If Then Else durchführen

Script 2.10 zeigt eine Warnmeldung an, wenn der freie Festplattenplatz gering ist. Wenn dies nicht der Fall ist, dann wird auch keine Nachricht angezeigt. Für ein einfaches Überwachungsscript reicht dies sicher aus. Andererseits weiß der Benutzer bei der Scriptausführung nicht, ob er keine Meldung bekommen hat, weil der Plattenplatz ausreichen ist, oder weil das Script aus irgendeinem Grund fehlgeschlagen ist.

Besser wäre es also, im Fall von wenig verfügbarem Speicherplatz eine Warnmeldung, und in allen anderen Fällen eine "Alles Ok"-Nachricht auszugeben. Einen solchen Ansatz können Sie über das If-Then-Else-Statement umsetzen.

If-Then-Else-Statements arbeiten folgendermaßen: Wenn (If) eine Bedingung wahr ist, dann (then) führe folgende Aktion durch - Andernfalls (else) führe folgende Aktion durch.
Wenn der Plattenplatz gering ist, dann gib eine Warnmeldung aus - andernfalls gib eine "Alles Ok"-Nachricht aus.

Script 2.11 zeigt Ihnen ein Beispiel hierzu. In Zeile 8 wird der freie Plattenplatz mit einem Grenzwert (warning_threshold) verglichen. Wenn die Bedingung wahr ist (also wenn der freie Platz unter dem Grenzwert liegt), dann wird Zeile 9 ausgeführt.

Was passiert, wenn die Bedingung falsch ist? In diesem Fall wird Zeile 11 hinter dem Else-Statement ausgeführt.

Script 2.11: Verwendung des If-Then-Else-Statements

1

2

3

4

5

6

7

8

9

10

11

12

13

Const CONVERSION_FACTOR = 1048576

Const WARNING_THRESHOLD = 100

Computer = "atl-dc-01"

Set objWMIService = GetObject("winmgmts://" & Computer)

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

If FreeMegaBytes < WARNING_THRESHOLD Then

Wscript.Echo objLogicalDisk.DeviceID & " is low on disk space."

Else

Wscript.Echo objLogicalDisk.DeviceID & " has adequate disk space."

End If

Next

Es ist durchaus möglich, raffiniertere Szenarien zu konstruieren, zum Beispiel welche, in denen es mehr als zwei mögliche Aktionen gibt. Später in diesem Kapitel werden Sie noch zwei unterschiedliche Wege hierzu kennen lernen.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Arrays (Felder)

Collections sind eine hervorragende Möglichkeit Informationen zusammenzufassen, da sie es ermöglichen mit einer unbegrenzten Zahl von Elementen zu arbeiten - und zwar auch dann, wenn Sie keine Details dieser Elemente kennen. Script 2.8 ermöglicht es Ihnen zum Beispiel den freien Plattenplatz für alle installierten Festplatten eines Computers abzufragen. Sie müssen vorher nicht wissen, wie viele Festplatten installiert sind. Um die einzelnen Elemente einer solchen Collection durchzugehen, verwenden Sie eine einfache For-Each-Schleife.

Diese Collections werden von Automatisationsobjekten für Sie erstellt. Es könnte jedoch sein, dass Sie andere Informationen verarbeiten möchten (Informationen, die nicht von einem Automatisationsobjekt zur Verfügung gestellt werden), und dass Sie für diese Informationen ebenfalls eine einfache Möglichkeit zum Durchgehen von Elementen benötigen. Stellen Sie sich zum Beispiel vor, dass Sie den verfügbaren Plattenplatz auf drei Computern statt auf nur einem prüfen möchten. Sie könnten hierzu natürlich einen Scriptcode schreiben, der dies auf dem ersten Computer durchführt, den Scriptcode dann kopieren und wieder einfügen, den kopierten Code so anpassen, dass er den Plattenplatz auf dem zweiten Computer prüft, usw.

Natürlich würde ein solcher Ansatz funktionieren. Er könnte jedoch schnell sehr mühsam werden. Stellen Sie sich vor, Sie müssten statt drei Computern nun 100 Computer prüfen. Oder stellen Sie sich vor, Sie müssten Änderungen am Code vornehmen - zum Beispiel um nicht nur den freien Plattenplatz, sondern auch die Gesamtgröße des Laufwerks abzufragen. In diesem Fall müssten Sie bei 100 Computern auch 100 Änderungen am Code vornehmen. Das wäre nicht nur sehr mühsam, sondern es gäbe ich eine gute Chance, dass Sie irgendwo einen Fehler machen.

Ein besserer Ansatz wäre hier eine For-Each-Schleife, die einfach eine Collection mit Computern durchgeht und für jeden den freien Plattenplatz abfragt. Dies können Sie erreichen, indem Sie die Computernamen in einem Array speichern. Ein Array ist eine Datenstruktur, die Sie ganz ähnlich wie eine Collection verwenden können.

Script 2.12 schreibt die Namen von drei Computern (atl-dc-01, atl-dc-02 und atl-dc-03) in ein Array. Dann verwendet es eine For-Each-Schleife, um eine Verbindung mit jedem Computer aufzubauen und den freien Plattenplatz abzufragen. Das Array wird in Zeile 3 mit Hilfe der Funktion Array erstellt. Ihr werden als Parameter die drei Computernamen angehängt (da die Namen Zeichenketten sind, werden sie jeweils in Anführungszeichen eingeschlossen). In Zeile 4 werden die einzelnen Elemente des Arrays Computers mit Hilfe einer For-Each-Schleife durchlaufen.

Script 2.12: Mit einem Array arbeiten

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Const CONVERSION_FACTOR = 1048576

Const WARNING_THRESHOLD = 100

Computers = Array("atl-dc-01", "atl-dc-02", "atl-dc-03")

For Each Computer In Computers

Set objWMIService = GetObject("winmgmts://" & Computer)

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

If FreeMegaBytes < WARNING_THRESHOLD Then

Wscript.Echo Computer & " " & objLogicalDisk.DeviceID & _

" is low on disk space."

End If

Next

Next

Auch wenn Arrays einer Collection sehr ähnlich sind, so gibt es doch einen grundlegenden Unterschied. Als Scriptentwickler haben Sie über Collections sehr wenig Kontrolle. Wenn Sie eine Liste der installierten Laufwerke über WMI abrufen, dann erhalten Sie die Liste in der Reihenfolge zurück, die WMI festgelegt hat. Sie sind außerdem nicht in der Lage auf ein einzelnes Laufwerk zuzugreifen, ohne die gesamte Collection durchzugehen.

Im Gegensatz dazu können Sie die Reihenfolge der Elemente eines Arrays bestimmten - denn Sie sind normalerweise derjenige, der den Array mit Elementen füllt. Außerdem haben Sie die Möglichkeit auf einzelne Elemente eines Arrays zuzugreifen, ohne das gesamte Array durchlaufen zu müssen. Das liegt daran, dass jedem Element eines Arrays eine Indexnummer zugewiesen wird. Unter VBScript hat das erste Element eines Arrays immer die Indexnummer 0 - die nachfolgenden Elemente erhalten fortlaufende Indexnummern (1, 2, 3 usw.). Der Array aus Script 2.12 enthält nach diesen Regeln also die in Tabelle 2.3 gezeigten Elemente und Indexnummern. Sie sollten sich merken, dass die höchste Indexnummer eines Arrays immer der Gesamtzahl von Elementen minus eins entspricht.

Tabelle 2.3: Indexnummern in einem Array

Indexnummer

Element

0

atl-dc-01

1

atl-dc-02

2

atl-dc-03

Sie können die Indexnummern verwenden, um auf die einzelnen Elemente eines Arrays zuzugreifen. Die folgende Codezeile gibt zum Beispiel den Text atl-dc-02 aus - der Wert von Element 1 (genauer: das Element mit der Indexnummer 1) im Array:

Wscript.Echo Computers(1)

Um den Wert eines anderen Elementes auszugeben, ersetzten Sie den Wert 1 einfach durch die entsprechende Indexnummer.

Später in diesem Kapitel werden noch weitere Verfahren zum Erstellen von Arrays und dem Zugriff auf einzelne Array-Elemente besprochen.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Eingabe

Script 2.12 wurde für eine Organisation entwickelt, in der sich die Computer-Infrastruktur wahrscheinlich nicht ändern wird. Es muss wohl kaum erwähnt werden, dass eine solche statische Infrastruktur eher die Ausnahmen als die Regel darstellt. In den meisten Organisationen gibt es eine viel dynamischere Umgebung. Auch wenn heute nur drei Server überwacht werden müssen (atl-dc-01, atl-dc-02, atl-dc-03), so gibt es doch keine Garantie dafür, dass sich dies nicht in Zukunft ändert.

Aus diesem Grund möchten wir die Computernamen nicht fest in das Script integrieren (hardcodieren). Eine solche Vorgehensweise führt oft zu Problemen:

  • Fehlende Flexibilität - Script 2.12 fragt nur die Computer atl-dc-01, atl-dc-02 und atl-dc-03 ab. Wenn Sie den freien Plattenplatz von Computer atl-dc-04 abfragen möchten, dann müssen Sie das Script verändern.
  • Regelmäßige Änderungen - Script 2.12 wurde entwickelt, um eine bestimmte Gruppe von Computern abzufragen (zum Beispiel alle Domänencontroller an einem bestimmten Standort). Jedes Mal, wenn ein neuer Domänencontroller hinzugefügt wird, muss das Script geändert werden. Wenn in Ihrer Organisation nur dieses eine Script verwendet wird, ist das sicher kein allzu großes Problem. Wenn Sie jedoch Dutzende von Scripten verwenden, dann verbringen Sie möglicherweise mehr Zeit mit der Pflege von Scripten, als Sie durch die Scripte einsparen.

Es gibt einige Arten, auf die Sie Informationen (zum Beispiel Computernamen) an ein Script übergeben können (weitere Informationen hierzu finden Sie im Kapitel Creating Enterprise Scripts in Teil 3 dieses Buchs). Der wahrscheinlich einfachste Weg ist es, den Benutzer beim Aufruf des Scripts Parameter (auch Argumente genannt) angeben zu lassen.

Ein Argument ist eine Information, die zusammen mit dem Befehl, über den das Script gestartet wird, angegeben wird. Nehmen wir einmal an, Sie starten ein Script normalerweise, indem Sie folgenden Befehl in der Eingabeaufforderung eingeben:

cscript FreeDiskSpace.vbs

Argumente sind alle Informationen, die Sie noch an diesen Befehl anhängen. Ein Befehl mit drei Argumenten (ein Computername ist jeweils ein Argument) sieht zum Beispiel so aus:

cscript FreeDiskSpace.vbs atl-dc-01 atl-dc-02 atl-dc-03

Sie müssen Ihrem Script natürlich auch Code hinzufügen, der diese Argumente verarbeitet. Im Kapitel Der WSH wird dies sehr detailliert besprochen - in Script 2.13 sehen Sie daher nur ein einfaches Beispiel. In Zeile 9 dieses Scripts wird eine For-Each-Schleife verwendet, um die vom Benutzer beim Start des Scripts angegebenen Argumente durchzugehen. Die einzelnen Argumente werden jeweils der Variable Computer zugewiesen. Mit Hilfe dieser Variable wird dann in Zeile 10 eine Verbindung zum WMI-Dienst dieses Computers aufgebaut.

Script 2.13: Eingaben des Benutzers verarbeiten

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Const CONVERSION_FACTOR = 1048576

Const WARNING_THRESHOLD = 100

If WScript.Arguments.Count = 0 Then

Wscript.Echo "Usage: FirstScript.vbs server1 [server2] [server3] ..."

WScript.Quit

End If

For Each Computer In WScript.Arguments

Set objWMIService = GetObject("winmgmts://" & Computer)

Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

If FreeMegaBytes < WARNING_THRESHOLD Then

Wscript.Echo Computer & " " & objLogicalDisk.DeviceID & _

" is low on disk space."

End If

Next

Next

Ein Vorteil von Befehlszeilenargumenten ist, dass sie automatisch über eine Collection bereitgestellt werden (Wscript.Arguments). So ist es einfach, die Argumente über eine For-Each-Schleife durchzugehen - denn dieser Vorgang unterscheidet sich nicht von der Auflistung aller Laufwerke eines Computers.

Dank der Collection ist es auch ganz einfach festzustellen, wie viele Argumente angegeben wurden - wenn überhaupt welche angegeben wurden. Hierzu wird in Zeile 4 des Scripts das Attribut Wscript.Arguments.Count verwendet. In ihm steht die Zahl der bei Scriptstart übergebenen Argumente. Wenn Wscript.Arguments.Count den Wert 0 hat, dann wurden keine Argumente übergeben. In diesem Fall wird in 2.13 einfach ein Text ausgegeben, der die möglichen Argumente des Scripts anzeigt. Danach wird das Script mit dem Befehl WScript.Quit beendet.).

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Fehlerbehandlung

Script 2.13 enthält einen potentiellen Fehler. Nehmen wird einmal an, der Benutzer gibt einen ungültigen Computernamen als Argument an. Wenn das Script dann versucht eine Verbindung mit diesem Computer aufzubauen, wird dies mit der Fehlermeldung "Der Remoteservercomputer existiert nicht oder ist nicht verfügbar: ,GetObjekt'" abgebrochen.

Solche Fehler sind natürlich in allen bis jetzt in diesem Kapitel vorgestellten Scripten möglich - auch wenn die Computernamen fest eingetragen (hardcodiert) wurden. Schließlich kann ein Script nicht zwischen einem ungültigen Computernamen und einem gültigen Computernamen, der nur im Moment nicht über das Netzwerk erreichbar ist, unterscheiden. Stellen Sie sich zum Beispiel vor, Computer atl-dc-01 aus Script 2.12 ist im Moment nicht erreichbar. In diesem Fall wird das Script bei der Abfrage dieses Computers mit einer Fehlermeldung abbrechen. Leider werden auch die beiden anderen Computer nicht mehr abgefragt - selbst wenn diese einwandfrei zu erreichen sind (das Script wird ja schon beim ersten Computer wegen des Fehlers beendet).

Das beschriebene Verhalten ist ein gutes Beispiel für einen Laufzeitfehler - ein Fehler, der erst nach dem Start des Scripts auftritt (im Gegensatz zu einem Syntaxfehler - zum Beispiel einem falsch geschriebenen Befehl, der bereits vor der Ausführung der ersten Scriptzeile auftritt). Um sich vor solchen Laufzeitfehlern zu schützen, können Sie den VBScript-Befehl zur Fehlerbehandlung On Error Resume Next in Ihren Scripten verwenden.

Ohne eine Fehlerbehandlung wird das Script bei einem Laufzeitfehler sofort angehalten. Mit Fehlerbehandlung wird das Script nicht angehalten. Stattdessen wird versucht, einfach die nächste Zeile des Scripts auszuführen. Die Scriptzeile, die den Fehler generiert hat, wird einfach ignoriert.

Das Err-Objekt

Der Befehl On Error Resume Next bewirkt, dass das Script nach einem Laufzeitfehler weiter ausgeführt wird. Hierbei gibt es jedoch mindestens zwei potentielle Probleme. Ersten wird keine Fehlermeldung angezeigt. Sie merken also nicht, dass ein Fehler aufgetreten ist und können nicht feststellen, ob das Script fehlgeschlagen ist.

Und zweitens könnte es ja sein, dass Sie nicht möchten, dass das Script nach einem Fehler weiter ausgeführt wird. Stellen Sie sich folgende Script-Funktionalität vor, die den Befehl On Error Resume Next verwendet:

  1. Eine Verbindung zu einem Remotecomputer herstellen.
  2. Dateien vom lokalen Computer auf den Remotecomputer kopieren.
  3. Die Originaldateien vom lokalen Computer löschen.

Stellen Sie sich nun vor, Sie starten das Script, und der Remotecomputer ist nicht erreichbar. Folgendes würde passieren:

  1. Das Script versucht eine Verbindung zum Remotecomputer herzustellen. Dies schlägt fehl. On Error Resume Next stellt jedoch sicher, dass das Script weiter ausgeführt wird.
  2. Das Script versucht, Dateien auf den Remotecomputer zu kopieren. Dies schlägt natürlich ebenfalls fehl. Auch hier stellt On Error Resume Next sicher, dass das Script weiter ausgeführt wird.
  3. Das Script löschte die Dateien vom lokalen Computer. Unglücklicherweise wird das sauber ausgeführt. Der lokale Computer steht ja zur Verfügung. Als Ergebnis sind die Dateien vom lokalen Computer gelöscht und nicht auf den Remotecomputer kopiert.

Glücklicherweise können Sie das VBScript-Objekt Err verwenden, um festzustellen, ob ein Fehler aufgetreten ist. Danach können Sie die erforderlichen Maßnahmen ergreifen.

Das Err-Objekt wird automatisch erstellt, sobald Sie das Script starten (solche immer verfügbaren Objekte werden auch Intrinsic-Objekte genannt). Es stellt mehrere Attribute zur Verfügung. Drei von ihnen sehen Sie in Tabelle 2.4. Wenn ein Laufzeitfehler auftritt, werden diese Attribute automatisch mit Werten gefüllt. Diese Werte zeigen Ihnen, was für ein Fehler aufgetreten ist.

Tabelle 2.4: Attribute des Err-Objektes

Attribut

Beschreibung

Description

Eine Beschreibung des Fehlers. Sie kann dazu verwendet werden, den Benutzer über den Fehler zu informieren. Geben Sie das Attribut einfach auf dem Bildschirm aus:

Wscript.Echo Err.Description

Number

Ein Integer-Wert (Ganzzahl), der den aufgetretenen Fehler eindeutig identifiziert. Es kann sich um eine VBScript-Fehlernummer oder um die Fehlernummer eines Automatisationsobjektes handeln. Die Herkunft der Fehlernummer können Sie über das Attribut Source feststellen.

Source

Klassenname oder ProgID (Programmatic Identifier) des Objektes, das den Fehler verursacht hat. Wenn VBScript den Fehler verursacht hat, dann enthält das Attribut den Wert 'Laufzeitfehler in Microsoft VBScript'. Wenn ein Automatisationsobjekt den Fehler verursacht hat, dann finden Sie hier die ProgID dieses Objektes (zum Beispiel 'Word.Application').

Wenn ein Script gestartet wird, dann weist VBScript dem Attribut Number den Standardwert 0 zu. Wenn ein Fehler auftritt, dann wir dem Attribut sofort die Fehlernummer zugewiesen. Wenn Sie also den Wert des Attributes Number regelmäßig abfragen, dann können Sie feststellen, ob ein Fehler aufgetreten ist. Sie können Ihr Script zum Beispiel so gestalten, dass es nach einem Verbindungsversuch mit einem Remotecomputer den Fehlerstatus im Attribut Number prüft. Wenn Err.Number nicht mit 0 ist, dann ist irgendein Fehler aufgetreten - und Sie können davon ausgehen, dass der Verbindungsversuch mit dem Remotecomputer fehlgeschlagen ist. Ihr Script kann dann hierauf reagieren.

Script 2.14 implementiert eine solche Fehlerbehandlung. In Zeile 1 wird die Fehlerbehandlung erst einmal durch On Error Resume Next aktiviert. In Zeile 10 wird eine For-Each-Schleife verwendet, um die Servernamen durchzugehen. In Zeile 11 versucht das Script jeweils eine Verbindung mit dem Server aufzubauen.

Was passiert nun, wenn einer der Server nicht erreichbar ist? In Zeile 11 versucht das Script auf den Server zuzugreifen. Wenn die Verbindung erfolgreich war, dann wird kein Fehler generiert. In diesem Fall steht in Err.Number noch immer der Wert 0. Wenn der Verbindungsversuch jedoch fehlschlägt, dann wird ein Fehler generiert. In Err.Number steht dann eine Fehlernummer.

In einem solchen Fall steht der Befehl On Error Resume Next sicher, dass das Script in der nächsten Zeile weiter ausgeführt wird. In Zeile 12 prüft das Script den Wert in Err.Number. Wenn dieser Wert nicht 0 ist (wenn also ein Fehler aufgetreten ist), dann gibt das Script den Wert in Err.Description aus. Danach geht es mit einem neuen Schleifendurchlauf normal weiter. Wenn der Wert in Err.Number jedoch 0 ist, dann bedeutet das, dass die Verbindung erfolgreich war. In diesem Fall fragt das Script den verfügbaren Plattenplatz ab und startet dann ganz normal einen weiteren Schleifendurchlauf mit dem nächsten Servernamen.

Script 2.14: Fehler abfangen

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

On Error Resume Next

Const CONVERSION_FACTOR = 1048576

Const WARNING_THRESHOLD = 100

If WScript.Arguments.Count = 0 Then

Wscript.Echo "Usage: FirstScript.vbs server1 [server2] [server3] ..."

WScript.Quit

End If

For Each Computer In WScript.Arguments

Set objWMIService = GetObject("winmgmts://" & Computer)

If Err.Number <> 0 Then

Wscript.Echo Computer & " " & Err.Description

Err.Clear

Else

Set colLogicalDisk = _

objWMIService.InstancesOf("Win32_LogicalDisk")

For Each objLogicalDisk In colLogicalDisk

FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR

If FreeMegaBytes < WARNING_THRESHOLD Then

Wscript.Echo Computer & " " & objLogicalDisk.DeviceID & _

" is low on disk space."

End If

Next

End If

Next

Wenn Sie Script 2.14 ausführen, und einer der Server nicht erreichbar ist, dann enthalten die Attribute des Err-Objektes die in Tabelle 2.5 zu sehenden Werte.

Tabelle 2.5: Werte der Attribute des Err-Objektes

Attribut

Wert

Err.Description

Der Remoteservercomputer existiert nicht oder ist nicht verfügbar: ,GetObjekt'

Err.Number

462

Err.Source

Laufzeitfehler in Microsoft VBScript

Fehler löschen

Script 2.14 verwendet in Zeile 14 die Methode Clear, um die Attribute des Err-Objektes explizit zurückzusetzen. Dies ist wichtig, da sich diese Attribute ansonsten nur dann ändern würden, wenn ein anderer Fehler auftritt. Wenn kein Fehler auftritt, dann würden die Werte der Attribute gleich bleiben. Das Script würde also bei jedem Durchlauf einen Fehler erkennen - auch dann, wenn gar kein Fehler aufgetreten ist (der Wert des Attributes Err.Number ist ja nicht 0).

Mit der Methode Clear umgehen Sie dieses Problem, indem Sie alle Attribute des Err-Objektes auf die Standardwertezurücksetzen (Number ist 0, Source und Description sind leer).

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

VBScript-Referenz

Die erste Hälfte dieses Kapitels hat Sie mit den grundlegenden Konzepten hinter VBScript vertraut gemacht. Sie haben einen ersten Einblick darin erhalten, welche Aufgaben Sie mit VBScript durchführen können - besonders im Hinblick auf die Verwendung von ADSI und WMI. Die zweite Hälfte dieses Kapitels ist mehr als Standardreferenz gedacht. Es konzentriert sich auf die Methoden und Funktionen von VBScript, die für Systemadministratoren am nützlichsten sind. Es handelt sich nicht um eine umfassende Übersicht aller Dinge, die Sie mit VBScript machen können. Die folgenden Abschnitte besprechen nur eine Untermenge aller VBSCript-Funktionen und -Methoden. Diese werden in einem Kontext verwendet, der Sie bei der Entwicklung von Scripten zur Systemadministration unterstützen soll.

Zeilenumbrüche in VBScript

Viele Script- und Programmiersprachen interessieren sich nicht dafür, ob der Code in eine physikalische Zeile oder in viele Zeilen geschrieben wurde. Das folgende Microsoft® JScript®- Codebeispiel umfasst beispielsweise zwar neun Zeilen - JScript behandelt es aber trotzdem wie eine einzige Zeile (und damit auch wie einen einzigen Befehl). Das liegt daran, dass JScript ein Zeilenende an einem bestimmten Zeichen erkennt (dem Semikolon). Die tatsächlichen Zeilen (also die Zeilenumbrüche) sind für JScript vollkommen irrelevant.

var 
objWMI 
= 
new 
Enumerator 
(GetObject("winmgmts:") 
. 
InstancesOf("Win32_process")) 
; 

Ein Ähnliches Stück Code in VBScript wird dagegen zu einem Syntax-Error führen:

Set 
objWMI 
= 
(GetObject("winmgmts:") 
. 
InstancesOf("Win32_process")) 

Das liegt daran, dass VBScript das Zeilenende (und damit normalerweise auch das Ende eines Befehls) am Zeilenumbruch statt an einem bestimmten Zeichen erkennt.

Im Allgemeinen ist dies ein Vorteil von VBScript. Es kann zum Beispiel nicht passieren, dass Sie vergessen das Zeilenendezeichen (das Semikolon) einzugeben. Ein Problem gibt es aber trotzdem: Um die Lesbarkeit Ihrer Scripte zu verbessern, sollten Sie keine Zeilen verwenden, die länger als max. 80 Zeichen sind (in einigen Texteditoren können Sie möglicherweise gar nicht mehr als 80 Zeichen in einer Zeile eingeben). Was machen wir also, wenn eine Zeile 100 Zeichen enthalten muss?

Auch wenn es nahe liegend erscheint: Sie können die Zeile nicht einfach durch einen Zielenumbruch in zwei Zeilen aufteilen. Das folgende Codestück würde unter VBScript zum Bespiel zu einem Fehler führen, da die erste Befehlszeile durch einen Zeilenumbruch in zwei einzelne Zeile aufgeteilt wurde (Zeile 1 und 2):

strMessageToDisplay = strUserFirstName, strUserMiddleInitial, strUserLastName, 
strCurrentStatus 
Wscript.Echo strMessageToDisplay 

In diesem Fall würde nun jede der beiden Zeilen als einzelner Befehl interpretiert. Die erste Zeile mag ja auch noch immer einen gültigen Befehl enthalten (eine Zuweisung zu einer Variable). Die zweite Zeile jedoch ist kein gültiger Befehl mehr.

Um einen Befehl über mehrere Zeile fortzusetzen, müssen Sie statt des Zeilenumbruchs den Unterstrich verwenden (_).

strMessageToDisplay = strUserFirstName, strUserMiddleInitial, strUserLastName, _ 
    strCurrentStatus 
Wscript.Echo strMessageToDisplay

Das Leerzeichen und der Unterstrich am Ende von Zeile 1 bedeuten für VBScript, dass der Befehl in der nächsten Zeile fortgesetzt wird. Um dies auch für den Leser zu verdeutlichen, wurde Zeile zwei um vier Zeichen eingerückt.

Wenn Sie versuchen eine Befehlszeile mit Zeichenketten (die in Anführungsstriche eingefasst sind) zu trennen, dann wird dies noch etwas komplexer. Stellen Sie sich zum Beispiel vor, sie teilen eine WMI-Abfrage folgendermaßen durch einen Unterstrich in zwei Zeilen auf:

Set colServiceList = GetObject("winmgmts:").ExecQuery("SELECT * FROM  _ 
    Win32_Service WHERE State = 'Stopped' AND StartMode = 'Auto' ") 

Wenn sie das Script so ausführen, dann erhalten Sie wieder einen Laufzeitfehler. Das liegt daran, dass Sie die Befehlszeile innerhalb einer Zeichenkette getrennt haben, die in Anführungsstrichen eingeschlossen war (und der trennende Unterstrich daher nur als Teil der Zeichenkette statt als Trennzeichen behandelt wird). Um eine solche Befehlszeile zu trennen gehen Sie folgendermaßen vor:

  1. Beenden Sie die erste Zeile mit einem Anführungszeichen. Hängen Sie dann das Leerzeichen und den Unterstrich dahinter.
  2. Beginnen Sie die zweite Zeile mit einem kaufmännischen "Und" (&). Dies zeigt VBScript, dass hier die unterbrochene Zeichenkette aus Zeile 1 fortgesetzt wird.
  3. Beginnen sie die fortgesetzte Befehlszeile mit einem weiteren Anführungszeichen.
  4. Das "&" und die Anführungsstriche zeigen VBScript, dass die in Zeile 1 begonnene Zeichenkette mit der folgenden Zeichenkette fortgesetzt werden soll.

Die korrekte Befehlszeile muss also so aussehen:

Set colServiceList = GetObject("winmgmts:").ExecQuery("SELECT * FROM " _ 
    & "Win32_Service WHERE State = 'Stopped' AND StartMode = 'Auto' ") 

Wenn Sie Befehlszeilen auf diese Art teilen, dann sollten Sie aufpassen, wo Sie die Leerzeichen setzen. Im gezeigten Beispiel wurde zum Beispiel ein Leerzeichen hinter dem Wort 'FROM' und vor dem schließenden Anführungszeichen eingefügt. Wenn dieses Leerzeichen nicht vorhanden wäre, dann würde die Zeichenkette so aussehen:

" SELECT * FROMWin32_Service WHERE State = 'Stopped' AND StartMode = 'Auto' "

Natürlich würde dies zu einem Fehler führen, "FROMWIn32"kann nicht richtig sein.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Arbeiten mit Variablen

Variablen sind benannte Speicherstellen im Speicher des Computers. Die meisten Scriptsprachen erlauben eine implizite Deklaration von Variablen. Sie können Variablen also verwenden, ohne deren vorgesehene Nutzung zu deklarieren. Sie können das folgende Script zum Beispiel ausführen, ohne dass es zu einem Fehler kommt, und das, obwohl in der ersten Zeile des Scripts der Wert 11 zur Variable sngDegreesCelsius zugewiesen wird und die Variable vorher nicht deklariert wurde (VBScript weiß also vorher nichts von deren Existenz).

sngDegreesCelsius = 11
sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius)
Wscript.Echo sngDegreesFahrenheit
Function ConvertToFahrenheit(ByVal sngDegreesCelsius)
    ConvertToFahrenheit = (sngDegreesCelsius * (9/5)) + 32
End Function

Durch eine implizite Variablendeklaration kann das Entwickeln von Scripten schneller und einfacher werden. Sie kann jedoch auch zu sehr subtilen Fehlern führen, die schwer zu finden und zu beheben sind.

Das folgende Script illustriert solche Probleme. Das vorherige Script konvertierte 11° Celsius in Fahrenheit (51.8°). Das folgende Script macht genau das gleiche. Leider gibt es 32 statt 51.8 zurück.

sngDegreesCelsius = 11
sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius)
Wscript.Echo sngDegreesFahrenheit
Function ConvertToFahrenheit(ByVal sngDegreesCelsius)
    ConvertToFahrenheit = (sngDegresCelsius * (9/5)) + 32
End Function

Warum gibt das Script einen falschen Wert zurück? Das Problem liegt in einem einfachen Tippfehler. In Zeile 6 sollte die Variable sngDegreesCelsius verwendet werden. Stattdessen hat der Entwickler jedoch sngDegresCelsius (ein e fehlt im Wort Degrees). Das führt dazu, dass die Berechnung den Wert in der Variable sngDegresCelsius statt jenem in sngDegreesCelsius verwendet. Da der Variablen sngDegresCelsius nie ein Wert zugewiesen wurde, enthält sie den Standardwert 0. Als Konsequenz wird der Wert 0 mit 9/5 multipliziert - das Ergebnis ist 0. Das Script addiert dann 32 zu diesem Wert und gibt das falsche Endergebnis 32 zurück.

Solche Fehler können wirklich schwer zu finden sein. Der Syntax ist korrekt, daher wird keine Fehlermeldung generiert. Sie erwarten einen numerischen Wert, und Sie erhalten auch einen. In einem größeren Script könnte die Suche nach einem Tippfehler sehr lange dauern.

Variablen unter VBScript deklarieren

Um Probleme wie das oben demonstrierte zu vermeiden, können Sie alle Variablen explizit deklarieren. In diesem Fall führen alle nicht deklarierten Variablen zu einem Laufzeitfehler.

In dem folgenden Script wird zum Beispiel über den Befehl Option Explicit eine explizite Variablendeklaration erzwungen und jede Variable wird über den Befehl Dim deklariert:

Option Explicit
Dim sngDegreesCelsius
Dim sngDegreesFahrenehit
sngDegreesCelsius = 11
sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius)
Wscript.Echo sngDegreesFahrenheit
Function ConvertToFahrenheit(ByVal sngDegreesCelsius)
    ConvertToFahrenheit = (sngDegresCelsius * (9/5)) + 32
End Function

Wenn das Script ausgeführt wird, findet der Scripting-Host eine undeklarierte Variable. Daher wird die Ausführung des Scripts angehalten, und es wird ein Fehlermeldung wie die folgende angezeigt:

C:\Scripts\TempConvert.vbs(10, 5) Laufzeitfehler in Microsoft VBScript: Variable ist nicht 
definiert: 'sngDegresCelsius'

Um in VBScript Variablen zu deklarieren, gehen Sie folgendermaßen vor:

  1. Verwenden Sie den Befehl Option Explicit, um die Deklaration von Variablen zu erzwingen. Der Befehl muss in der ersten Zeile Ihres Scripts stehen.

  2. Verwenden Sie den Befehl Dimzur Deklaration von Variablen. Auch wenn Sie mit einem Dim-Befehl mehrere Variablen deklarieren können, sollten Sie sich doch auf eine Variable pro Dim-Befehl beschränken. Dies ermöglicht es Ihnen, einen Kommentar hinter der Deklaration einzufügen, indem Sie die Verwendung der Variable beschreiben können. Das Ergebnis könnte so aussehen:

    Option Explicit

    Dim intFirstNumber ' First number in our simple equation

    Dim intSecondNumber ' Second number in our simple equation

    Dim intTotal ' Sum of intFirstNumber and intSecondNumber

Initialisierung von Variablen

Initialisieren von Variablen bedeutet ganz einfach, dass Sie den Variablen schon zu Beginn einen Wert zuweisen. Die folgenden beiden Codezeilen initialisieren zum Beispiel zwei Variablen. X wird der Wert 100 zugewiesen und Y der Wert abcde:

X = 100
Y = 'abcde'

Wenn Sie Variablen deklarieren, diese aber nicht initialisieren (ihnen also keinen Wert zuweisen), dann hat die Variable einen von zwei Standardwerten:

  • Wenn die Variable als Zeichenkette (String) verwendet wird, dann hat sie den Wert Leer (Empty).
  • Wenn die Variable als Zahl verwendet wird, dann hat Sie den Wert 0.

Das folgende Script deklariert zum Beispiel zwei Variablen (X und Y), weist diesen jedoch keinen Wert zu:

Dim X
Dim Y
Wscript.Echo X & Y
Wscript.Echo X + Y

In Zeile 3 werden die beiden Variablen als Zeichenketten verwendet (der Operator "&" verbindet zwei Zeichenketten zu einer). Das Ergebnis dieser Zeile sehen Sie in Abbildung 2.8. Da beide Variablen leer sind, ist auch die Kombination aus beiden leer. Das Fenster zeigt also eine leere Zeichenkette an.

Dn151187.9880977F66440CB32F2FC668CA77499B(de-de,TechNet.10).png

Abbildung 2.8: Verbinden zweier nicht initialisierter Variablen

In Zeile 4 werden die beiden Variablen als Zahlen verwendet. Numerische Variablen, die nicht initialisiert wurden, haben automatisch den Wert 0. Daher gibt diese Zeile des Scripts auch die Summe aus 0 + 0 zurück.

Dn151187.509253CA8693F49068AC5D9002E70AD2(de-de,TechNet.10).png

Abbildung 2.9: Addition zweier nicht initialisierter Variablen

Verwendung des Gleichheitszeichens in VBScript

In VBScript hat das Gleichheitszeichen (=) unterschiedliche Bedeutungen. Normalerweise wird der Ausdruck X = 2 + 2 so gelesen:

'X gleich 2 plus 2.'

In VBScript wird er allerdings so gelesen:

'X wird der Wert von 2 plus 2 zugewiesen.'

Anscheinend gibt es keinen großen Unterschied. In beiden Fällen wird X der Wert 4 zugewiesen. Sehen Sie sich jedoch einmal folgendes Script an. Es zählt in einer Schleife von 1 bis 10:

For i = 1 to 10
    X = X + 1
Next

Die zweite Zeile des Scripts scheint mathematisch unmöglich. Wie kann X gleich X plus 1 sein? Unter VBScript ist dies jedoch ein gültiger Ausdruck. Es handelt sich nicht um eine mathematische Berechnung. Stattdessen wird einfach nur der Variable X ein neuer Wert zugewiesen. Der Ausdruck liest sich also so:

'X wird der momentane Wert von X plus 1 zugewiesen.'

In anderen Worten, wenn X im Moment 3 ist, denn wird X mit diesem Ausdruck der neue Wert 4 zugewiesen - 3 (der momentane Wert von X) plus 1.

Das Gleichheitszeichen ist also tatsächlich ein Zuweisungszeichen. Sie können es auch zum Erstellen von Zeichenketten verwenden. Das folgende Script konstruiert zum Beispiel eine Meldung aus mehreren Zeichenketten:

Message = "Dies "
Message = Message & "ist eine "
Message = Message & "Testmeldung."
Wscript.Echo Message

Die Ausgabe des Scripts sehen Sie in Abbildung 2.10.

Dn151187.3E4EF703E95AA912206821DB39936FCF(de-de,TechNet.10).png

Abbildung 2.10: Zusammengefasste Meldung

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Verwendung von Konstanten

Konstanten sind Werte, die während der Laufzeit eines Scripts nicht geändert werden können. Nehmen Sie zum Beispiel an, dass eines Ihrer Scripte US-Dollar in Euro konvertiert. Wenn wir davon ausgehen, dass der Wechselkurs für einen Dollar 0,84 Euro beträgt, dann können Sie diesen Wert fest in Ihr Script implementieren (hardcodieren):

curConvertedPrice = curPriceInEuro * 0.84

Auch wenn dieser Ansatz funktioniert gibt es doch einige potentielle Probleme:

  • Ein anderer Script-Entwickler weiß möglicherweise nicht, wofür der Wert 0.84 steht.
  • Wechselkurse ändern sich regelmäßig. Wenn Sie den Wert direkt in Ihr Script eintragen, dann müssen Sie bei einer Änderung das ganze Script durchsuchen und an jeder Stelle den Wert ändern. Wenn Sie auch nur eine Stelle übersehen, an der der Wert verwendet wird, dann kann dies zu falschen Berechnungen führen.
  • Jedes Mal, wenn Sie den Wert per Hand im Script eingeben oder ändern, dann besteht die Gefahr von Tippfehlern. Wenn Sie zum Beispiel versehentlich 0.084 eingehen, dann wird das drastische Auswirkungen auf die Berechnung haben.

Um solche Probleme zu vermeiden, sollten Sie statt hardcodierter Werte Konstanten verwenden. Diese bieten Ihnen einige Vorteile:

  • Sie können einer Konstante einen eindeutigen Namen geben. Statt der Zahl 0.84 können Sie so zum Beispiel den Namen US_DOLLAR_IN_EURO_WECHSELKURS verwenden.
  • Sie sind einfach zu ändern. Wenn sich der Wechselkurs ändert, dann ändern Sie nur die Stelle, an der die Konstante definiert wird.
  • Da Sie den Wert nur einmal eingeben müssen, sind sie weniger anfällig für Tippfehler.
  • Sie können nicht versehentlich geändert werden. Nachdem eine Konstante definiert wurde, führt jeder Versuch im Script den Wert der Konstante zu ändern, zu einem Fehler.
  • Sie können für Zeichenketten und für Zahlenwerte verwendet werden.

Definieren von Konstanten

Unter VBScript werden Konstanten mit dem Schlüsselwort Const gefolgt von dem Namen und dem Wert der Konstante, definiert. Sie müssen der Konstante bei deren Definition einen Wert zuweisen; es ist nicht möglich, der Konstante über eine Variable, eine andere Konstante oder über eine Funktion einen Wert zuzuweisen. Das folgende Beispiel versucht, eine Konstante mit der Variable NumberOfDepartments zu definieren und verursacht den Fehler "Literalkonstante erwartet":

NumberOfDepartments = 20
Const NUMBER_OF_DEPARTMENTS = NumberOfDepartments

Der Konstante muss stattdessen der Wert 20 zugewiesen werden:

Const NUMBER_OF_DEPARTMENTS = 20

Vordefinierte Konstanten verwenden

VBScript umfasst bereits einige vordefinierte Konstanten. Diese können Sie zum Beispiel für Nachrichtenfenster, Ausgaben oder andere Aktivitäten verwenden. Das folgende Script zeigt zum Beispiel ein Nachrichtenfenster an. Die im Nachrichtenfenster angezeigten Schalter werden hierbei durch einen numerischen Wert festgelegt. Auch wenn das Script problemlos funktioniert, ist es doch schwer festzustellen, was genau das Script macht. Sie müssen wissen, dass die Zahl 260 bedeutet, dass ein Nachrichtenfenster mit den Schaltern Ja und Nein erstellt werden soll, bei dem der Schalter Nein standardmäßig den Focus hat. Die Zahl 7 bedeutet, dass der Benutzer auf den Schalter Nein geklickt hat.

ConfirmDelete = MsgBox ("Möchten Sie die Dateien löschen? ",  _
    260, "Alle Dateien löschen")
If ConfirmDelete = 7 then
    Wscript.Quit
End If

Die folgende Variante des Scripts verwendet statt Zahlen die vordefinierten Konstanten von VBScript (VbYesNo, VBDefaultButton2 und VbNo). Das Script wird so besser lesbar und verständlicher.

ConfirmDelete = MsgBox ("Möchten Sie die Dateien löschen? ",  _
    VbYesNo OR VBDefaultButton2, "Alle Dateien löschen")
If ConfirmDelete = VbNo then
    Wscript.Quit
End If

Mit Konstanten wird es außerdem einfacher das Script in einer anderen Programmiersprache umzusetzen. VBScript verwendet für die Konstante True zum Beispiel den Wert -1; in Visual Basic hat True aber den Wert 1. Wenn Sie eine Konstante statt des Wertes verwendet haben, dann müssen Sie sich über dieses Problem keine Sorgen machen, wenn Sie das Script übertragen sollten.

Die zwei am häufigsten verwendeten vordefinierten Konstanten sind wahrscheinlich:

  • VbCrLf - Diese Konstante steht für einen Zeilenumbruch. Sie wird meist zur Formatierung von Ausgaben verwendet. Das folgende Script produziert zum Beispiel einen mehrzeiligen Nachrichtentext:

    Wscript.Echo 'Erste Textzeile.' & VbCrLF & VbCrLF & _

    'Zweite Textzeile.'

    Wenn Sie das Script mit Wscript ausführen, dann sehen Sie ein Nachrichtenfenster, das wie in Abbildung 2.11 aussieht.

    Dn151187.E9B2F9B69E6E7B4B6369C428D8E9F911(de-de,TechNet.10).png

    Abbildung 2.11: Mit VbCrLf getrennter Text

  • VbTab - Diese Konstante entspricht einem Tabulatorzeichen. Das folgende Script produziert zum Beispiel drei durch Tabulatoren getrennte Textspalten:

    Wscript.Echo ' 1' & VbTab & ' 2' & VbTab & ' 3'

    Wscript.Echo 'A' & VbTab & 'B' & VbTab & 'C'

    Wscript.Echo 'D' & VbTab & 'E' & VbTab & 'F'

    Wenn Sie das Script mit Cscript ausführen, dann sieht seine Ausgabe in der Eingabeaufforderung so aus:

    1 2 3

    A B C

    D E F

Scripte, die in VBScript geschrieben werden, können auch nur auf die vordefinierten Konstanten von VBScript zugreifen. Sie haben keinen Zugriff auf die vordefinierten Konstanten von WMI, ADSI, der Script-Laufzeitbibliothek oder externen Automatisationsobjekten. Alle VBSCript-Konstanten (zum Beispiel VbCrLf oder VbYesNo) können Sie nutzen, ohne diese vorher definieren zu müssen. Wenn Sie jedoch WMI- oder ADSI-Konstanten nutzen möchten, dann müssen Sie diese vorher selbst definieren.

Das Objekt Drive aus der Script-Laufzeitbibliothek verfügt zum Beispiel über die Konstante mit dem Namen Fixed. Da VBScript jedoch auf die Konstanten dieses Automatisationsobjektes keinen Zugriff hat, müssen Sie die Konstante Fixed selbst mit einem entsprechenden Wert definieren.

Wenn Sie die Konstante nicht vorher definieren, dann wird das Script einen Fehler produzieren oder fehlerhaft arbeiten. Wenn Sie zum Beispiel versuchen das folgende Script auszuführen, dann wird es alles Mögliche machen. Es wird jedoch nicht die reparierten Laufwerke abfragen:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colDiskDrives = objFSO.Drives
For Each objDiskDrive in colDiskDrives
    If objDiskDrive.DriveType = Fixed then
        Wscript.Echo objDiskDrive.DriveLetter
    End if
Next

Das Script arbeitet fehlerhaft, da VBScript nicht weiß, dass die Konstante Fixed den Wert 2 hat. Stattdessen behandelt VBScript Fixed als einfache Variable, der kein Wert zugewiesen wurde. Damit ist die Variable leer, und es wird nach Laufwerken gesucht, bei denen das Attribut DriveType den Wert 0 statt 2 hat. Da VBScript kein Laufwerk mit diesem Wert finden kann, wird auch nichts ausgegeben.

Damit das Script funktioniert, müssen Sie eine eigene Konstante mit dem Namen Fixed und dem Wert 2 definieren:

Const Fixed = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colDiskDrives = objFSO.Drives
For Each objDiskDrive in colDiskDrives
    If objDiskDrive.DriveType = Fixed then
        Wscript.Echo objDiskDrive.DriveLetter
    End if
Next

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Datentypen unter VBScript

VBScript ist eine typenlose Sprache. Das bedeutet, dass Variablen nicht auf einen einzelnen Datentyp beschränkt werden können. Stattdessen verwendet VBScript nur einen einzigen Variablentyp: Variant. Dieser kann sämtliche Datentypen speichern.

Im Gegensatz dazu müssen Sie in einer Programmiersprache wie C++ den Typ der in einer Variablen zu speichernden Daten genau definieren. Wenn Sie versuchen Daten in einer Variable zu speichern, die für einen anderen Datentyp vorgesehen ist, dann kommt es zu einem Fehler.

Variant-Variablen können das Entwickeln von Scripten sehr vereinfachen. Sie können Variablen deklarieren und verwenden, und müssen sich keine Gedanke über die in ihnen gespeicherten Daten machen. Wenn Sie sich jedoch nicht mit der Typumwandlung auskennen, dann kann das gleiche Prinzip aber auch zu Problemen führen.

Typumwandlung

Scriptsprachen scheinen nur für den Entwickler typlos zu sein. Intern müssen auch Scriptsprachen mit Datentypen arbeiten. Wenn sie auf einen einfachen Ausdruck wie x = a + b trifft, dann muss die Scriptsprache aus diesem Ausdruck zum Beispiel die Datentypen von a und b herleiten. Mit anderen Worten: Die Scriptsprache muss die beiden Werte vom Typ Variant nehmen und Werte vom Typ Integer (Ganzzahl) oder String (Zeichenkette) aus ihnen machen. Nachdem die Datentypen hergeleitet wurden, kann die Rechenoperation durchgeführt werden.

Da der Wert von Typ Variant temporär in einen neuen Datentyp umgewandelt wird, wird diese Herleitung der Datentypen Typumwandlung genannt. Die Typumwandlung basiert auf bestimmen Regeln. Sie funktioniert in den allermeisten Fällen automatisch und problemlos.

Die Typumwandlung kann jedoch auch zu Problemen führen. Das folgende Script ist ein Beispiel hierfür:

intFirstNumber = InputBox("Erste Zahl eingeben:")
intSecondNumber = InputBox("Zweite Zahl eingeben:")
intTotal = intFirstNumber + intSecondNumber
Wscript.Echo intTotal

Wenn Sie das Script ausführen und als erste Zahl 4 und als zweite Zahl 2 eingeben, dann gibt das Script als Ergebnis der Berechnung 4 + 2 die Zahl 42. Wir hatten aber mit der Zahl 6 gerechnet.

Das liegt daran, dass der Operator sowohl für Zahlen als auch für Zeichenketten verwendet werden kann. VBScript hat in diesem Fall nur zwei Werte (4 und 2). Es gibt keine Angaben dazu, was das für Werte sind. Ohne weitere Informationen führt VBScript eine Typumwandlung der beiden Variablen in einen String (Zeichenkette) durch. Wenn die beiden Zeichenketten nun verkettet werden, dann ist das Ergebnis logischerweise die neue Zeichenkette "42".

Im Gegensatz dazu gibt das folgende Script den korrekten Wert (2) zurück (zumindest dann, wenn Sie die Zahlen 4 und 2 eingeben). Das liegt daran, dass der Divisionsoperator (/) nur mit Zahlen arbeiten kann. In diesem Fall führt VBScript eine Typumwandlung in Ganzzahlen (Integer) durch.

intFirstNumber = InputBox("Please enter the first number:")
intSecondNumber = InputBox("Please enter the second number:")
intTotal = intFirstNumber / intSecondNumber
Wscript.Echo intTotal

Um solche Probleme zu vermeiden, können Sie die von VBScript zu verwendenden Datentypen direkt in Ihrem Script angeben. Dies wird auch Casting oder auch explizite Typumwandlung genannt. Das folgende Script verwendet die Funktion CInt, um die Eingabevariablen vor der Berechnung in Ganzahlen (Integer) zu konvertieren:

intFirstNumber = CInt(InputBox("Please enter the first number:"))
intSecondNumber = CInt(InputBox("Please enter the second number:"))
intTotal = intFirstNumber + intSecondNumber
Wscript.Echo intTotal

In Tabelle 2.6 sehen Sie alle unter VBScript verfügbaren Funktionen zur expliziten Typumwandlung.

Tabelle 2.6: VBScript-Funktionen zur expliziten Typumwandlung

Funktion

Beschreibung

CBool

Konvertiert einen Wert größer Null in Wahr (True) und den Wert 0 zu Falsch (False).

CByte

Konvertiert einen Wert in den Datentyp Byte.

CCur

Konvertiert einen Wert in den Datentyp Currency (Währung).

CDate

Konvertiert einen Wert in den Datentyp Date (Datum).

CDbl

Konvertiert einen Wert in den Datentyp Double (Fliesskommazahl).

CInt

Konvertiert einen Wert in den Datentyp Integer (Ganzzahl). Wenn der Nachkommawert einer Fliesskommazahl 5 oder größer ist, dann rundet die Funktion das Ergebnis auf. Die Fliesskommazahl 3.5 wird zum Beispiel zu 4 aufgerundet.

CLng

Konvertiert einen Wert in den Datentyp Long.

CSng

Konvertiert einen Wert in den Datentyp Single.

CStr

Konvertiert einen Wert in den Datentyp String (Zeichenkette).

Mit leeren Variablen und Null-Variablen arbeiten

Für die erfolgreiche Ausführung eines Scripts kann es wichtig sein, dass Sie den Unterschied zwischen einer leeren Variable (Empty) und einer Null-Variable (Null) verstehen. Eine leere Variable ist eine Variable, die nicht initialisiert wurde. Nach dem Ausdruck Dim curBonus ist diese Variable so lange "leer", bis Sie ihr einen Wert zugewiesen haben. Eine leere Variable hat den Wert 0, wenn Sie als Zahl verwendet wird. Wenn Sie als Zeichenkette (String) verwendet wird, hat sie hingegen den Wert '' (eine Zeichenkette der Länge null).

Eine Null-Variable ist hingegen eine Variable, der kein gültiger Wert zugewiesen ist. Typischerweise entstehen Null-Variablen im Zusammenhang mit Datenbankoperationen. Stellen Sie sich zum Beispiel vor, Sie führen eine Datenbankabfrage durch und erhalten so das Feld "Bonus" eines bestimmten Mitarbeiters. Diesen Wert weisen Sie dann der Variable curBonus zu. Wenn dieser Mitarbeiter keinen Bonus erhält, dann ist die Variable in diesem Fall Null.

Der Unterschied zwischen einer leeren Variable und einer Null-Variable tritt bei mathematischen Operationen auf. Im folgenden Script wird der Wert von curBonus auf Empty (leer) gesetzt. Danach wird die Variable curBonus zur Variable curBaseSalary (50.000) addiert. Das Ergebnis ist: 50,000 + 0 = 50,000.

curBonus = Empty
curBaseSalary = 50000
curTotalCompensation = curBaseSalary + curBonus
Wscript.Echo TotalCompensation

Im nächsten Script wird genau das gleiche durchgeführt. Die Variable curBonus wird jedoch auf den Wert Null gesetzt. Bei der Berechnung erhalten Sie jedoch nicht 50.000 als Ergebnis. Stattdessen lautet das Ergebnis Null. Wenn in einer mathematischen Operation eine Null-Variable verwendet wird, dann ist das Endergebnis immer Null. Das liegt daran, dass der Wert einer Null-Variable nicht bekannt ist - sie hat ja keinen Wert (stellen Sie sich das Ergebnis Null vor als "ich weiß es nicht").

curBonus = Null
curBaseSalary = 50000
curTotalCompensation = curBaseSalary + curBonus
Wscript.Echo TotalCompensation

Null-Werte könnten bei der Arbeit mit Datenbanken und beim Abfragen von Active Directory-Informationen über ADSI zu Problemen führen. Glücklicherweise können Sie über die Methode IsNull feststellen, ob eine Variable den Wert Null hat. Das folgende Script prüft zum Beispiel den Wert der Variable curBonus. Wenn sie den Wert Null hat, wird ihr explizit der Wert 0 zugewiesen (denken Sie daran: Null heißt "kein Wert" und 0 heißt "der Wert 0"). Somit kann die Variable dann für eine Berechnung verwendet werden. Alternativ könnten Sie sich dazu entscheiden die Berechnung nicht durchzuführen und eine Meldung wie "Dem Mitarbeiter wurden keine Bonus-Informationen zugewiesen" anzuzeigen.

curBonus = Null
curBaseSalary = 50000
If IsNull(curBonus) Then
    CurBonus = 0
End If
curTotalCompensation = curBaseSalary + curBonus
Wscript.Echo curTotalCompensation

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Mit Datum- und Zeitinformationen arbeiten

Daten und Uhrzeiten spielen in der Systemadministration eine wichtige Rolle. Wenn Sie zum Beispiel mit Ereignisprotokollen arbeiten, dann möchten Sie möglicherweise alle Einträge für einen bestimmten Zeitraum anzeigen. Um die Verfügbarkeit von Diensten zu prüfen, müssen Sie möglicherweise feststellen, wann ein Dienst gestartet und beendet wurde - und aus diesen beiden Werten die tatsächliche Laufzeit des Dienstes berechnen. Um sicherzustellen, dass Scripte wie geplant ausgeführt werden, müssen Sie Datum und Uhrzeit der Scriptausführung festhalten. Sie sehen also, es gibt eine Menge Anwendungen für Datum- und Zeitinformationen.

VBScript bietet Ihnen mehrere unterschiedliche Wege, um Datum- und Zeitwerte zu erhalten. Außerdem stehen Ihnen mehrere Methoden zur Verfügung, um mit diesen Werten zu rechnen (zum Beispiel um die Tage zwischen zwei Daten zu berechnen).

Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Die unter VBScript verwendeten Datums- und Zeitformate unterscheiden sich deutlich von denen, die in WMI verwendet werden. Mehr zu den Formaten in WMI erfahren Sie im Kapitel WM- Scripting in diesem Buch.

Abfragen der aktuellen Uhrzeit und des Datums

Oft benötigen Sie zur Systemadministration die aktuelle Uhrzeit oder das aktuelle Datum. VBScript bietet Ihnen hierzu drei Funktionen an:

  • Now - gib das aktuelle Datum und die Uhrzeit zurück.
  • Date - gibt nur das aktuelle Datum zurück.
  • Time - gibt nur die aktuelle Uhrzeit zurück.

Das folgende Script verwendet die drei Funktionen und zeigt die Ergebnisse in einem Nachrichtenfenster an:

DateInfo = DateInfo & Now & VbCrLf
DateInfo = DateInfo & Date & VbCrLf
DateInfo = DateInfo & Time & VbCrLf
Wscript.Echo DateInfo
Die Ausgabe des Scripts sehen Sie in Abbildung 2.12. 

Dn151187.53BFECC893FC72DF12EC6197A369C51C(de-de,TechNet.10).png

Abbildung 2.12: Rückgabewerte der Funktionen Now, Date und Time

Prüfen, ob ein Wert ein gültiges Datum ist

Bei der Arbeit mit Daten müssen Sie manchmal feststellen, ob ein Wert ein Datum ist oder nicht. Dies kann zum Beispiel bei WMI-Abfragen oder bei der Arbeit mit Datenbanken wichtig werden.

Die Funktion IsDate zeigt Ihnen, ob ein Wert ein gültiges Datum ist. Sie gibt den Wert 0 (False - Falsch) zurück, wenn es sich bei dem Wert nicht um ein Datum handelt - andernfalls erhalten sie den Wert -1 (True - Wahr) zurück. Sie können der Funktion den zu prüfenden Wert auf zwei Arten übergeben:

  • Als VBScript-Datumswert - Das Datum wird durch zwei Doppelkreuze (#) eingeschlossen. Dies ist die empfohlene Vorgehensweise. Sie verhindert, dass VBScript den Wert falsch interpretiert. Ein Datumswert sieht folgendermaßen aus:

    #9/3/2002#

  • Datum- und Zeitformate, wie sie durch Ihre Systemeinstellungen festgelegt sind - Wenn Ihre Systemeinstellungen beispielsweise auf Deutsch festgelegt sind, dann können Sie für das Datum 6. Januar 2002 zum Beispiel die folgenden Schreibweisen verwenden:

    • 6/1/2002
    • 6,1,2002
    • 6-1-2002
    • 6.1.2002
    • Bei der Einstellung English (USA) ist hingegen die letzte Schreibweise ungültig. Außerdem wären die Werte von Tag und Monat vertauscht. Der 6. Januar 2002 würde zum Beispiel so dargestellt. 1/6/2002
Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Um die auf Ihrem Computer eingestellten Formate zu prüfen, öffnen Sie die Regions- und Sprachoptionen in der Systemsteuerung. Dort klicken Sie dann auf Anpassen und wählen die Registerkarte Datum oder Uhrzeit.

Das folgende Script erstellt einen Array mit Werten und geht den Array dann durch. Es verwendet die Funktion IsDate,um festzustellen, ob es sich bei den Werten des Arrays um Daten handelt. Die Rückgabe der Funktion wird dem Benutzer angezeigt.

DateArray = Array("6/1/2002", "Juni 1, 2002", "6", "6/1")
For Each dtmDate in DateArray
    If IsDate(dtmDate) = 0 Then
        Wscript.Echo dtmDate & " ist kein gültiges Datum."
    Else
        Wscript.Echo dtmDate & " ist ein gültiges Datum."
    End If
Next

Wenn Sie das Script mit CScript ausführen, erhalten Sie folgende Ausgabe:

6/1/2002 ist ein gültiges Datum.
Juni 1, 2002 ist ein gültiges Datum.
6 ist kein gültiges Datum.
6/1 ist ein gültiges Datum.
Dn151187.note(de-de,TechNet.10).gifAnmerkung:
Warum ist 6/1 ein gültiges Datum? Die Funktion IsDate versucht aus dem übergebenen Wert ein gültiges Datum zu konstruieren. Der Wert 6/1 kann als Tag/Monat interpretiert werden. Daher hängt IsDate einfach das aktuelle Jahr an und kommt zum Ergebnis Tag/Monat/Jahr.

Teile eines Datums oder eines Zeitwertes abfragen

Oft benötigen Sie nur einen bestimmten Teil eines Datums oder eines Zeitwertes. Zum Beispiel, wenn Sie Ihr Sicherungsscript nur an Sonntagen oder nur am 15. eines Monats ausführen möchten.

Unter VBScript haben Sie zwei Möglichkeiten Teile eines Datums oder eines Zeitwertes abzufragen. Mit der Funktion DatePart können Sie jeden beliebigen Teil eines Datums oder eines Zeitwertes abfragen. Außerdem stellt VBScript mehrere Funktionen zur Verfügung, um bestimmte Teile abzufragen (zum Beispiel die Funktionen Day, Month und Year).

Die Funktion DatePart benötigt zwei Parameter: Das Datum und den Teil des Datums, den Sie herausfinden möchten. Der Teil muss in einem bestimmen Format angegeben werden. Dieses Format wird in der folgenden Tabelle beschrieben.

Tabelle 2.7: Parameter der Funktion DatePart

Parameter

Beschreibung

yyyy

Jahr - gibt die Jahreszahl des Datum-/Zeitwerts zurück.

q

Quartal - gibt das Quartal - 1, 2, 3 oder 4 - des Datum-/Zeitwerts zurück.

m

Monat - gibt den Monat des Datum-/Zeitwerts zurück. Hierbei gelten folgend Werte:

1 - Januar

2 - Februar

3 - März

4 - April

5 - Mai

6 - Juni

7 - Juli

8 - August

9 - September

10 - Oktober

11 - November

12 - Dezember

y

Tag des Jahres - hierbei steht 1 für den 1. Januar und 365 für den 31. Dezember (bei Schaltjahren 366). Der 1. Februar wäre zum Beispiel der Wert 32, da er der zweiunddreißigste Tag des Jahres ist.

d

Tag - gibt den Tag des Monats zurück. Für den 17. April würden Sie zum Beispiel den Wert 17 erhalten.

w

Wochentag - gibt den Wochentag zurück. Hierbei gelten die folgenden Werte:

1 - Sonntag

2 - Montag

3 - Dienstag

4 - Mittwoch

5 - Donnerstag

6 - Freitag

7 - Samstag

Wenn Sie möchten, könnten Sie angeben, dass die Woche mit einem anderen Tag als Sonntag beginnt. Weitere Informationen hierzu finden Sie weiter unten in diesem Kapitel.

ww

Woche des Jahres - hierbei steht 1 für die erste Woche im Januar und 52 für die letzte Woche im Dezember. Auch hier können Sie die erste Woche des Jahres nach Ihrem Wünschen festlegen.

h

Stunde - Gibt die Stunde im 24-Stunden-Format zurück. Für den Zeitraum zwischen 00:00 Uhr und 01:00 Uhr wird der Wert 0 zurückgegeben.

n

Minute

s

Sekunde

Den von der Funktion DatePart zurückgegebenen Wert können Sie zum Beispiel einer Variablen zuweisen. Die folgende Codezeile extrahiert zum Beispiel das Jahr aus dem aktuellen Datum und weist dieses der Variable CurrentYear zu:

CurrentYear = DatePart("yyyy", Date)

In diesem Beispiel werden die folgenden Parameter verwendet:

  • 'yyyy" - gibt an, dass das Jahr aus dem Datum extrahiert werden soll. Dieser Parameter muss immer in Anführungszeichen eingeschlossen werden.

  • Date - gibt das Datum an, aus dem der angegebene Teil extrahiert werden soll. In diesem Fall wird für diesen Parameter die Funktion Date angegeben, die das aktuelle Datum zurückgibt. Sie können natürlich auch ein tatsächliches Datum angeben. Denken Sie daran, dass solche Datumswerte in Doppelkreuze eingeschlossen werden müssen (zum Beispiel '6/1/2002'). Die folgenden beiden Codezeilen geben zum Beispiel das Jahr 1977 zurück:

    DateToCheck = #8/15/1977#

    CurrentYear = DatePart('yyyy' , DateToCheck)

Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Auch wenn Sie ein Datum zu einer Variablen zuweisen, müssen Sie das Datum in Doppelkreuze (#) einschließen. So stellen Sie sicher, dass VBScript den Wert auch als Datum und nicht als Zahl oder Zeichenkette interpretiert. Alternativ können Sie auch die Funktion CDate verwenden.

Script 2.15 interpretiert das aktuelle Datum und die Uhrzeit und gibt die einzelnen Komponenten für den Benutzer aus.

Script 2.15: Verwendung der Funktion DatePart

1

2

3

4

5

6

7

8

9

10

11

Wscript.Echo Now

Wscript.Echo "Jahr: " & DatePart("yyyy" , Now)

Wscript.Echo "Quartal: " & DatePart("q", Now)

Wscript.Echo "Monat: " & DatePart("m" , Now)

Wscript.Echo "Tag des Jahres: " & DatePart("y" , Now)

Wscript.Echo "Tag: " & DatePart("d" , Now)

Wscript.Echo "Wochentag: " & DatePart("w" , Now)

Wscript.Echo "Woche des Jahrs: " & DatePart("ww" , Now)

Wscript.Echo "Stunde: " & DatePart("h", Now)

Wscript.Echo "Minute: " & DatePart("n" , Now)

Wscript.Echo "Sekunde: " & DatePart("s" , Now)

Wenn das Script am 14. März 2004 um 20:45:20 ausgeführt wird, dann produziert es folgende Ausgabe:

14.03.2004 20:45:20
Jahr: 2004
Quartal: 1
Monat: 3
Tag des Jahres: 74
Tag: 14
Wochentag: 1
Woche des Jahrs: 12
Stunde: 20
Minute: 45
Sekunde: 20

Wenn Sie für die Funktion DatePart unvollständige Parameter verwenden, wird keine Fehlermeldung ausgegeben. Es könnte jedoch sein, dass Sie nicht das erwartete Resultat erhalten. Die folgende Codezeile gibt zum Beispiel den Wert 1899 zurück:

Wscript.Echo DatePart("yyyy", "8:00")

Diese Codezeile gibt den Wert 0 zurück:

Wscript.Echo DatePart("h", "12/1/2002")

Optionen von DatePart

Standardmäßig ist unter VBScript die erste Woche des Jahres die Woche mit dem 1. Januar. Sie können dieses Verhalten jedoch mit den in der folgenden Tabelle gezeigten Werten ändern.

Tabelle 2.8: Parameter für die Einstellung "Erste Woche des Jahres"

Konstante

Wert

Beschreibung

vbUseSystem

0

Verwendet die National Language Support API, um die erste Woche des Jahres auf Basis der Regional- und Spracheinstellungen festzulegen.

vbFirstJan1

1

Setzt die erste Woche auf die Woche mit dem 1. Januar.

vbFirstFourDays

2

Setzt die erste Woche auf die erste Woche mit mindestens 4 Tagen.

VbFirstFullWeek

3

Setzt die erste Woche auf die erste Woche, die mit einem Montag beginnt.

Hängen Sie den Wert als dritten Parameter hinter das Datum an. Das folgende Script zeigt die Verwendung des Parameters "Erste Woche":

TestDate = "6/1/2003"
Wscript.Echo TestDate
Wscript.Echo "Woche: " & DatePart("ww" , TestDate)
Wscript.Echo "Woche: " & DatePart("ww" , TestDate, vbFirstJan1)
Wscript.Echo "Woche: " & DatePart("ww" , TestDate, vbFirstFourDays)
Wscript.Echo "Woche: " & DatePart("ww" , TestDate, vbFirstFullWeek)

Wenn Sie das Script mit CScript ausführen, dann erhalten Sie folgendes Ergebnis:

6/1/2003
Woche: 2
Woche: 2
Woche: 2
Woche: 1

Wie Sie in Abbildung 2.13 sehen, fällt der 6. Januar 2003 nicht in dieselbe Woche wie der 1. Januar. Außerdem liegt er nicht in der ersten Woche, die mindestens vier Tage hat. Er liegt jedoch in der ersten Woche, die mit einem Montag beginnt.

Dn151187.EC112672850D57896ED1B2363BAECEB7(de-de,TechNet.10).png

Abbildung 2.13: 6. Januar 2003

Weitere Funktionen, um Teile eines Datums zu extrahieren

Zusätzlich zur Funktion DatePart können Sie die Funktionen aus Tabelle 2.9 verwenden. DatePart bietet allerdings einige Möglichkeiten, die Ihnen mit den zusätzlichen Funktionen nicht zur Verfügung stehen (zum Beispiel den Tag des Jahres). Möglicherweise fällt es Ihnen jedoch schwer, sich die Parameter von DatePart zu merken. In diesem Fall sind die zusätzlichen Funktionen deutlich einfacher zu verwenden - sie erfordern keine Parameter. Die folgenden beiden Codezeilen geben beispielsweise die Minute der aktuellen Uhrzeit zurück. Für die Funktion Minute benötigen Sie jedoch keine Parameter:

Wscript.Echo DatePart("n", Now)
Wscript.Echo Minute(Now)

Tabelle 2.9: Funktionen, um Teile eines Datums oder eines Zeitwertes zu extrahieren

Funktion

Beschreibung

Day

Gibt den Tag zurück

Hour

Gibt die Stunde zurück

Minute

Gibt die Minute zurück

Month

Gibt den Monat zurück

Second

Gibt die Sekunde zurück

Weekday

Gibt den Wochentag zurück. Hierbei gelten folgende Wert:

1 - Sonntag

2 - Montag

3 - Dienstag

4 - Mittwoch

5 - Donnerstag

6 - Freitag

7 - Samstag

Year

Gibt das Jahr zurück.

Um diese Funktionen zu verwenden, reicht es, sie einfach mit dem Datum- oder Zeitwert als Parameter aufzurufen. Das folgende Script führt dies zum Beispiel mit dem aktuellen Datum und der Uhrzeit durch:

CurrentDate = Now
Wscript.Echo "Jahr: " & VbTab & VbTab & Year(CurrentDate)
Wscript.Echo "Monat: " & VbTab & VbTab & Month(CurrentDate)
Wscript.Echo "Tag: " & VbTab & VbTab & Day(CurrentDate)
Wscript.Echo "Wochentag: " & VbTab & Weekday(CurrentDate)
Wscript.Echo "Stunde: " & VbTab & VbTab & Hour(CurrentDate)
Wscript.Echo "Minute: " & VbTab & Minute(CurrentDate)
Wscript.Echo "Sekunde: " & VbTab & Second(CurrentDate)

Wenn Sie das Script über CScript ausführen, erhalten Sie zum Beispiel folgende Ausgabe:

Jahr:           2004
Monat:          3
Tag:            14
Wochentag:      1
Stunde:         21
Minute:         17
Sekunde:        37

In der Systemadministration ist das Berechnen von Zeiträumen genauso wichtig wie das Feststellen von Daten - zum Beispiel wenn Sie wissen möchten, welcher Tag in 180 Tagen von heute an ist, oder wenn Sie wissen möchten, wie lange ein Dienst zwischen Start und Ende ausgeführt wurde.

Zum Berechnen von Zeiträumen stellt VBScript zwei Funktionen zur Verfügung. DateDiff und DateAdd.

Berechnen des Zeitraumes zwischen zwei Daten oder Uhrzeiten

Hierzu wird die Funktion DateDiff verwendet. Sie benötigt drei Parameter:

  • Den Datums- oder Zeitintervall (zum Beispiel die Zahl der Tage zwischen zwei Daten oder die Zahl der Stunden zwischen zwei Uhrzeiten). Dieser Parameter verwendet dieselben Werte wie die Funktion DatePart - diese finden Sie in Tabelle 2.7).
  • Das Startdatum.
  • Das Enddatum.

Script 2.16 berechnet zum Beispiel die Tage zwischen dem aktuellen Datum und dem 1. Juli 2007. Hierzu wird der Parameter "d" verwendet. Wenn Sie zum Beispiel die Wochen zwischen den beiden Daten berechnen möchten, dann würden Sie den Parameter durch "w" ersetzen.

Script 2.16: Berechnen von Zeiträumen

1

2

Wscript.Echo "Date: " & Date

Wscript.Echo "Tage bis 1. Juli 2007: " & DateDiff("d", Date, "7/1/2002")

Wenn Sie das Script über Cscript ausführen, erhalten Sie folgendes Ergebnis:

Date: 14.03.2004
Tage seit 1. Juli 2002: 1029
Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Abhängig von den verwendeten Daten könnte es auch sein, dass Sie eine negative Zahl erhalten. Dies passiert, wenn das Startdatum hinter dem Enddatum liegt. Wenn Sie keinen negativen Wert erhalten möchten, dann können Sie dies mit der Funktion Abs vermeiden. Sie gibt Ihnen den absoluten Wert einer Zahl zurück. Der Aufruf würde dann folgendermaßen aussehen: Abs(DateDiff('d', '7/1/2002', '1/18/2002').

Mit DateDiff erhalten Sie möglicherweise unterschiedliche Ergebnisse, abhängig davon, ob Sie den Paramter 'w' oder 'ww' verwenden. Der Parameter 'w' berechnet die Anzahl der Wochen zwischen zwei Daten auf Basis des Tages des Startdatums. Der 18. Januar 2002 fiel zum Beispiel auf einen Freitag. Mit dem Parameter "w" berechnet DateDiff die Zahl der Freitage zwischen diesem Datum und einem anderen Datum. Im Gegensatz dazu berechnet DateDiff mit dem Parameter "ww" die Wochen auf Basis der Sonntage zwischen den beiden Daten.

Mit DateDiff können Sie auch feststellen, wie lange Ihr Script zur Ausführung benötig hat. Hierzu weisen Sie einfach in der ersten Zeile einer Variable den Rückgabewert der Funktion Now zu. Sie enthält nun die Uhrzeit des Scriptstarts. Am Ende des Scripts berechnen Sie die Differenz zwischen der Zeit in der Variable und dem Rückgabewert der Funktion Now.

Das folgende Script fragt den freien Plattenplatz für alle Laufwerke des lokalen Computers ab und misst die Zeit, die es zur Ausführung benötigt:

Start = Now
Set objWMIService = GetObject("winmgmts://")
Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk") 
For Each objLogicalDisk In colLogicalDisk     
    Wscript.Echo objLogicalDisk.DeviceID & " " & objLogicalDisk.FreeSpace
Next
Wscript.Echo DateDiff("s", Start, Now)

Daten berechnen

Mit DateDiff können Sie feststellen, wie groß der Zeitraum zwischen zwei Daten ist. Es wird jedoch ganz sicher auch Fälle geben, in denen Sie den Zeitraum kennen und mit diesem ein Datum berechnen müssen. Wenn Sie zum Beispiel alle Protokolleinträge der letzten 45 Tage abrufen möchten, dann kennen Sie das Enddatum (heute) und den Zeitraum (45 Tage) - nun fehlt ihnen noch das Startdatum.

Ein solches Datum können Sie mit der Funktion DateAdd berechnen. Die Funktion erwartet drei Parameter:

  • Den Intervall (auch hier verwenden Sie bitte wieder die Werte von DatePart aus Tabelle 2.7). Wenn Sie zum Beispiel das Datum in 180 Tagen von heute an berechnen möchten, dann verwenden Sie den Parameter "d".
  • Den Zeitraum (zum Beispiel 180 für 180 Tage). Um von einem Datum aus rückwärts zu rechnen, verwenden Sie einfach eine negative Zahl.
  • Das Startdatum.

Script 2.17 berechnet das Datum, das 180 Tag nach dem heutigen Datum liegt.

Script 2.17: Berechnen eines Datums

1

2

Wscript.Echo "Datum: " & Date

Wscript.Echo "180 von heute an: " & DateAdd("d", 180, Date)

Wenn das Script am 14. März 2004 ausgeführt wird, dann erhalten Sie folgende Ausgabe:

Datum: 14.03.2004
180 von heute an: 10.09.2004

Formatierung von Datum- und Zeitwerten

Standardmäßig zeigt VBScript die Ausgaben der Funktionen Now, Date und Time so an, dass sie den Betriebssystemeinstellungen entsprechen. Auf Computer mit der deutschen Version von Windows sieht diese Ausgabe normalerweise so aus, wie in Tabelle 2.10 dargestellt.

Tabelle 2.10: Standardausgabe von Datum und Uhrzeit

Funktion

Beispielausgabe

Now

14.03.2004 22:08:10

Date

14.03.2004

Time

22:08:10

Sie müssen sich jedoch nicht auf diese Standardformate beschränken. Stattdessen stellt VBScript mehrere Konstanten zur Verfügung, über die Sie mit der Funktion FormatDateTime Datum- und Zeitwerte neu formatieren können.

Tabelle 2.11: Parameter der Funktion FormatDateTime

Konstante

Wert

vbGeneralDate

0

vbLongDate

1

vbShortDate

2

vbLongTime

3

vbShortTime

4

Das folgende Script zeigt das aktuelle Datum und die Uhrzeit an, und gibt diese in unterschiedlichen Formaten aus:

CurrentDate = Now
Wscript.Echo "GeneralDate: " & FormatDateTime(CurrentDate, vbGeneralDate)
Wscript.Echo "LongDate: " & FormatDateTime(CurrentDate, vbLongDate)
Wscript.Echo "ShortDate: " & FormatDateTime(CurrentDate, vbShortDate)
Wscript.Echo "LongTime: " & FormatDateTime(CurrentDate, vbLongTime)
Wscript.Echo "ShortTime: " & FormatDateTime(CurrentDate, vbShortTime)

Wenn Sie das Script über CScript ausführen, erhalten Sie das folgende Ergebnis:

GeneralDate: 14.03.2004 22:12:53
LongDate: Sonntag, 14. März 2004
ShortDate: 14.03.2004
LongTime: 22:12:53
ShortTime: 22:12

Dies sind die einzigen vordefinierten Formate unter VBScript. Sie können Sich jedoch auch eigene Formate zusammenbauen. Die folgende Codezeile zeigt das Datum zum Beispiel im Format "Monat/Jahr" an:

Wscript.Echo Month(Now) & "/" & Year(Now)

Formatierung von Wochentag und Monat des Jahres

Die Funktionen WeekdayDay und Month liefern Ihnen den Wochentag oder den Monat eines Datums. Bei dem Rückgabewert handelt es sich allerdings um einen Integer-Wert (Ganzahl). Die Bedeutung der Werte sehen Sie in Tabelle 2.12

Tabelle 2.12: Werte für Wochentag und Monat

Wert

Wochentag

Monat

1

Sonntag

Januar

2

Montag

Februar

3

Dienstag

März

4

Mittwoch

April

5

Donnerstag

Mai

6

Freitag

Juni

7

Samstag

Juli

8

-

August

9

-

September

10

-

Oktober

11

-

November

12

-

Dezember

Um die Funktionen WeekdayName und MonthName verwenden zu können, müssen Sie erst den Tag oder den Monat aus dem Datum extrahieren. Sie können nicht direkt mit einem Datum verwendet werden. Die folgende Codezeile funktioniert zum Beispiel nicht:

Wscript.Echo MonthName("19/9/2002")

Um MonthName verwenden zu können, müssen Sie zuerst die Funktion Month verwenden:

MonthValue = Month("19/9/2002")
Wscript.Echo MonthName(MonthValue)

Alternativ können Sie die beiden Funktionen in einer Codezeile verschachteln:

Wscript.Echo MonthName(Month("19/9/2002"))

Eine genauere Beschreibung der Funktionen WeekdayName und MonthName finden Sie in Tabelle 2.13.

Tabelle 2.13: WeekdayName und MonthName

Funktion

Beschreibung

WeekdayName

Gibt statt der Nummer des Tages dessen Namen zurück. Als Parameter muss nur der Tag angegeben werden. Daher müssen Sie die Funktionen WeekdayName und Day folgendermaßen verschachteln:

Wscript.Echo WeekDayName(Day('1/9/2002'))

Diese Codezeile gibt den Wert Sonntag zurück. Mit einem weiteren optionalen Parameter können Sie sich die Abkürzung von den Namen des Wochentages zurückliefern lassen. Hängen Sie den Parameter True einfach hinter den Wochentag an:

Wscript.Echo WeekDayName(Day('9/1/2002'), True)

MonthName

Gibt statt der Nummer des Monats dessen Namen zurück. Als Parameter muss nur der Monat angegeben werden. Daher müssen Sie die Funktionen MonthName und Month folgendermaßen verschachteln:

Wscript.Echo MonthName(Month('9/1/2002'))

Diese Codezeile gibt den Wert September zurück. Mit einem weiteren optionalen Parameter können Sie sich die Abkürzung von den Namen des Monats zurückliefern lassen. Hängen Sie den Parameter True einfach hinter den Monat an:

Wscript.Echo MonthName(Month('9/1/2002') , True)

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Arbeiten mit Strings (Zeichenketten)

Viele Scripte zur Systemadministration geben Informationen über verwaltete Elemente zurück - zum Beispiel Dienste, Hardware oder Ereignisse. Viele dieser Informationen werden als Zeichenketten zurückgegeben. Wenn Sie zum Beispiel die Beschreibung eines Ereignisses aus dem Ereignisprotokoll abrufen, dann erhalten Sie einen String wie den folgenden:

Dienst "Universeller Plug & Play-Gerätehost" befindet sich jetzt im Status "Ausgeführt".

Auch wenn Zeichenketten eigentlich ganz einfach sind, kann die Arbeit mit Ihnen kniffelig sein. Ganz besonders, wenn die Daten von einem COM-Objekt zurückgegeben werden oder wenn Sie die Daten in einer Datenbank speichern oder auf dem Bildschirm anzeigen müssen. Das liegt daran, dass Sie keine Kontrolle darüber haben, wie die zurückgegebenen Daten aussehen. Es kann sein, dass sie falsch formatiert sind (zum Beispiel nur Großbuchstaben) oder das eine Zeichenkette zu lang oder zu kurz für den vorgesehenen Platz ist (wenn das Feld in der Datenbank zum Beispiel nur 20 Zeichen lang und die Zeichenkette 30 Zeichen lang ist).

Daher sollten Sie in der Lage sein mit Strings umzugehen - zum Beispiel einen String zu verkürzen oder zu verlängern, einen String neu zu formatieren oder in einem String nach einem Text zu suchen. Hierzu stellt Ihnen VBScript einige Funktionen zur Verfügung.

Manipulation von Strings und String-Längen

Oft benötigen Sie nur einen Teil eines Strings. Der Windows Script Host (WSH) stellt zum Beispiel ein Attribut mit dem Namen FullName zur Verfügung. Dieses zeigt Ihnen, ob ein Script unter CScript oder WScript ausgeführt wird. Diese Information kann sehr nützlich sein, wenn Sie Scripte verwenden, die entweder nur unter CScript oder nur unter WScript ausgeführt werden können. Das Attribut gibt aber leider nicht nur den Namen des Scripting Hosts zurück, sondern den gesamten Pfad der ausführbaren Datei des Scripting Hosts. Dieser sieht normalerweise so aus:

C:\Windows\Cscript.exe
C:\Windows\Wscript.exe.

Meistens benötigen Sie jedoch nicht den gesamten Pfad, sondern nur den Namen des Scripting Hosts - außerdem hängt der Pfad auch vom Speicherort der ausführbaren Datei des Scripting Hosts ab. Daher benötigen Sie eine Methode, um nur die letzten acht Zeichen (cscript.exe oder wscript.exe) aus dem Pfad zu extrahieren.

In anderen Fällen ist die Länge eines Strings sehr wichtig. Ganz besonders dann, wenn es um formatierte Bildschirmausgaben oder Ausgaben in eine Textdatei geht. Das folgende Script ruft zum Beispiel eine Collection ab, die die im Ordner C:\Windows gespeicherten Dateien enthält und gibt Dateiname, Dateigröße und das Datum des letzten Zugriffs für jede Datei aus:

Set FSO = CreateObject("Scripting.FileSystemObject")
Set Folder = FSO.GetFolder("C:\Windows")
Set FileList = Folder.Files
For Each File in FileList
    Wscript.Echo File.Name & VbTab & File.Size & File.DateLastModified
Next

Wenn Sie das Script ausführen, dann wird die Ausgabe so ähnlich wie unten aussehen. Wie Sie feststellen werden, ist es nicht so einfach, diese Ausgabe zu lesen.

regedit.exe     14131229.08.2002 04:43:40
regopt.log      134816.01.2004 22:15:13
Rhododendron.bmp        1736218.08.2001 14:00:00
Santa Fe-Stuck.bmp      6583218.08.2001 14:00:00
SchedLgU.Txt    542414.03.2004 18:36:49
Seifenblase.bmp 6597818.08.2001 14:00:00
sessmgr.setup.log       106016.01.2004 22:27:34
SET3.tmp        108618229.08.2002 09:54:40
SETA.tmp        1389818.08.2001 14:00:00

Mit ein paar Tabulatoren und in Spalten angeordnet ist die Ausgabe viel einfacher zu lesen und zu überblicken:

regedit.exe               141312   29.08.2002 04:43:40
regopt.log                1348     16.01.2004 22:15:13
Rhododendron.bmp          17362    18.08.2001 14:00:00
Santa Fe-Stuck.bmp        65832    18.08.2001 14:00:00
SchedLgU.Txt              5424     14.03.2004 18:36:49
Seifenblase.bmp           65978    18.08.2001 14:00:00
sessmgr.setup.log         1060     16.01.2004 22:27:34
SET3.tmp                  1086182  29.08.2002 09:54:40
SETA.tmp                  13898    18.08.2001 14:00:00

Um eine solche Ausgabe zu erreichen, müssen Sie Strings verändern. In der letzten Ausgabe beginnt der Dateiname zum Beispiel an Zeichenposition 1, und die Dateigröße beginnt immer an Zeichenposition 30:

123456789012345678901234567890123456789012345678901234567890123456789
SETA.tmp                     13898    18.08.2001     14:00:00

Um eine solche Ausgabe zu erstellen, müssen Sie Folgendes durchführen:

  1. Sie müssen die Länge der Dateinamen berechnen (der Dateiname SETA.tmp ist zum Beispiel 8 Zeichen lang).
  2. Sie müssen die Länge des Dateinamens (8 Zeichen) vom Gesamtplatz für den Dateinamen (30 Zeichen) abziehen.
  3. Sie müssen entsprechend viele Leerzeichen einfügen (30 minus 8 = 22 Leerzeichen).

Glücklicherweise stellt VBScript eine Menge Funktionen zur Manipulation von Strings zur Verfügung. Einige dieser Funktionen sehen Sie in Tabelle 2.14.

Tabelle 2.14: Funktionen zur String-Bearbeitung

Funktion

Beschreibung

Len

Gibt die Zahl der Zeichen in einem String zurück. Diese Funktion ist besonders bei der Bildschirmausgabe von Strings nützlich. Stellen Sie sich vor, Sie möchten in einer bestimmten Spalte nicht mehr als 20 Zeichen ausgeben. Um dies zu garantieren, müssen Sie feststellen können, wie viele Zeichen ein String enthält.

Das folgende Codestück gibt den Wert 24 zurück, da der String Dies ist ein Test-String 24 Zeichen lang ist.
TestString = "Dies ist ein Test-String" Wscript.Echo Len(TestString)

Left

Gibt eine bestimmte Anzahl von Zeichen zurück. Die zurückgegebenen Zeichen beginnen mit dem ersten Zeichen des Strings und setzen sich nach rechts bis zum Ende des Strings fort. Sie müssen zwei Parameter angeben: den String und die Anzahl der zurückzugebenden Zeichen.

Das folgende Codestück gibt den String Die zurück, da dies die ersten drei Zeichen des Strings Dies ist ein Test-Stringsind.
TestString = "Dies ist ein Test-String" Wscript.Echo Left(TestString, 3)

Right

Gibt eine bestimmte Zahl von Zeichen zurück. Die zurückgegebenen Zeichen beginnen mit dem letzten Zeichen des Strings und setzen sich nach links bis zum Anfang des Strings fort. Sie müssen zwei Parameter angeben: den String und die Anzahl der zurückzugebenden Zeichen.

Das folgende Codestück gibt den String ing zurück, da dies die letzten drei Zeichen des Strings Dies ist ein Test-Stringsind.
TestString = "Dies ist ein Test-String" Wscript.Echo Right(TestString, 3)

Mid

Gibt eine bestimmte Zahl von Zeichen zurück. Die zurückgegebenen Zeichen beginnen an der als Parameter angegebenen Position und setzten sich zum Ende des Strings fort (von links nach rechts). Sie müssen drei Parameter angeben: den String, die Startposition im String (zum Beispiel 5, um beim fünften Zeichen des Strings zu beginnen) und die Anzahl der zurückzugebenden Zeichen.

Das folgende Codestück gibt den String ist_ zurück (der Unterstrich steht für ein Leerzeichen), da dies die Zeichen an den Positionen 6, 7, 8 und 9 sind.
TestString = "Dies ist ein Test-String" Wscript.Echo Mid(TestString, 6, 4)

Space

Fügt die angegebene Anzahl von Leerzeichen in einen String ein. Das folgende Codestück fügt zum Beispiel 10 Leerzeichen zwischen Dies ist ein und Test-String ein.
Wscript.Echo "Dies ist ein" & Space(10) _ & "Test-String"

LTrim

Entfernt alle Leerzeichen am Anfang eines Strings.
TestString = " This is a test string " Wscript.Echo LTrim(TestString)

RTrim

Entfernt alle Leerzeichen am Ende eines Strings.
TestString = " This is a test string " Wscript.Echo RTrim(TestString)

Trim

Entfernt alle Leerzeichen am Anfang und am Ende eines Strings. Das folgende Codestück wandelt den String " Dies ist ein Teststring " zum Beispiel in den String "Dies ist ein Test-String" um.
TestString = " This is a test string " Wscript.Echo Trim(TestString)

Tabellarische Ausgaben

Die Funktionen zur Stringbearbeitungen sind besonders bei der Erstellung von tabellarischen Ausgaben sehr nützlich. Ein Beispiel hierfür sehen Sie in Script 2.18. Es verwendet die Funktionen Len und Space, um eine Tabelle zu erstellen, in der zwei Dienste und deren Status angezeigt werden. Das Script geht folgendermaßen vor:

  1. Es setzt den Wert von vier Variablen - zwei für die Namen der Dienste und zwei für deren Status.
  2. Es stellt mit der Funktion Len die Länge des Strings in der ersten Variable fest und speichert diesen Wert in der Variable NameLength. "Warndienst" hat zum Beispiel 10 Zeichen - daher wird in NameLength der Wert 10 gespeichert.
  3. Das Script subtrahiert den Wert in NameLength von 20 (der Spaltenbreite der Spalte für die Dienstnamen) und speichert das Ergebnis in der Variable SpacesToAdd. Für den "Warndienst" wäre das 10 (20-10).
  4. Es schreibt den Namen des Dienstes in die Variable DisplayName und hängt so viele Leerzeichen an, dass der String in dieser Variable 20 Zeichen lang ist. Für den "Warndienst" wären das zum Beispiel 10 zusätzliche Leerzeichen (der Wert in der Variable SpacesToAdd). Diese Leerzeichen werden über die Funktion Space hinzugefügt.
    Die Variable DisplayName enthält dann folgenden String (die Trennstriche stehen für Leerzeichen):
    Warndienst----------
  5. Das Script gib die Variable DisplayName und den Status des Dienstes aus.
  6. Es wiederholt den Prozess für den nächsten Dienstnamen.

Script 2.18: Tabellarische Ausgaben

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Service1 = "Warndienst"

State1 = "Wird ausgeführt"

Service2 = "DHCP-Client"

State2 = "Angehalten"

NameLength = Len(Service1)

SpacesToAdd = 20 - NameLength

DisplayName = Service1 & Space(SpacesToAdd)

Wscript.Echo DisplayName & State1

Display = ""

NameLength = Len(Service2)

SpacesToAdd = 20 - NameLength

DisplayName = Service2 & Space(SpacesToAdd)

Wscript.Echo DisplayName & State2

Wenn Sie das Script unter CScript ausführen, dann erhalten Sie die folgende Ausgabe:

Warndienst          Wird ausgeführt
DHCP-Client         Angehalten

Text in Nachrichtenfenster formatieren

Wenn Sie es vorziehen, Text in Nachrichtenfenstern auszugeben, dann werden Sie feststellen, dass es hier sehr viel schwerer ist den Text in Spalten auszugeben - wenn nicht gar unmöglich. Das liegt an den unterschiedlichen Scripten in der Eingabeaufforderung und im Nachrichtenfenster. In der Eingabeaufforderung wird eine nichtproportionale Schrift verwendet. Das bedeutet, dass alle Zeichen (auch die Leerzeichen) gleich breit sind. In Abbildung 2.14 sehen Sie, dass die Buchstaben i, j und l genauso breit sind wie m, v und w.

Dn151187.18E6316DD5D213FCB6ED77DE1489B8FF(de-de,TechNet.10).png

Abbildung 2.14: Buchstaben in einer nichtproportionalen Schrift

Im Gegensatz dazu wird in einem Nachrichtenfenster normalerweise eine proportionale Schrift verwendet. Das bedeutet, dass die Breite der Buchstaben unterschiedlich ist. Wie Sie in Abbildung 2,15 sehen, sind die Zeichen i, j und l hier viel schmaler als die Zeichen m, v und w.

Dn151187.19E7F3318DE2D7798E99685F2FAA0F39(de-de,TechNet.10).png

Abbildung 2.15: Zeichenbreite bei einer proportionalen Schrift

Aufgrund dieser unterschiedlichen Zeichenbreiten können Sie nicht einfach davon ausgehen, dass eine Spalte zum Beispiel an Position 20 beginnt und dass die Spalte damit bündig ausgerichtet ist.

In einem String nach Text suchen

Sie haben also nicht immer eine vollständige Kontrolle über den ausgegebenen Text. Stellen wir uns einmal vor, Sie möchten eine Protokolldatei öffnen und feststellen, welche Aktionen fehlgeschlagen und welche erfolgreich waren. In den meisten Fällen enthalten Protokolleinträge sehr viel mehr Text als ein einfaches Erfolgreich oder Fehlgeschlagen. Stattdessen können Einträge zum Beispiel so aussehen:

   MSI: False - MSP: True - CMW: False
   MSISW: REINSTALL=all REINSTALLMODE=vomus /QB /L*V+ C:\WINNT\DEBUG\officexp_sp1.log
   MSPSW: REBOOT=ReallySuppress /QB- /L*V+ C:\WINDOWS\DEBUG\officexp_sp1.log
   InstallFile Result: [0] and Success: True
   Client Maint Wiz: PROPLUS detected

Um hier Erfolg oder Fehlschlag festzustellen, muss Ihr Script den gesamten Text lesen und dann nach den gewünschten Informationen suchen (in diesem Beispiel nach dem Text 'Success: True').

Die Funktion InStr gibt Ihnen die Möglichkeit, nach einem String in einem anderen String zu suchen. Stellen Sie sich zum Beispiel vor, Sie haben eine Protokolldatei mit Hunderten solcher Einträge:

6/1/2002   File a.doc successfully copied
6/1/2002   File b.doc successfully copied
6/1/2002   Error: File c.doc could not be copied
6/1/2002   File d.doc successfully copied

Statt diese nun per Hand zu prüfen, können Sie ein Script schreiben, dass die Protokolldatei Zeilenweise einliest und nur die Zeilen ausgibt, die das Wort "Error" enthalten.

Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Die Funktion InStr wurde für einfache Stringbearbeitung entwickelt. Wenn Sie komplexere Aktionen mit einem String durchführen müssen, dann verwenden Sie reguläre Ausdrücke. Die Verwendung von regulären Ausdrücken liegt jedoch nicht im Themenbereich dieses Buches. Weitere Informationen hierzu finden Sie unter https://www.microsoft.com/windows/reskits/webresources (englischsprachig).

InStr gibt die Zeichenposition zurück, an der der Suchstring gefunden wurde. Nehmen wir an, Sie suchen nach dem Text ment im Wort developmental. In diesem Fall gibt InStr den Wert 8 zurück, da der Text ment an Zeichenposition Acht anfängt.

Dn151187.FE65473935D61AA210F4C280538A7B0D(de-de,TechNet.10).png

Abbildung 2.16: Zeichenpositionen im Wort Developmental

Wenn Sie jedoch nach dem Text mant suchen, dann gibt InStr den Wert 0 zurück. Dieser Rückgabewert bedeutet, dass der Suchstring nicht gefunden wurde.

InStr benötigt zwei Parameter: den String, in dem gesucht werden soll und den String, nach dem gesucht werden soll (der Suchstring). Die folgende Codezeile sucht im Wort developmental zum Beispiel nach dem Text ment:

Wscript.Echo InStr("ment", "developmental")

Sie können die verwendeten Strings auch zu Variablen zuweisen und diese dann in der Funktion verwenden. Das folgende Script sucht im Satz In diesem Text-String wird nach zwei unterschiedlichen Wörtern gesucht nach den Wörtern Strang und Test.

TestString = "In diesem Text-String wird nach zwei unterschiedlichen Wörtern gesucht"
PresentString = "Test"
AbsentString = "Strang"
Wscript.Echo InStr(PresentString, TestString)
Wscript.Echo InStr(AbsentString, TestString)

Wenn Sie das Script ausführen, werden die Werte 11 und 0 zurückgegeben. Der Wert 11 zeigt, dass das Wort Test an Zeichenposition Elf gefunden wurde, und der Wert 0 zeigt, dass das Wort Strang gar nicht gefunden wird.

Groß- und Kleinbuchstaben

Die Kontrolle über die Schrifteigenschaften ist nicht gerade die starke Seite von VBScript. Egal, ob Sie etwas in einer Eingabeaufforderung oder in einem Nachrichtenfenster ausgeben - über Eigenschaften wie Schriftart, -größe und -farbe haben Sie keine Kontrolle. Das Einzige, was Sie verändern können, ist die Groß- und Kleinschreibung.

Mit Großbuchstaben können Sie wichtige Informationen betonen. Die folgende hypothetische Ausgabe ist zum Beispiel besser zu lesen, wenn der fehlerhafte Server schnell zu erkennen ist:

Server         Status
atl-dc-01      Healthy
atl-dc-02      Healthy
ATL-DC-03      ERROR
atl-dc-04      Healthy

Auch für Eingaben kann die Kontrolle über die Groß- und Kleinschreibung ganz nützlich sein. Wenn Sie zum Beispiel sicherstellen möchten, dass der Benutzer ein Landeskürzel (DE, GB, USA) in Großbuchstaben eingibt, dann können Sie die den eingegebenen String einfach in Großbuchstaben umwandeln - so spielt es keine Rolle, was der Benutzer eingegeben hat.

Tabelle 2.15: Funktionen zur Umwandlung in Groß- oder Kleinbuchstaben

Funktion

Beschreibung

LCase

Konvertiert alle alphabetischen Zeichen in Kleinbuchstaben.

Das folgende Codestück konvertiert den String Ulf Dornheck Busscher in den String ulf dornheck busscher.
UserName = "Ulf Dornheck Busscher" Wscript.Echo LCase(UserName)

UCase

Konvertiert alle alphabetischen Zeichen in Großbuchstaben.

Das folgende Codestück konvertiert den String Ulf Dornheck Busscher in den String ULF DORNHECK BUSSCHER.
UserName = "Ulf Dornheck Busscher" Wscript.Echo UCase(UserName)

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Arbeiten mit Zahlen

Vieles im Bereich der Systemadministration hat mit Zahlen zu tun: Über wie viel Speicher verfügt ein Computer? Wie viele fehlgeschlagene Anmeldeversuche gab es? Wie viel Prozessorzeit wird auf einem Domänencontroller verbraucht?

Solche Informationen können über Scripte sehr einfach ermittelt werden. Die Fragen oben können Sie zum Beispiel alle über WMI beantworten. Leider werden Informationen nicht immer im gewünschten Format zurückgegeben. Der freue Plattenplatz wird zum Beispiel in Byte zurückgeliefert - bei einer Festplatte mit ca. 10 GB freiem Speicherplatz erhalten Sie so den Wert 10,842,824,704 Byte zurück. Die Prozessorauslastung wird in 100 Nanosekunden-Schritten angegeben. Die Maximalhöhe und -breite des von einem Drucker unterstützten Papiers wird in Zehntelmillimeter zurückgegeben.

Glücklicherweise bietet VBScript Ihnen einige Funktionen zur Verarbeitung von Zahlen.

Rechenreihenfolge

Die meisten Berechnungen, die Sie als Systemadministrator vornehmen werden, sind sehr einfach - zum Beispiel eine Division durch 1,024, um Byte in KB umzurechnen. Trotzdem müssen Sie vielleicht gelegentlich Berechnungen durchführen, die mehr als eine Rechenart verwenden (zum Beispiel zwei Werte addieren und das Ergebnis durch einen weiteren Wert teilen). Daher müssen Sie wissen, in welcher Reihenfolge VBScript Berechnungen durchführt.

Rechenoperationen (Addition, Subtraktion, Multiplikation und Division) werden von VBScript nicht gleichwertig behandelt. Stattdessen führt VBScript diese in der folgenden Reihenfolge durch:

  1. Division
  2. Multiplikation
  3. Addition
  4. Subtraktion

Warum ist das für Sie wichtig? Schauen Sie sich folgendes Script an. Es addiert zwei Werte, multipliziert diese mit einem dritten, subtrahiert einen vierten und dividiert durch einen fünften:

Wscript.Echo 1 + 2 * 3 - 4 / 5

Wenn Sie das Script ausführen, dann wird der Wert 6,2 ausgegeben. Und so kommt es zu diesem Wert:

  1. Da die Division Vorrang vor allen anderen Rechenoperationen hat, dividiert VBScript als erstes 4 durch 5. Die verbleibende Berechnung sieht nach diesem Schritt so aus:

    1 + 2 * 3 - 0.8

  2. Als nächstes wird multipliziert: 2 und 3 ergibt 6. Die verbleibende Berechnung sieht so aus:

    1 + 6 - 0.8

  3. Die Addition ist die nächste Berechnung; 1 und 6 ergibt 7

    7 - 0.8

  4. Als letztes wird die Subtraktion durchgeführt: 7 minus 0,8 ist 6,2.

Nun könnte es natürlich sein, dass dies nicht die von Ihnen gewünschte Rechenreihenfolge ist. Stattdessen wollten Sie folgende Berechnung durchführen:

  1. Addition 1 + 2
  2. Ergebnis mit 3 multiplizieren
  3. 4 subtrahieren
  4. Ergebnis durch 5 dividieren

Damit dies so passiert, müssen Sie Klammern verwenden. Sie zeigen VBScript die richtige Rechenreihenfolge. Klammern haben immer Vorrang - egal welche Rechenoperation verwendet wird. Wenn mehrere verschachtelte Klammern verwendet werden, dann werden die Berechnungen immer von der innersten Klammer zur äußersten Klammer durchgeführt (die innerste Klammer wird also als erstes berechnet).

Wscript.Echo (((1 + 2) * 3) - 4) / 5

Formatierung von Zahlen

Sich selbst überlassen formatiert VBScript Zahlen immer gleich. Erinnern wir uns an eines der ersten Scripte dieses Kapitels: es gab den freien Plattenplatz für ein Laufwerk zurück. Der zurückgegebene Wert war 10842824704. Er war ziemlich schwer zu lesen - besser wäre eine Ausgabe wie 10.842.824.704 gewesen.

Eine Berechnung weiter oben in diesem Kapitel gab zum Beispiel den Wert 10340,4458007813 zurück. Wenn überhaupt, dann werden Sie eine so genaue Kommazahl nur ganz selten benötigen. Es wäre besser, wenn der Wert als 10.340 oder 10.340,45 zurückgegeben würde. Diese Ausgaben sind nicht nur besser zu lesen, sie benötigen auch weniger Anzeigeplatz. Das könnte zum Beispiel wichtig werden, wenn Sie Ausgaben in Tabellenform durchführen möchten.

Mit der Funktion FormatNumber können Sie definieren, wie Zahlen ausgegeben werden. Sie erwartet als Parameter die zu formatierende Zahl und eine oder alle Parameter aus Tabelle 2.16. Die folgende Codezeile gibt die Zahl 37,874 zum Beispiel ohne Nachkommastellen aus - es wird als nur 37 angezeigt:

Wscript.Echo FormatNumber(37.874, 0)

Tabelle 2.16: Paramter von FormatNumber

Parameter

Beschreibung

Zahl der Nachkomma-
stellen.

Die Funktion FormatNumber löscht nicht angezeigte Nachkommastellen nicht einfach. Stattdessen werden sie auf- oder abgerundet. Wenn Sie die Zahl 11,6 zum Beispiel ohne Nachkommastellen anzeigen lassen, dann wird die Zahl 12 angezeigt. Im Gegensatz dazu ergäbe 19,2 die Zahl 19.

Wenn Sie statt der Zahl der Nachkommastellen den Wert -1 verwenden, dann werden die Einstellungen aus den Regional- und Spracheinstellung des Computers verwendet.

Führende Null.

Mögliche Werte:

-1 - True. Mit führender 0.

0 - False. Ohne führende 0

-2 - Einstellungen aus Regional- und Spracheinstellungen verwenden.

Negative Zahlen in Klammern.

Mögliche Werte:

-1 - True. Negative Zahlen in Klammern.

0 - False. Keine Klammern.

-2 - Einstellungen aus Regional- und Spracheinstellungen verwenden.

Tausender-Trennzeichen.

Mögliche Werte:

-1 - True. Mit Tausender-Trennzeichen.

0 - False. Ohne Tausender-Trennzeichen

-2 - Einstellungen aus Regional- und Spracheinstellungen verwenden.

Damit Ihr Script einfacher zu lesen und zu pflegen sein wird, können Sie statt der in der Tabelle gezeigten Werte auch Konstanten verwenden. In der folgenden Scriptzeile ist zum Beispiel nicht unbedingt sofort klar, wofür die 0 steht:

Wscript.Echo FormatNumber(37.874, 0)

Mit einer Konstante ist das Script viel einfacher zu lesen:

Const NoDecimalPlaces = 0
Wscript.Echo FormatNumber(37.874, NoDecimalPlaces)

Alle Formatierungsparameter sind optional. Sie können durchaus alle Parameter ignorieren und nur das Tausender-Trennzeichen verwenden. Dieser Parameter muss allerdings immer der fünfte Parameter sein (nach den Nachkommastellen und den drei anderen optionalen Parametern). Wenn Sie nur einzelne Parameter verwenden möchten, dann haben Sie die folgenden Möglichkeiten:

  • Verwenden Sie "leere" Parameter (schreiben Sie für die Parameter, die Sie nicht verwenden möchten, also nur ein Komma ohne Wert).
  • Verwenden Sie für die nicht verwendeten Parameter den Standardwert. Setzen Sie diese hierzu einfach auf False (Falsch).

Im folgenden Script werden zum Beispiel Konstanten mit den entsprechenden Werten verwendet:

Const Decimals = 3
Const LeadingZero = True
Const UseParentheses = True
Const Default = False
NumberToFormat = 1 / -7
Wscript.Echo NumberToFormat
Wscript.Echo FormatNumber(NumberToFormat, Decimals)
Wscript.Echo FormatNumber(NumberToFormat, Default, LeadingZero)
Wscript.Echo FormatNumber(NumberToFormat, Default, Default, UseParentheses)

Wenn Sie das Script unter CScript ausführen, erhalten Sie folgende Ausgabe:

-0,142857142857143
-0,143
-0,14
(0,14)

Einen alternativen Weg sehen Sie im folgenden Script. Es formatiert das Ergebnis der Multiplikation von 33 mit 454:

Const GroupDigits = True
Const Default = False
Const NoDecimals = 0
NumberToFormat = 33 * 454
Wscript.Echo NumberToFormat
Wscript.Echo FormatNumber(NumberToFormat, Default, Default, Default, GroupDigits)
Wscript.Echo FormatNumber _
    (NumberToFormat, NoDecimals , Default, Default, GroupDigits)

Wenn Sie dieses Script unter CScript ausführen, dann erhalten Sie folgende Ausgabe:

14982
14,982.00
14,982

Prozentwerte formatieren

Manchmal sind Prozentwerte nützlicher als reine Zahlen. Die Maximalgröße des Ereignisprotokolls kann zum Beispiel von Computer zu Computer unterschiedlich sein. Daher wissen Sie nach der Abfrage der aktuellen Größe des Ereignisprotokolls (zum Beispiel über WMI) nicht, wie voll das Protokoll tatsächlich ist. Besser wäre es, die prozentuale Auslastung des Ereignisprotokolls abzufragen.

Wenn Sie Prozentwerte abfragen, dann sollten Sie diese auch als Prozentwerte anzeigen. Wenn das Ereignisprotokoll zum Beispiel maximal 5.000.000 Byte groß werden kann und die aktuelle Größe 3.127.354 Byte ist, dann können Sie 3.127.354 durch 5.000.000 teilen. Sie erhalten als Ergebnis den Wert 0,6254708 zurück. Dieses Ergebnis wäre als Prozentwert (63%) viel aussagekräftiger.

Die Funktion FormatPercent konvertiert eine Zahl in einen Prozentwert; das bedeutet, dass sie die Zahl mit 100 multipliziert und ein Prozentzeichen anhängt. FormatPercent akzeptiert die gleichen Formatierungsparameter wie FormatNumber:

  • Nachkommastellen
  • Führende Null bei Kommawerten, die kleiner als 1 und größer als -1 sind
  • Negative Werte in Klammern
  • Tausender-Trennzeichen (6.500.000% statt 6500000%)

Die Syntax der Funktion FormatPercent ist identisch mit der Funktion FormatNumber:

Das folgende Script dividiert 1 durch 7 und gibt das Ergebnis aus. Es verwendet FormatPercent, um die Ausgabe als Prozentwert ohne Nachkommastellen zu formatieren.

Const NoDecimals = 0
NumberToFormat = 1 / 7
Wscript.Echo NumberToFormat
Wscript.Echo FormatPercent(NumberToFormat, NoDecimals)
Wenn Sie das Script unter CScript ausführen, dann erhalten 
Sie folgende Ausgabe:
0,142857142857143
14%

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Befehle mehrfach ausführen

Ein Grund dafür, dass die Systemadministration so schwierig und zeitaufwändig ist, liegt darin, dass IT-Umgebungen dynamisch sind. Das bedeutet, dass Systemadministratoren dieselben Aufgaben wieder und wieder ausführen müssen. Wenn ein Computer heute über ausreichend freien Festplattenplatz verfügt, dann muss das morgen oder nächsten Monat nicht ebenfalls so sein.

Zum Glück wird Scripten nie langweilig. Sie werden auch nie müde oder machen Fehler, wenn sie eine Aufgabe ständig wiederholen müssen. Ein Script wird so zum perfekten Instrument, um sich ständig wiederholende Aufgaben auszuführen. Hierzu steht Ihnen unter VBScript die Do-Loop-Schleife zur Verfügung.

Do Loop

Eine Do-Loop-Schleife ermöglicht es Ihnen dieselben Befehle so lange auszuführen, bis eine bestimmte Bedingung eingetreten ist - zum Beispiel, wenn Sie den freien Festplattenplatz so lange überwachen möchten, bis dieser unter einen bestimmten Wert fällt. Im Gegensatz zur For-Next-Schleife können Sie mit der Do-Loop-Schleife Befehle für einen bestimmten Zeitraum ausführen.

VBScript unterstützt zwei Arten von Do-Loop-Schleifen: Do Until und Do While. Die Do-Until-Schleife wird so lange ausgeführt, bis eine bestimmte Bedingung zutrifft (wahr ist). Das folgende Script verwendet das Objekt FileSystemObject, um eine Textdatei zu öffnen und diese dann Zeile für Zeile auszulesen. Hierzu ist der Code zum Auslesen der Textzeilen in einer Schleife platziert. Diese wird so lange ausgeführt, bis (until) das Ende der Datei (Ende des Textstreams - End Of Stream) erreicht ist. Die Bedingung für diese Schleife sieht so aus:

Do Until objTextFile.AtEndOfStream

Diesen Befehl können Sie auch so lesen: "Führe die Schleife so lange aus, bis das Ende der Datei erreicht ist".

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
    ("c:\test.txt", ForReading)
Do Until objTextFile.AtEndOfStream
    strNextLine = objTextFile.Readline
    Wscript.Echo strNextLine
Loop

Wenn das Script ausgeführt wird, wird die Schleifenbedingung bei jedem Durchlauf geprüft. Wenn die Bedingung wahr (True) ist - wenn also das Dateiende erreicht ist - dann wird die Schleife nicht mehr weiter ausgeführt.

Im Gegensatz dazu wird eine Do-While-Schleife so lange ausgeführt, wie die Bedingung nicht zutrifft (also falsch ist - False). Das folgende Script verwendet hierzu die Syntax:

Do While Not objTextFile.AtEndOfStream

Diese Scriptzeile könnte übersetzt lauten "Führe die Schleife so lange aus, wie das Ende der Textdatei nicht erreicht ist".

Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
    ("c:\test.txt", ForReading)
Do While Not objTextFile.AtEndOfStream
    strNextLine = objTextFile.Readline
    Wscript.Echo strNextLine
Loop

Endlosschleifen

Vielleicht haben Sie es sich schon gedacht: Es ist möglich Endlosschleifen zu erstellen - diese werden nie beendet (wenn die Bedingung niemals zutrifft, dann wird die Schleife unendlich ausgeführt). Meist handelt es sich bei solchen Schleifen um einen Fehler des Scripterstellers. Es könnte jedoch auch sein, dass Sie zum Beispiel ein Script benötigen, das Sie bei jedem Fehler im Ereignisprotokoll benachrichtigt. Sie möchten nicht, dass das Script nach dem ersten Fehler beendet wird; stattdessen möchten Sie, dass es in einer Endlosschleife auf weitere Fehler wartet.

Um ein Script mit einer solchen Schleife zu erstellen, verwenden Sie einfach eine Bedingung, die niemals zutreffen kann. Das folgende Script macht dies, indem es die Schleife so lange ausführt, bis die Variable LoopVariable den Wert 0 hat. Da das Script jedoch nie etwas an dem Wert von LoopVariable ändert, wird diese Bedingung niemals zutreffen.

LoopVariable = 1
Do Until LoopVariable = 0
    FreeMegaBytes = objLogicalDisk.FreeSpace / CONVERSION_FACTOR
    If FreeMegaBytes < WARNING_THRESHOLD Then
        Wscript.Echo Computer & " " & objLogicalDisk.DeviceID & _
            " is low on disk space."
    End If
Loop

Dieses Script müssen Sie bei Bedarf dann natürlich auch manuell beenden.

Prüfen der Schleifenbedingung

Die Schleifenbedingung können Sie unter VBScript an zwei Stellen der Schleife prüfen: Entweder bevor die Schleife ausgeführt wird, oder nachdem die Schleife ausgeführt wurde. Dies kann durchaus ein Unterschied sein. Wenn Sie möchten, dass die Schleife nur dann ausgeführt wird, wenn die Bedingung zutrifft, dann prüfen Sie die Bedingung vor der Schleifenausführung. Wenn Sie sicherstellen möchten, dass die Schleife mindestens einmal ausgeführt wird (egal, ob die Bedingung zutrifft oder nicht), dann prüfen Sie die Bedingung am Ende der Schleife.

Das folgende Script verdeutlicht den Unterschied zwischen den beiden Varianten. Nachdem Die Variable LoopVariable auf den Wert 1 gesetzt wurde, verwendet das Script zwei Schleifen. In der ersten Schleife wird die Bedingung vor dem Schleifendurchlauf geprüft. Die Syntax hierzu lautet:

Do Until LoopVariable = 1

Die zweite Schleife prüft die Bedingung erst nach dem Schleifendurchlauf. Die entsprechende Syntax lautet:

Loop Until LoopVariable = 1

Das Script selbst sieht so aus:

LoopVariable = 1
Do Until LoopVariable  = 1
    Wscript.Echo "Script ist in Schleife 1."
Loop
Do
    Wscript.Echo "Script ist in Schleife 2."
Loop Until LoopVariable  = 1

Wenn Sie das Script ausführen, dann erhalten Sie folgende Ausgabe:

Script ist in Schleife 2

Wie Sie sehen können, wird Schleife 2 einmal ausgeführt. Schleife 1 wird gar nicht ausgeführt.

Woher kommt dieser Unterschied? In der ersten Schleife ist die Bedingung (wenn die Variable LoopVariable gleich 1 ist) vor der Ausführung der Schleife getestet. Da LoopVariable den Wert 1 hat, wird die Do-Loop-Schleife sofort beendet. Sie wird also nicht einmal ausgeführt.

In der zweiten Schleife wird die Bedingung erst dann getestet, wenn die Schleife ausgeführt wurde. Der genaue Ablauf sieht also so aus:

  1. Die Schleife beginnt mit dem Befehl Do Loop
  2. In der Schleife wird der Text 'Script ist in Schleife2' ausgegeben
  3. Am Ende der Schleife wird die Bedingung geprüft (ist die Variable LoopVariable gleich 1?). Das ist wahr. Daher wird die Schleife beendet, nachdem sie einmal ausgeführt wurde.

Mit dem Befehl Loop Until wird jede Schleife als mindestens einmal ausgeführt. Wenn Sie dies nicht möchten, dann verwenden Sie den Befehl Do Until.

Eine Schleife verlassen

VBScript arbeitet standardmäßig jede Zeile Code innerhalb einer Do-Loop-Schleife nacheinander ab. In den meisten Fällen ist das auch genau das, was Sie möchten. Es mag jedoch auch Ausnahmen geben, in denen Sie eine Schleife sofort verlassen möchten - und zwar ohne den restlichen Code in der Schleife abzuarbeiten. Dies können Sie mit dem Befehl Exit Do erreichen. Er sorgt dafür, dass diese Schleife sofort beendet wird.

Das folgende Script erzeugt einen Fehler (5 geteilt durch 0). Die Schleifenbedingung sagt: "Führe die Schleife aus, bis ein Fehler auftritt" (Err 0). Sie könnten also annehmen, dass die Schleife bei dem Versuch 5 durch 0 zu teilen beendet wird (das wäre ja ein Fehler).

On Error Resume Next
Do Until Err <> 0
    X = 5/0
    Wscript.Echo " Das Ergebnis ist " & X & "."
Loop

Wenn Sie das Script ausführen, dann erhalten Sie jedoch die folgende Ausgabe:

Dn151187.6A86D628DEADE476F1DDD9115226F045(de-de,TechNet.10).png

Abbildung 2.17: Fehlerhaftes Nachrichtenfenster

Warum ist das so? Wenn das Script den Fehler durch die Division durch 0 feststellt, dann wird die Schleife nicht verlassen - obwohl dies in der Bedingung so angegeben ist. Stattdessen werden die verbleibenden Befehle der Schleife weiter abgearbeitet. Das liegt daran, dass die Schleifenbedingung nur einmal pro Durchlauf geprüft wird (am Anfang). So wird nach dem Fehler noch die Ausgabe durchgeführt (X enthält den Wert Null). Erst dann wird vor dem nächsten Vorlauf die Schleifenbedingung erneut geprüft und die Schleife beendet.

Wenn Sie eine Schleife vor der Beendigung eines Durchlaufes verlassen müssen, dann verwenden Sie den Befehl Exit Do. Im folgenden Script wird die Fehlerbedingung innerhalb der Schleife getestet. Wenn ein Fehler aufgetreten ist, dann wird eine Fehlermeldung ausgegeben, und die Schleife wird über den Befehl Exit Do sofort beendet.

On Error Resume Next
Do Until Err <> 0
    X = 5/0
    If Err <> 0 Then
        Wscript.Echo "Es ist ein Fehler aufgetreten."
        Exit Do
    End If
        Wscript.Echo " Das Ergebnis ist " & X & "."
Loop

Wenn Sie dieses Script ausführen, dann erhalten Sie die folgende Anzeige:

Dn151187.2278E269628102017C7EA9A3EC00D9D8(de-de,TechNet.10).png

Abbildung 2.18: Das Nachrichtenfenster zeigt an, dass ein Fehler aufgetreten ist

Wie Sie sehen können, wurde die Schleife beendet, bevor die Ergebnisausgabe durchgeführt wird.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Entscheidungen treffen

Ein Script wird normalerweise sequenziell ausgeführt. Das heißt, Zeile 1 wird abgearbeitet, dann Zeile 2, Zeile 3 usw. bis die letzte Zeile abgearbeitet wurde.

Im Allgemeinen wird das Schreiben von Scripten durch diese Tatsache einfacher. Nachdem ein Script gestartet wurde, können Sie davon ausgehen, dass es alle Zeilen korrekt ausführt und dann beendet wird. Das Ausführen jeder Zeile des Scripts kann jedoch aus zu Komplikationen führen. Was passiert, wenn es Zeilen gibt, die Sie nicht ausführen wollen?

Nehmen wir einmal ein, Sie haben ein Script geschrieben, dass eine bestimmte Gruppe von Dateien auf einen Remotecomputer sichert und die Originaldateien dann löscht. Solange keine Probleme auftauchen, möchten Sie auch, dass jede Zeile des Scripts ganz normal ausgeführt wird. Was ist aber, wenn der Remotecomputer nicht erreichbar ist? In diesem Fall versucht das Script die Dateien auf den Remotecomputer zu sichern. Dies schlägt dann natürlich fehl. Dann löscht das Script die Originaldateien. Problem erkannt?

In einem Fall wie diesem wünschen Sie sich sicherlich ein Script, das eine bestimmte Bedingung überprüfen kann ("Ist der Remotecomputer erreichbar?") und nur weiterarbeitet, wenn diese Bedingung wahr ist. Eine solche Entscheidung können Sie über die Befehle If Then oder Select Case implementieren.

Mehrere Bedingungen prüfen

Die Scripte, die in der ersten Hälfte dieses Kapitels verwendet wurde, trafen ihre Entscheidungen auf Basis einer einzelnen Bedingung. Wenn zum Beispiel die Menge an freiem Speicherplatz unter einen bestimmten Wert gefallen ist, dann wird ein Alarm ausgelöst:

If FreeMegaBytes < WARNING_THRESHOLD Then
    Wscript.Echo objLogicalDisk.DeviceID & " is low on disk space."
End If

Es könnte jedoch vorkommen, dass Sie eine bestimmte Aktion nur dann durchführen möchten, wenn zwei oder mehr Bedingungen zutreffen. Eine sofortige Alarmmeldung benötigen Sie zum Beispiel nur für die Mailserver. Bei allen anderen Servern möchten Sie nicht sofort benachrichtigt werden. Stattdessen soll zum Beispiel nur ein Protokolleintrag erzeugt werden.

Der Alarm soll also nur dann angezeigt werden, wenn zwei Bedingungen wahr sind: der freie Plattenplatz liegt unter einer bestimmten Grenze und der Server ist ein Mailserver. Eine solche Entscheidung können Sie über den logischen Operator And (Und) implementieren.

Im folgenden Script wird die Alarmmeldung nur in diesem Fall angezeigt. Wenn eine der beiden Bedingungen nicht wahr ist, dann wird kein Alarm angezeigt.

If FreeMegaBytes < WARNING_THRESHOLD And ServerType = "Email" Then
    Wscript.Echo objLogicalDisk.DeviceID & " is low on disk space."
End If

In anderen Fällen kann es zum Beispiel wichtig sein, eine Aktion durchzuführen, wenn eine oder einige der Bedingungen wahr sind. Zum Beispiel, wenn Sie eine Meldung anzeigen möchten, wenn der freie Speicherplatz unter einer bestimmten Grenze liegt, oder wenn der verfügbare Arbeitsspeicher unter eine bestimmten Grenze liegt. In Tabelle 2.17 sehen Sie alle möglichen Zustände und Entscheidungen für ein solches Script

Tabelle 2.17: Entscheidungsmatrix

Ausreichend Speicherplatz

Ausreichen Arbeitsspeicher

Alarmmeldung

Ja

Ja

Nein

Ja

Nein

Ja

Nein

Ja

Ja

Nein

Nein

Ja

Solche Entscheidungen können Sie mit dem logischen Operator Or (Oder) implementieren:

If FreeMegaBytes < WARNING_THRESHOLD Or AvailableMemory < MEMORY_THRESHOLD Then
    Wscript.Echo "Computer is low on disk space or memory."
End If

Der logische Operator Or (Oder) gibt Wahr zurück, wenn irgendeine der Bedingungen wahr ist (oder wenn alle wahr sind).

If Then ElseIf

Systemadministratoren müssen oft Entweder/Oder-Entscheidungen treffen. Entweder der Computer hat genügend Festplattenplatz oder nicht. In solchen Situationen bietet Ihnen das If-Then-Else-Konstrukt eine optimale Möglichkeit eine Bedingung mit minimalem Programmieraufwand zu implementieren.

Natürlich kann es sein, dass es mehr als zwei mögliche Bedingungen gibt. Stellen Sie sich zum Beispiel vor, Sie möchten die Wartung von Festplatten nach den folgenden Kriterien entscheiden:

  • Ein Laufwerk mit weniger als 100 MB verfügbarem Speicherplatz benötigt Ihre sofortige Aufmerksamkeit.
  • Um ein Laufwerk mit weniger als 250 MB und mehr als 100 MB freiem Speicherplatz können Sie sich bei Gelegenheit kümmern.
  • Ein Laufwerk mit mehr als 250 MB freiem Speicherplatz benötigt keine Aufmerksamkeit.

Um mehrere Alternativen zu implementieren, können Sie den If-Then-Else-Befehl verwenden. Mit diesem prüft das Script ganz normal die Bedingung (zum Beispiel x = 1). Wenn diese wahr ist, dann führt das Script die entsprechende Aktion aus. Wenn die Bedingung jedoch nicht wahr ist, dann können Sie eine zweite Bedingung prüfen lassen. Die Syntax hierzu sieht so aus:

ElseIf x = 2 Then

Sie können so viele ElseIf-Befehle verwenden, wie Sie möchten. Statt des letzten ElseIf-Befehls, verwenden Sie einen einfachen Else-Befehl.

Das folgende Script zeigt - abhängig von den folgenden Bedingungen - jeweils unterschiedliche Meldungen an

  • Weniger als 100 MB verfügbarer Speicherplatz
  • Weniger als 250 MB und mehr als 100 MB freier Speicherplatz
  • Mehr als 250 MB freier Speicherplatz
If FreeMegabytes <= 100 Then
    Wscript.Echo Computer.Name & " benötigt sofortige Aufmerksamkeit."
ElseIf FreeMegabytes < 250 Then
    Wscript.Echo Computer.Name & " sollten Sie so schnell wie möglich überprüfen."
Else
    Wscript.Echo Computer.Name & " verfügt über genügend Speicherplatz."
End If

Wenn Sie mehrere Bedingungen implementieren, dann prüft If-Then-Else alle Bedingungen, bis eine Bedingung gefunden wird, die wahr ist. In diesem Fall werden die Befehle hinter dieser Bedingung ausgeführt und keine weiteren Bedingungen mehr geprüft. Das bedeutet natürlich, dass Sie die Bedingungen sehr gewissenhaft anordnen müssen.

Sehen wir uns zum Beispiel einmal das folgende Script an:

x = 5
If x < 20 Then
    Wscript.Echo "X ist zwischen 11 und 20."
ElseIf x < 11 Then
    Wscript.Echo " X ist zwischen 0 und 10."
Else
    Wscript.Echo "X ist gleich 0."
End If

Die Ausgabe des Scripts sehen Sie in Abbildung 2.19

Dn151187.D720AD8B9783EA24A19E97EAD30F2D89(de-de,TechNet.10).png

Abbildung 2.19: Falsche Anordnung von Bedingungen

Woher kommt dieses falsche Ergebnis? Die erste Bedingung prüft, ob X kleiner als 20 ist. Da dies immer wahr ist, wird natürlich auch immer die Nachricht 'X ist zwischen 11 und 20" ausgegeben. Nachdem die erste Bedingung wahr ist, werden keine weiteren Bedingungen geprüft.

Damit das Script korrekt arbeitet, müssen Sie die Bedingungen neu anordnen:

x = 5
If x = 0 Then
    Wscript.Echo "X ist gleich 0."
ElseIf x < 11 Then
    Wscript.Echo " X ist zwischen 0 und 10."
Else
    Wscript.Echo " X ist zwischen 11 und 20."
End If

Einen Else-Befehl im Ende zu verwenden ist immer eine gute Idee. So können Sie auch die Fälle abfangen, in denen keine der ElseIf-Bedingungen zutrifft. Sehen Sie sich zum Beispiel das folgende Script an:

If JobID = 1 Then
    Wscript.Echo "Dieser Benutzer ist ein Manager."
ElseIf JobID = 2 Then
    Wscript.Echo " Dieser Benutzer ist kein Manager."
End If

Es funktioniert sehr gut, solange jedem Benutzer eine JobID von 1 oder 2 zugewiesen wurde. Was passiert aber, wenn die JobID eines Benutzers 3 ist (oder wenn der Benutzer keine JobID hat)? Diesen Fall können Sie über einen abschließenden Else-Befehl abfangen:

If JobID = 1 Then
    Wscript.Echo "Dieser Benutzer ist ein Manager."
ElseIf JobID = 2 Then
    Wscript.Echo " Dieser Benutzer ist kein Manager."
End If
    Wscript.Echo "Diesem Benutzer wurde keine gültige Job-ID zugewiesen."
End If

Select Case

Der Befehl Select-Case ist eine strukturiertere Alternative zum Befehl If-Then-ElseIf. Wenn Sie mehr als drei Bedingungen überprüfen müssen, dann ist er meistens schneller und einfacher zu implementieren. Das folgende Script verwendet den Select-Case-Befehl zum Beispiel, um die WMI-Rückgabewerte zum Druckerstatus auszuwerten:

Select Case PrinterStatus
    Case 1 strCurrentState = "Other"
    Case 2 strCurrentState = "Unknown"
    Case 3 strCurrentState = "Idle"
    Case 4 strCurrentState = "Printing"
    Case 5 strCurrentState = "Warming Up"
End Select

Die gleiche Aufgabe mit If-Then-ElseIf-Befehlen zu lösen führt zu einem mehr als doppelt so langen Script, dass schwer zu lesen ist:

If PrinterStatus = 1 Then
    strCurrentState = "Other"
ElseIf PrinterStatus = 2 Then
    strCurrentState = "Unknown"
ElseIf PrinterStatus = 3 Then
    strCurrentState = "Idle"
ElseIf PrinterStatus = 4 Then
    strCurrentState = "Printing"
ElseIf PrinterStatus = 5 Then
    strCurrentState = "Warming Up"
End Select

Der Select-Case-Befehl wird folgendermaßen verwendet:

  1. Beginnen Sie den Befehlsblock mit dem Befehl Select Case und dem Namen der Variable, die Sie auswerten möchten.
  2. Fügen Sie für jeden potentiellen Wert der Variable einen Case-Befehl ein. Diesem Case-Befehl muss dann jeweils der Scriptcode folgen, der ausgeführt werden soll, wenn die Variable den mit Case angegebenen Wert enthält.
  3. Beenden Sie den Select-Case-Block mit einem abschließenden End-Select-Befehl.

Wenn keine der Case-Bedingungen zutrifft, dann können Sie diesen Fall mit einem abschließenden Case-Else-Befehl abfangen:

Select Case PrinterStatus
    Case 1 strCurrentState = "Other"
    Case 2 strCurrentState = "Unknown"
    Case 3 strCurrentState = "Idle"
    Case 4 strCurrentState = "Printing"
    Case 5 strCurrentState = "Warming Up"
    Case Else strCurrentState = "Status cannot be determined."
End Select

Außerdem haben Sie die Möglichkeit, die Case-Bedingung in eine eigene Zeile zu schreiben. Dieser Zeile können dann beliebig viele Zeilen mit Anweisungen für diesen Fall folgen:

Case 1
    strCurrentState = "Other"
    Wscript.Echo strCurrentState
Case 2

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Arrays

Scripte sind wohl am nützlichsten, wenn Sie dieselbe Aufgabe mehrfach ausführen können. Wenn Sie zum Beispiel nur über einen Computer verfügen, dann ist es nicht sehr mühsam, das Snap-In Dienste aufzumachen, und einfach zu schauen, welche Dienste installiert sind. Ein Script hierfür zu schreiben dürfte wohl deutlich länger dauern. Wenn Sie jedoch 100 Computer betreuen, dann ziehen Sie es sicher vor, wenn ein Script diese Aufgabe für Sie erledigt.

Wenn ein Script Informationen von 100 Computern abfragen soll, dann muss es natürlich deren Namen irgendwo speichern. Außerdem muss es sich merken können, von welchen Computern es bereits Informationen abgefragt hat und von welchen nicht. Ein Standardweg zur Speicherung solcher Informationen ist die Verwendung von Arrays (Felder). Ein Array ist ein bestimmter Variablentyp, der mehrere Werte speichern kann.

Dn151187.note(de-de,TechNet.10).gifAnmerkung:

Eine vollständige Besprechung zu Arrays - insbesondere die Verwendung von mehrdimensionalen Arrays - liegt außerhalb des Themenbereichs dieses Kapitels. Das Kapitel konzentriert sich auf die Verwendung von Arrays in administrativen Scripten.

Erstellen von Arrays

Der einfachste Weg ein Array zu erstellen, ist die Funktion Array. Auch wenn das wirklich ganz einfach ist, sollten Sie zwei Dinge bei der Verwendung der Array-Funktion bedenken. Erstens können mit der Array-Funktion nur eindimensionale Arrays erstellt werden. Und zweitens müssen Sie bei dieser Funktion alle Elemente des Arrays bereits im Voraus kennen. Bei administrativen Aufgaben ist das normalerweise nicht der Fall - meist schreiben Sie ein Script, um genau diese Elemente (zum Beispiel die Dienste oder die Computer in einer OU) abzurufen.

Wenn Sie die Elemente des Arrays bereits kennen, dann ist die Funktion Array natürlich trotzdem sehr nützlich. Ein Script in der ersten Hälfte dieses Kapitels sollte zum Beispiel auf drei Computern ausgeführt werden. Mit der Funktion Array können Sie die Namen dieser drei Computer in ein Array schreiben:

Computers = Array("atl-dc-01", "atl-dc-02", "atl-dc-03")

Ein Array deklarieren und füllen

Normalerweise kennen Sie die zu speichernden Elemente vorher nicht. Das Script könnte die Computernamen zu Beispiel aus einer Textdatei einlesen oder die in einem Ordner enthaltenen Dateinamen in einem Array speichern. In einem solchen Fall kennen Sie die Elemente und deren Anzahl erst dann, wenn das Script ausgeführt wird.

Unter VBScript haben Sie die Möglichkeit, eine Variable als Array zu definieren. Diese Variable müssen Sie nicht sofort mit Elementen füllen. Hierzu legen Sie mit dem Befehl Dim die Variable und die maximale Anzahl der in ihr gespeicherten Elemente fest.

Das erste Element eines Arrays wird immer durch die Indexnummer 0 bezeichnet - nicht durch 1. Die Indexnummer des letzten Elementes eines Arrays entspricht der Maximalzahl an Elementen minus 1. Wenn Ihr Array also 9 Elemente aufnehmen soll, dann müssen Sie es über den Dim-Befehl mit der Größe 8 definieren (9 - 1).

Das folgende Beispiel erstellt einen Array mit dem Namen arrTestArray und der Größe 4 (4 - 1 = 3):

Dim arrTestArray(3)

Nachdem Sie einen Array deklariert haben, können Sie ihn mit den gewünschten Werten auffüllen. Die nächste Codezeile weist Element 0 des Arrays (das erste Element) zum Beispiel den Wert "A" zu:

arrTestArray(0) = "A"

Dieses einfache Script erstellt einen Array mit dem Namen arrTestArray und weist den vier Elementen des Arrays Werte zu:

Dim arrTestArray(3)
arrTestArray(0) = "A"
arrTestArray(1) = "B"
arrTestArray(2) = "C"
arrTestArray(3) = "D"

So weit so gut. Was passiert aber, wenn Sie den Array ursprünglich zu klein deklariert haben? Was, wenn arrTestArray fünf Werte aufnehmen soll? Wenn Sie einfach versuchen dem fünften Elemente einen Wert zuzuweisen, dann werden Sie einen Fehler produzieren. Das folgende Beispielscript versucht einem Array mit vier Elementen einen fünften Wert zuzuweisen:

Dim arrTestArray(3)
arrTestArray(0) = "A"
arrTestArray(1) = "B"
arrTestArray(2) = "C"
arrTestArray(3) = "D"
arrTestArray(4) = "E"

Wie Sie sehen, erzeugt das Script den Fehler "Index außerhalb des gültigen Bereichs: ,(number: 4)' wenn Sie versuchen es auszuführen.

In einer solchen Situation haben Sie zwei Möglichkeiten:

  • Sie können den Array schon im Voraus größer machen. Sie deklarieren arrTestArray einfach mit 1.000 Elementen statt mit 4 Elementen. Das wäre allerdings in vielen Fällen eine sinnlose Speicherverschwendung, da Sie viele der Elemente ja gar nicht verwenden.
  • Sie erstellen einen dynamischen Array.

Dynamische Arrays erstellen

Ein dynamisches Array bietet Ihnen zwei Vorteile:

  • Sie müssen die Maximalgröße des Arrays nicht im Voraus festlegen.
  • Die Größe des Arrays kann während der Ausführung des Scripts verändert werden.

Wenn Sie zum Beispiel die Computernamen aus einer Textdatei einlesen, und das Array ist zu klein, dann können Sie das Array für jeden weiteren Computernamen einfach vergrößern - und zwar so lange, bis alle Computernamen gelesen und gespeichert wurden. Um ein dynamisches Array zu erstellen, müssen Sie zwei Dinge tun: Erstens dürfen Sie bei der Deklaration des Arrays keine Größe angeben. Stattdessen schreiben Sie einfach zwei Klammern:

Dim arrTestArray()

Und zweitens müssen Sie den Befehl ReDim Preserve verwenden, um das Array zu vergrößern. Dieser Befehl erfüllt zwei Aufgaben:

  • Der Teil ReDim sorgt für die Vergrößerung des Arrays.
  • Der Teil Preserve stellt sicher, dass die vorhandenen Inhalte des Arrays bei diesem Vorgang nicht gelöscht werden. Wenn Sie nur den Befehl ReDim verwenden, dann werden alle Array-Inhalte bei der Vergrößerung gelöscht.

Das folgende Script erstellt ein dynamisches Array mit dem Namen arrTestArray. Danach wird eine Variable mit dem Namen intSize erstellt. Dieser wird der Wert 0 zugewiesen. Mit der Variable wird dann das Array so neudimensioniert, dass es ein Element aufnehmen kann (1 - 1 = 0).

Nachdem dem ersten Element (Index 0) ein Wert zugewiesen wurde, wird der Befehl ReDim Preserve verwendet, um das Array so zu vergrößern, dass es zwei Elemente aufnehmen kann (intSize + 1). Dem zweiten Element wird dann ebenfalls ein Wert zugewiesen:

Dim arrTestArray()
intSize = 0
ReDim Preserve arrTestArray(intSize)
arrTestArray(intSize) = "A"
ReDim Preserve arrTestArray(intSize + 1)
arrTestArray(intSize + 1) = "B"

Um zu zeigen, wie der Befehl ReDim Preserve in einem echten Script zur Systemadministration verwendet werden kann, fragt das folgende Scripte eine Liste aller auf dem Computer installierten Dienste ab. Es speichert die Dienstnamen in einem dynamischen Array. Hierzu geht es folgendermaßen vor:

  1. Es erstellt ein dynamisches Array mit dem Namen arrTestArray.
  2. Es erstellt eine Variable mit dem Namen intSize und weist dieser den Wert 0 zu.
  3. Es verbindet sich mit dem WMI-Dienst und fragt eine Liste der installierten Dienste ab.
  4. Für jeden Dienst in der erhaltenen Collection führt es folgendes aus:
  5. Es verwendet den Befehl ReDim Preserve, um die Größe von arrTestArray auf den Wert in der Variable intSize anzupassen. Beim ersten Dienst der Collection hat intSize den Wert 0. Das Array hat daher auch die Größe 0 - was bedeutet, dass ein Element in ihm gespeichert werden kann.
  6. Es weist dem gerade erstellen Array-Element den Dienstnamen zu (objService.DisplayName).
  7. Es erhöht den Wert von intSize um eins. Nach dem ersten Element hat intSize zum Beispiel den Wert 1 (den bisherigen Wert plus 1).
  8. Es wiederholt diese Schritte für die verbleibenden Dienste aus der Collection.
Dim arrTestArray()
intSize = 0
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_Service")
For Each objService in colRunningServices
    ReDim Preserve arrTestArray(intSize)
    arrTestArray(intSize) = objService.DisplayName
    intSize = intSize + 1
Next

Einen String mit Trennzeichen in ein Array konvertieren

Um administrative Daten für eine Vielzahl von Anwendungen (inklusive Scripte) lesbar zu machen, werden diese Daten oft durch bestimmte Zeichen getrennt in Textdateien gespeichert. Das Trennzeichen ist in diesem Fall einfach das Zeichen, dass die einzelnen in der Textdatei gespeicherten Informationen voneinander trennt - typischer Weise ist dieses Zeichen ein Komma. Solche Dateien werden auch oft als CSV-Dateien (Comma Separated Values) bezeichnet.

Eine Protokolldatei, in der die Namen von Servern, die Namen der Ereignisprotokolle auf diesen Servern und in diesen Protokollen aufgetretenen Fehlernummern gespeichert werden, könnte zum Beispiel so aussehen:

atl-dc-01,DNS Server,13
atl-dc-01,System,14
atl-dc-02,Security,3
alt-dc-02,Application,22

Ein Vorteil von solchen Dateien ist, dass sie in viele andere Anwendungen importiert werden können. Microsoft Excel und Microsoft Access würden das Beispiel oben so interpretieren:

Tabelle 2.18: Importierte Beispieldaten

Feld 1

Feld 2

Feld 3

atl-dc-01

DNS Server

13

atl-dc-01

System

4

atl-dc-02

Security

3

atl-dc-02

Application

22

Einen durch Trennzeichen aufgeteilten String können Sie mit der Funktion Split in ein Array umwandeln. Hierzu müssen Sie der Funktion zwei Parameter übergeben:

  • Den String mit den Werten und den Trennzeichen
  • Das Trennzeichen

Im folgenden Script ist der zu trennende Text in der Variable TestString gespeichert. Als Trennzeichen wird das Komma verwendet:

TestString = " atl-dc-01,DNS Server,13"
TestArray = Split(TestString , ",")
For i = LBound(TestArray) to UBound(TestArray)
    Wscript.Echo TestArray(i)
Next

Wenn Sie das Script unter CScript ausführen, dann erhalten Sie die folgende Ausgabe:

atl-dc-01
DNS Server
13

Alternativen zur Verwendung von Arrays

Arrays sind ein schneller und einfacher Weg, um eindimensionale Daten zu speichern. Wenn Sie es jedoch mit multidimensionalen Daten zu tun haben, dann kann es schnell kompliziert werden. Bevor Sie also multidimensionale Arrays verwenden, sollten Sie über die folgenden Alternativen nachdenken:

  • Dictionary-Objekt: Das Dictionary-Objekt ist Teil der Script-Laufzeitbibliothek und bietet Ihnen eine einfache Möglichkeit arrayähnliche Daten zu speichern, abzufragen und zu verändern. Weitere Informationen zum Dictionary-Objekt finden Sie im Kapitel Script-Laufzeitbibliothek in diesem Buch

  • Disconnected Recordset: Ein "Disconnected Recordset" ist eine temporäre Datenbank, die nicht mit einer tatsächlichen physikalischen Datenbank verbunden ist. Stattdessen wird sie im Speicher erstellt und nach Beendigung des Scripts gelöscht. Wie beim Dictionary-Objekt auch, können Sie beim Recordset mit einem Namen oder einer Indexnummer auf die Elemente zugreifen. Außerdem haben Sie die gleichen Möglichkeiten, wie mit einem normalen Recordset (inklusive Sortieren). Das folgende Codebeispiel sortiert zum Beispiel ein eindimensionales Array:
    For i = LBound(SampleArray) to UBound(SampleArray)
    For j = LBound(SampleArray) to UBound(SampleArray)
    If j = UBound(SampleArray) Then
    Else
    If SampleArray(j) > SampleArray(j + 1) Then
    TempValue = SampleArray(j + 1)
    SampleArray(j + 1) = SampleArray(j)
    SampleArray(j) = TempValue
    End If
    End If
    Next
    Next

    Eein Recordset kann im Gegensatz dazu mit der folgenden einzelnen Codezeile sortiert werden:

    DisconnectedRecordset.Sort = 'FileSize'

    Weitere Informationen zu solchen Recordsets finden Sie im Kapitel Creating Enterprise Scripts in diesem Buch.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Fehlerbehandlung

VBScript stellt Ihnen ein relativ einfaches Verfahren zur Behandlung von Laufzeitfehlern zur Verfügung. Laufzeitfehler sind alle Fehler, die nicht vom Compiler abgefangen werden können und daher erst nach dem Scriptstart auftreten. Das nächste Script produziert zum Beispiel einen Syntaxfehler, da der Befehl Wscript.Echo falsch geschrieben ist. Der Compiler kann die Codezeile nicht interpretieren. Bevor ein Script ausgeführt wird, wird jede Zeile des Scripts von der Script-Engine eingelesen und auf korrekte Syntax geprüft. Bevor das gesamte Script nicht so geprüft wurde, wird keine Zeile des Scripts ausgeführt. Daher wird die Fehlermeldung sofort ausgegeben - auch wenn der Fehler erst in Zeile 3 auftritt:

Wscript.Echo "Line 1."
Wscript.Echo "Line 2."
W script.Echo "Line 3."

Das Nachrichtenfenster aus Abbildung 2.20 wird angezeigt.

Dn151187.084B40FB907C8424136D4C800C41F784(de-de,TechNet.10).png

Abbildung 2.20: Kompilierungsfehler

Im Gegensatz dazu zeigt das folgende Script erst zwei Nachrichtenfenster an, bevor es zu dem Fehler kommt (der falsch geschriebene Befehl Wscript.Echo). Das liegt daran, dass Zeile 3 für den Compiler korrekt aussieht. Er kann nicht feststellen, dass Eho keine gültige Methode des Objektes Wscript ist. Daher zeigt er diese Zeile auch nicht als fehlerhaft an, und die Scriptausführung wird gestartet:

Wscript.Echo "Line 1."
Wscript.Echo "Line 2."
Wscript.Eho "Line 3."

Wenn dann Zeile 3 des Scripts ausgeführt wird, wird die Fehlermeldung aus Abbildung 2.21 angezeigt. Achten Sie darauf, dass es sich hier um einen Laufzeitfehler statt um einen Kompilierungsfehler handelt.

Dn151187.678D115F11C2543084AA89220B1618C9(de-de,TechNet.10).png

Abbildung 2.21: Laufzeitfehler

Laufzeitfehler kommen nicht nur durch falsch geschriebene Befehle zustande. Die nächste Codezeile ist zum Beispiel syntaktisch und typografisch korrekt. Sie erzeugt einen Laufzeitfehler, weil nicht auf den Remotecomputer zugegriffen werden kann:

Set Computer = GetObject("winmgmts:\\InaccessibleComputer")

Das bedeutet, dass wir über das Auftreten von Laufzeitfehlern nur wenig Kontrolle haben (das Netzwerk kann fehlerhaft sein, ein Computer kann heruntergefahren worden sein usw.). Sie haben unter VBScript drei Möglichkeiten, solche Fehler zu handhaben. Die Vor- und Nachteile dieser drei Optionen sehen Sie in Tabelle 2.19.

Tabelle 2.19: Vorteile und Nachteile der Optionen zur Fehlerbehandlung

Option

Vorteile

Nachteile

Fehlschlag des Scripts in Kauf nehmen

Kein Aufwand für den Scriptersteller erforderlich. Scripte schlagen fehl, wenn ein Laufzeitfehler auftritt.

In vielen Fällen ist es besser, dass ein Script fehlschlägt, wenn es nicht korrekt ausgeführt werden kann. Wenn Sie zum Beispiel einem Script eine Sicherung von bestimmten Dateien vornehmen lassen und das Script die Originaldateien danach löschen soll, dann ist es besser, dass das Script fehlschlägt, wenn die Dateien nicht gesichert wenn können. So werden wenigstens nicht die Originaldateien gelöscht.

Wenn das Script an irgendeinem Punkt fehlschlägt, könnte dies dazu führen, dass der Computer in einem instabilen Zustand verbleibt.

Fehler müssen nicht fatal sein. Stellen Sie sich zum Beispiel ein Überwachungsscript vor, das Informationen über 100 Computer abruft. Wenn Computer 1 nicht erreicht werden kann, ist es trotzdem sinnvoll, die Informationen der restlichen 99 Computer abzufragen.

Alle Fehler im Script ignorieren

Scripte werden ohne Unterbrechung weiter ausgeführt.

Scripte führen den Großteil ihrer Aufgaben durch - auch wenn ein Problem auftritt. Ein Script könnte zum Beispiel 99 von 100 Dateien erfolgreich kopieren.

Endbenutzer erhalten keine Fehlermeldungen, auf die sie reagieren müssen.

Probleme sind schwer zu finden, da Sie keine Fehlermeldung erhalten.

Der Computer kann in einen unbekannten Zustand versetzt werden, da möglicherweise einige Aktionen ausgeführt werden und andere nicht.

Auf Fehler im Script mit eigenem Code reagieren

Sie haben die Möglichkeit, aussagekräftige Fehlermeldungen anzeigen zu lassen.

Sie können versuchen, das Problem über den Scriptcode zu beheben. Wenn ein Script zum Beispiel nicht in der Lage ist eine Verbindung zu einem Remotecomputer aufzubauen, dann kann es beispielsweise nach einiger Zeit einen neuen Verbindungsversuch starten.

Erfordert zusätzliche Arbeit bei der Scripterstellung. Der Scriptautor muss wissen, welche Fehler auftreten können. Dann muss er diese über entsprechenden Scriptcode abfangen und handhaben.

Handhabung von Laufzeitfehlern

In den meisten Fällen bedeutet die Handhabung von Laufzeitfehlern einfach folgendes: "Wenn ein Fehler auftritt, brich das Script nicht ab, sondern mache irgendetwas Anderes". Typischerweise ist "irgendetwas Anderes" in eines der folgenden Dinge:

  • Sie können den Fehler ignorieren und einfach mit der nächsten Zeile des Scripts weiter machen.
  • Sie können den Fehler abfangen und mit Scriptcode auf den Fehler reagieren (zum Beispiel könnten Sie eine Fehlermeldung anzeigen).

Beide Methoden werden über den Befehl On Error Resume Next implementiert. Mit diesem Befehl wird ein Script beim Auftreten eines Fehlers nicht einfach beendet. Stattdessen ignoriert das Script die fehlerhafte Codezeile einfach und versucht die nächste Codezeile auszuführen.

Alle Fehler ignorieren

Die bei weitem einfachste Form der Fehlerbehandlung ist das Ignorieren alle Fehler. Hierzu schreiben Sie in die erste Zeile des Scripts einfach den Befehl On Error Resume Next. Das folgende Beispielscript versucht die nicht existente WSH-Methode Wscript.X zu verwenden und verursacht so einen Laufzeitfehler. Das Script wird trotzdem ohne Fehlermeldung ausgeführt:

On Error Resume Next
Wscript.X "Testing 1-2-3."
Wscript.X "Testing 4-5-6"
Wscript.X "Testing 7-8-9"

Bedenken Sie, dass die Fehlerbehandlung erst mit dem Befehl On Error Resume Next beginnt. Das folgende Script führt zu einem Laufzeitfehler, da der Befehl erst nach der ersten fehlerhaften Scriptzeile verwendet wird:

Wscript.Echo "Line 1."
Wscript.Echo "Line 2."
Wscript.Eho "Line 3."
On Error Resume Next
Wscript.Echo "Line 4."

Um sicherzustellen, dass die Fehlerbehandlung korrekt funktioniert, sollten Sie den Befehl On Error Resume Next direkt am Anfang des Scripts verwenden:

On Error Resume Next
Wscript.Echo "Line 1."
Wscript.Echo "Line 2."
Wscript.Eho "Line 3."
Wscript.Echo "Line 4."

Wenn Sie das vorhergehende Script unter CScript ausführen, dann erhalten Sie die folgende Ausgabe:

Line 1.
Line 2.
Line 4. 

Wenn der Laufzeitfehler in der Zeile mit dem Befehl "Wscript.Eho ." auftritt, dann wird einfach die nächste Zeile des Scripts ausgeführt.

Auf Fehler reagieren

Statt Fehler in Ihrem Script zu ignorieren, könnten Sie Scriptcode schreiben, der auf diese Fehler reagiert. Ein solcher Code kann zum Beispiel

  1. prüfen, ob der Wert des Err-Objektes einen anderen Wert als 0 hat (solange kein Laufzeitfehler auftritt, bleibt der Wert bei 0).
  2. auf Fehler reagieren (zum Beispiel Err.Number und Err.Description anzeigen).
  3. den Wert des Err-Objektes auf 0 zurücksetzen. Dies ist sehr wichtig, da es sonst nicht möglich ist, einen weiteren Fehler zu erkennen.

Das folgende Script versucht als Erstes eine Verbindung mit dem WMI-Dienst herzustellen. Wenn dieser Verbindungsversuch fehlschlägt (wenn also Err einen anderen Wert als 0 hat), dann wird ein Nachrichtenfenster mit der Fehlernummer und der Fehlerbeschreibung angezeigt. Danach wird das Err-Objektauf 0 zurückgesetzt.

Im nächsten Schritt versucht das Script eine Liste aller auf dem Computer installierten Dienste abzurufen. Dies schlägt fehl, da die Methode ExecQuery falsch geschrieben ist (ExcQuery). Das Script fragt erneut das Err-Objekt ab - wiederum wird ein Nachrichtenfenster angezeigt, wenn sein Wert ungleich 0 ist. Danach wird das Err-Objekt auf den Wert 0 zurückgesetzt.

On Error Resume Next
Set Computer = GetObject("winmgmts:")
If Err <> 0 Then
    Wscript.Echo Err.Number & " -- " &  Err.Description
    Err.Clear
End If
Set ServiceList = Computer.ExcQuery("SELECT * FROM Win32_Service")
If Err <> 0 Then
    Wscript.Echo Err.Number & " -- " &  Err.Description
    Err.Clear
End If

Wenn Sie das Script unter WScript ausführen, erhalten Sie die in Abbildung 2.22 zu sehende Ausgabe.

Dn151187.BF09B0571AEF4C931A4AFE8A351FE5AE(de-de,TechNet.10).png

Abbildung 2.22: WMI-Fehlermeldung

Aktivieren der Fehlerbehandlung

Manchmal möchten Sie sicher in einem Teil eines Scripts eine Fehlerbehandlung implementieren und in einem anderen Teil nicht. Hierzu können Sie die Fehlerbehandlung an- und abschalten:

  • Mit dem Befehl On Error Resume Next schalten Sie die Fehlerbehandlung an.
  • Mit dem Befehl On Error GoTo 0 schalten Sie die Fehlerbehandlung aus.

Das folgende Script implementiert die Fehlerbehandlung zum Beispiel gleich in der ersten Zeile. In der zweiten Zeile tritt ein Fehler auf, da Wscript.Echo falsch geschrieben wurde - aufgrund der Fehlerbehandlung wird das Script jedoch weiter ausgeführt. In Zeile 3 wird die Fehlerbehandlung aus- und in Zeile 5 wieder angeschaltet. Da es jedoch dazwischen nicht zu Fehlern kommt, wird das Script ohne Fehler ausgeführt:

On Error Resume Next
Wscript.Eco "A"
On Error GoTo 0
Wscript.Echo "B"
On Error Resume Next
Wscript.Eco "C"
Wscript.Echo "D"

Wenn Sie das Script unter Cscript ausführen, erhalten Sie die folgende Ausgabe:

B
D

Beim folgenden Script handelt es sich um eine leicht abgewandelte Version des vorherigen Scripts. Es schlägt jedoch fehl, da während der abgeschalteten Fehlerbehandlung ein Fehler auftritt:

On Error Resume Next
Wscript.Eco "A"
On Error GoTo 0
Wscript.Eco "B"
On Error Resume Next
Wscript.Eco "C"
Wscript.Echo "D"

Wenn Sie das Script unter Cscript ausführen, wird die folgende Fehlermeldung ausgegeben:

Microsoft (R) Windows Script Host, Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. Alle Rechte vorbehalten.
C:\test.vbs(4, 1) Laufzeitfehler in Microsoft VBScript: Das Objekt unterstützt diese Eigenschaft 
oder Methode nicht.: 'Wscript.Eco'

Fehlerbehandlung in COM-Objekten

Ein Problem, weswegen die Fehlerbehandlung schwieriger wird, ist die Tatsache, dass Scripte normalerweise COM-Objekte verwenden. Wenn im COM-Objekt selbst ein Fehler auftritt, bemerkt VBScript dies zwar - es ist möglicherweise jedoch nicht festzustellen, was den Fehler ausgelöst hat. Im folgenden Script versucht WMI zum Beispiel eine Bindung zum nicht existierenden Drucker TestPrinter aufzubauen - dies führt natürlich zu einem Fehler. Das Script versucht dann die Fehlernummer und die Fehlerbeschreibung abzufangen und anzuzeigen:

On Error Resume Next
Set Test = GetObject _
    ("Winmgmts:root\cimv2:Win32_Printer.Name='TestPrinter'")
Wscript.Echo Err.Number & VbTab & Err.Description

Wenn Sie das Script ausführen, dann erhalten nicht etwa eine normale VBScript-Fehlernummer mit vier Ziffern oder eine Fehlerbeschreibung - stattdessen wird das Nachrichtenfenster aus Abbildung 2.23 angezeigt.

Dn151187.B4C593F7E740CDE2D30EF5DB51FE5922(de-de,TechNet.10).png

Abbildung 2.23: Fehlernummer und Fehlerbeschreibung eines COM-Objektes

Das Problem liegt darin, dass dieser Fehler innerhalb von WMI aufgetreten ist. VBScript erfährt nur, dass ein Fehler aufgetreten ist. In einigen Scripten mag dies auch ausreichen - in anderen Scripten oder bei der Entwicklung von Scripten wäre es jedoch deutlich praktischer mehr Informationen über den Fehler zu erhalten.

Viele COM-Objekte stellen eigene Mechanismen zu Fehlerbehandlung bereit. WMI erlaubt es Ihnen zum Beispiel das Fehlerobjekt SWbemLastError zu erstellen - über dieses erhalten Sie die folgenden Informationen:

  • Die aufgerufene Methode.
  • Der Parameter, der für den Fehler verantwortlich ist.
  • Der Name des WMI-Providers, in dem der Fehler aufgetreten ist.

Das folgende Script verwendet das Objekt SWbemLastError, und zeigt die über das Objekt abgefragten Informationen in einem Nachrichtenfenster an:

On Error Resume Next
Set Test = GetObject _
    ("Winmgmts:root\cimv2:Win32_Printer.Name='TestPrinter'")
Set WMI_Error = CreateObject("WbemScripting.SwbemLastError")
Wscript.Echo WMI_Error.Operation & VbTab & _
    WMI_Error.ParameterInfo & VbTab & WMI_Error.ProviderName

Die Ausgabe des Scripts sehen Sie in Abbildung 2.24.

Dn151187.7992DCBCA24296711321AECC355427A4(de-de,TechNet.10).png

Abbildung 2.24: Informationen aus dem Objekt SWbemLastError

Wenn Sie SWbemLastError verwenden, dann dürfen Sie das Objekt erst nach der Codezeile erstellen, von der Sie glauben, dass sie fehlerhaft ist. Das folgende Script gibt zum Beispiel keine Fehlerinformationen zurück, da SWbemLastError vor dem Auftreten des Fehlers erstellt wird:

On Error Resume Next
Set WMI_Error = CreateObject("WbemScripting.SwbemLastError")
Set Test = GetObject _
    ("Winmgmts:root\cimv2:Win32_Printer.Name='TestPrinter'")
Wscript.Echo WMI_Error.Operation & VbTab & _
    WMI_Error.ParameterInfo & VbTab & WMI_Error.ProviderName

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

Prozeduren

Die ersten Administrationsscripte, die Sie schreiben, werden wahrscheinlich sehr einfach sein - sie führen eine einzelne Aufgabe aus und sind dann beendet. Ein Beispiel hierfür wäre ein Script, das sich mit einem Computer verbindet, eine Liste mit allen auf diesem Computer ausgeführten Diensten abfragt und dann endet. Vielleicht verwenden Sie ein zweites Script, das bestimmte Dienste auf einem Computer startet, und ein drittes Script, das bestimmte Dienste beendet.

Wenn Sie mehr Erfahrung gewinnen, dann fangen Sie wahrscheinlich an, komplexere Scripte zu schreiben - zum Beispiel indem Sie mehrere Scripte kombinieren. Statt drei separate Scripte zum Verwalten von Diensten zu verwenden, schreiben Sie ein Script, das drei unterschiedliche Aufgaben ausführen kann. Für ein solches Script könnten Sie beispielsweise Kommandozeilenparameter verwenden:

  • Wenn Sie den Parameter /info angeben, dann gibt das Script Informationen über die ausgeführten Dienste zurück.
  • Wenn Sie den Parameter /start angeben, dann startet das Script bestimmte Dienste.
  • Wenn Sie den Parameter /stop angeben, dann beendet das Script bestimmte Dienste.

Wenn Ihr Script umfangreicher wird, werden Sie es wahrscheinlich praktisch finden, einzelne Scriptteile in Prozeduren zu verlagern. Prozeduren sind Scriptteile, die eine bestimmte Aufgabe ausführen. Das Script zur Verwaltung von Diensten könnte zum Beispiel drei Prozeduren verwenden: eine zum Abfragen der ausgeführten Dienste, eine, um die Dienste zu beenden und eine, um die Dienst zu starten. Wenn Sie den jeweiligen Scriptcode für die drei Aufgaben in drei Prozeduren platzieren, wird die Bearbeitung des Scripts viel einfacher - außerdem verbessern Sei die Lesbarkeit Ihres Scripts, und es wird einfach, bestimmte Scriptteile in andere Scripte zu übernehmen.

Auch wenn Scripte die gleichen Aufgaben immer wieder ausführen, sind Prozeduren sinnvoll. Zum Beispiel, wenn Sie bei jedem Fehler im Script eine bestimmte Nachricht anzeigen lassen möchten. Hierzu können Sie natürlich den entsprechen Scriptcode an all den Stellen Ihres Scripts einfügen, an denen ein Fehler auftreten kann. Dieses Verfahren erfordert jedoch einen recht hohen Aufwand - Sie müssen nicht nur den entsprechenden Code an möglicherweise sehr vielen Stellen einfügen, sondern bei einer Änderung der Fehlerausgabe müssen alle Stellen, an denen der Code verwendet wird, von Hand bearbeitet werden.

Ein besserer Ansatz wäre eine Prozedur zu erstellen, die eine Fehlernachricht anzeigt und diese Prozedur dann bei einem Fehler aufzurufen. Bei diesem Verfahren müssen Sie bei einer Änderung der Fehlernachricht den entsprechenden Code nur noch an einer Stelle ändern.

Unter VBScript können Sie zwei Arten von Prozeduren erstellen:

  • Subroutinen - Diese Prozeduren geben normalerweise keinen Wert zurück (zum Beispiel eine Prozedur zur Anzeige einer Fehlernachricht).
  • Funktionen - Diese Prozeduren geben einen Wert zurück. Funktionenwerden zum Beispiel für mathematische Berechnungen verwendet - beispielsweise, wenn Sie eine Funktion erstellen, die den freien Festplattenplatz von Byte zu GB konvertiert und den GB-Wert dann zurückgibt.

Aufrufen einer Prozedur

Normalerweise führt VBScript die einzelnen Zeilen eines Scripte der Reihe nach aus. Prozeduren bilden jedoch eine Ausnahme von dieser Regel. Subroutinen und Funktionen werden erst dann ausgeführt, wenn diese irgendwo im Script explizit aufgerufen werden. Wenn eine Subroutine nicht aufgerufen wird, dann wird sie auch nicht ausgeführt - egal, an welcher Stelle im Script sie sich befindet.

Das folgende Script enthält zum Beispiel eine Subroutine, die sich in der Mitte des Scripts befindet - diese wird jedoch niemals ausgeführt:

Wscript.Echo "A"
Sub EchoLine2
   Wscript.Echo "B"
End Sub
Wscript.Echo "C"

Wenn Sie das Script unter CScript ausführen, erhalten Sie die folgende Ausgabe:

A
C

Da die Subroutine nicht aufgerufen wird, wird auch der in ihr enthaltene Code nicht ausgeführt. Das Script läuft also folgendermaßen ab:

  1. Zeile 1 wird ausgeführt - der Text 'A' wird angezeigt.
  2. Zeile 2 wird als Anfang einer Subroutine erkannt - da die Subroutine hier jedoch nur definiert und nicht aufgerufen wird, werden die Zeilen 2, 3 und 4 nicht ausgeführt.
  3. Das Script fährt mit Zeile 5 fort - der ersten Zeile nach der Subroutine. Danach ist das Script beendet.

Um die Subroutine auch auszuführen, müssen Sie sie explizit aufrufen. Als Befehl verwenden Sie hierzu den Namen der Subroutine. Das folgende Script gibt zum Beispiel erst den Text 'A' aus und ruft dann die Subroutine mit dem Namen EchoLineB aus - danach wird der Text 'C' ausgegeben:

Wscript.Echo "A"
EchoLine2
Wscript.Echo "C"
Wscript.Quit
Sub EchoLineB
   Wscript.Echo "B"
End Sub

Wenn Sie das Script unter CScript ausführen, erhalten Sie die folgende Ausgabe:

A
B
C

Das Script wird in diesem Fall folgendermaßen ausgeführt:

  1. Zeile 1 wird ausgeführt, und der Text 'A' wird ausgegeben.
  2. In Zeile 2 wird die Subroutine mit dem Namen EchoLineB aufgerufen.
  3. Das Script springt zu Zeile 5 - in der die Subroutine beginnt.
  4. Zeile 6 (die erste Zeile in der Subroutine) wird ausgeführt - der Text 'B' wird angezeigt.
  5. In Zeile 7 ist die Subroutine beendet. Daher springt das Script zu der Zeile nach dem Scriptaufruf (Zeile 3 - die Subroutine wurde ja in Zeile 2 aufgerufen).
  6. Zeile 3 wird ausgeführt - der Text 'C' wird ausgegeben
  7. Zeile 4 wird ausgeführt, und das Script ist damit beendet.

Prozeduren können an jeder beliebigen Position im Script platziert werden - auf die Funktionsweise oder die Leistung des Scripts hat dies keinen Einfluss. Die Platzierung der Prozeduren kann jedoch Auswirkungen auf die Lesbarkeit Ihrer Scripte haben. Weitere Informationen zur Platzierung von Prozeduren finden Sie im Kapitel Scripting Guidelines in Teil 3 dieses Buches.

Das folgende Script verwendet zur Anzeige von möglichen WMI-Fehlern eine Prozedur:

On Error Resume Next
Set objWMIService = GetObject("Winmgmts:root\cimv2")
If Err <> 0 Then
    ErrorHandler
End If
Set colPrinters = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_Printer WHERE Name='TestPrinter'")
If Err <> 0 Then
    ErrorHandler
End If
For Each objPrinter in colPrinters
    Wscript.Echo objPrinter.Name
Next
Sub ErrorHandler
    Select Case Hex(Err.Number)
        Case "80041001"
            Wscript.Echo "The call failed."
        Case "80041002"
            Wscript.Echo "The object could not be found."
        Case "80041010"
            Wscript.Echo "The specified class is not valid."
        Case "8004103A"
            Wscript.Echo "The specified object path was invalid."
        Case "80041048"
            Wscript.Echo "The specified class is not supported."
        Case Else
            Wscript.Echo "An unknown error occurred."
    End Select
    Err.Clear
End Sub

Funktionen

Wie Subroutinen auch, fassen Funktionen Codestücke zusammen - sie sollten jedoch einen Wert zurückgeben. Leider kümmert sich VBScript nicht darum, ob die Funktion auch tatsächlich einen Wert zurückgibt.

Wenn Sie eine Funktion deklarieren, erstellt VBScript automatisch eine Variable, die denselben Namen wie die Funktion hat - in dieser Variable wird der Rückgabewert der Funktion gespeichert. Das folgende Script verwendet zum Beispiel den Befehl Wscript.Echo ThisDate. ThisDate ist der Name einer Funktion, die das aktuelle Datum zurückgibt. Für VBScript bedeutet das:

  • Der Befehl Wscript.Echo ThisDate führt zwei Aufgaben aus:
  • Erst wird die Funktion ThisDate aufgerufen - diese schreibt das aktuelle Datum in die zur Funktion gehörende Variable ThisDate.
  • Nachdem die Funktion vollständig ausgeführt wurde, verwendet der Befehl Wscript.Echo den Wert der Variable, um das Datum auszugeben.
  • Obwohl der Befehl Option Explicit verwendet wird und die Variable nie deklariert wurde, kommt es zu keinem Fehler. Dies liegt daran, dass die Variable zusammen mit der Funktion von VBScript deklariert und initialisiert wird.
Option Explicit
Wscript.Echo ThisDate
Function ThisDate
    ThisDate = Date
End Function

Bedenken Sie, dass dieser Ansatz nur mit Funktionen und nicht mit Subroutinen funktioniert. Das folgende Script führt zu einem Laufzeitfehler, da VBScript das Datum nicht zum Namen der Subroutine zuweisen kann:

Wscript.Echo ThisDate
Sub ThisDate
    ThisDate = Date
End Sub

Parameter an Funktionen übergeben

Funktionen werden oft für mathematische Berechnungen verwendet. Das Ergebnis der Berechnung ist dann der Rückgabewert der Funktion. Ein Beispiel hierfür wäre eine Funktion, die Byte in MB oder Pfund in Kilogramm konvertiert.

Hierzu müssen Sie der Funktion die entsprechenden Werte übergeben. Wenn Sie zum Beispiel die Zahlen 1 und 2 addieren möchten, dann benötigt die Funktion diese beiden Werte. Sie werden ihr als Parameter (auch Argumente genannt) übergeben.

Um Parameter an eine Funktion zu übergeben, nehmen Sie diese einfach mit in den Funktionsaufruf auf. Die folgende Codezeile ruft zum Beispiel die Funktion AddTwoNumbers auf und übergibt Ihr die Wert 1 und 2 als Parameter:

AddTwoNumbers(1 , 2)

Damit Sie einer Funktion Parameter übergeben können, müssen diese in der Funktion definiert werden. Hierzu fügen Sie der Funktion einfach die entsprechende Anzahl an Variablen hinzu. Die folgende Codezeile definiert eine Funktion, die drei Parameter akzeptiert:

Function AddThreeNumbers(x, y, z)

Wenn die Zahl der von der Funktion erwarteten Parameter nicht mit der Zahl der Parameter im Funktionsaufruf übereinstimmt, kommt es zu einem Fehler. Das folgende Script erzeugt einen solchen Fehler. Es werden zwei Parameter an die Funktion übergeben - diese erwartet jedoch überhaupt keine Parameter:

x = 5
y = 10
Wscript.Echo AddTwoNumbers(x, y)
Function AddTwoNumbers
    AddTwoNumbers = a + b
End Function

Um dieses Problem zu beheben, müssen Sie die Funktionsdefinition ändern und ihr die zwei Parameter hinzufügen:

x = 5
y = 10
Wscript.Echo AddTwoNumbers(x, y)
Function AddTwoNumbers(a, b)
    AddTwoNumbers = a + b
End Function

Sicher ist Ihnen aufgefallen, dass die Parameter im Funktionsaufruf andere Namen haben (x und y) als die Parameter in der Funktionsdefinition (a und b). Es ist nicht notwendig, dass die Parameter identische Namen verwenden. Wichtig ist nur, dass die Reihenfolge der Parameter übereinstimmt. Da x der erste Parameter im Funktionsaufruf ist, wird der Wert von x der Variable a zugewiesen. y ist der zweite Parameter - daher wird der entsprechende Wert natürlich b zugewiesen.

Das folgende Beispiel soll zeigen, wie eine Funktion in einem echten Administrationsscript verwendet wird. Es fragt den freien Speicherplatz von Laufwerk C ab und ruft dann eine Funktion mit dem Namen FreeMegabytes auf. Diese Funktion konvertiert den freien Speicherplatz von Byte in MB und gibt diesen Wert zurück. Der neue Wert wird dann vom Script ausgegeben:

Set objWMIService = GetObject("winmgmts:")
Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")
Wscript.Echo FreeMegaBytes(objLogicalDisk.FreeSpace)
Function FreeMegabytes(FreeBytes)
    FreeMegabytes =  FreeBytes / 1048576
    FreeMegabytes = Int(FreeMegabytes)
End Function

Bedenken Sie, dass VBScript jedes Mal versucht die Funktion aufzurufen, wenn deren Name im Script auftaucht. Auch wenn es immer eine Variable mit dem Namen der Funktion gibt, können Sie deren Wert nicht einfach abfragen. Stattdessen wird immer die Funktion aufgerufen, und Sie erhalten den Rückgabewert der Funktion. Das folgende Script ruft zum Beispiel die Funktion FreeMegaBytes auf und versucht im nächsten Schritt auf die Variable FreeMegabytes zuzugreifen. Da auch hier die Funktion aufgerufen wird, kommt es zu einem Fehler - denn die Funktion erwartet ja einen Parameter:

Set objWMIService = GetObject("winmgmts:")
Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")
Wscript.Echo FreeMegaBytes(objLogicalDisk.FreeSpace)
Wscript.Echo "Free space: " & FreeMegaBytes
Function FreeMegabytes(FreeBytes)
    FreeMegabytes =  FreeBytes / 1048576
    FreeMegabytes = Int(FreeMegabytes)
End Function

Wenn Sie das Script ausführen, erhalten Sie die folgende Fehlermeldung:

Dn151187.FF33409CBEA1385CC377D79CB97454F4(de-de,TechNet.10).png

Abbildung 2.25: Fehlermeldung durch einen fehlerhaften Funktionsaufruf

Wenn Sie später auf den Rückgabewert der Funktion zugreifen möchten ohne die Funktion erneut aufzurufen, dann müssen Sie diesen in einer separaten Variablen speichern. Das folgende Script speichert den Rückgabewert der Funktion FreeMegabytes in der Variable AvailableSpace. Mit dieser Variable können Sie dann jederzeit auf den Wert zugreifen, ohne die Funktion erneut aufrufen zu müssen:

Set objWMIService = GetObject("winmgmts:")
Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='c:'")
AvailableSpace = FreeMegaBytes(objLogicalDisk.FreeSpace)
Wscript.Echo "Free space: " & AvailableSpace
Function FreeMegabytes(FreeBytes)
    FreeMegabytes =  FreeBytes / 1048576
    FreeMegabytes = Int(FreeMegabytes)
End Function

Parameterübergabe by Value oder by Reference

In den seltensten Fällen werden die Parameter in einem Script fest eingetragen. Normalerweise werden sie über Variablen an eine Funktion übergeben. In den folgenden beiden Codezeilen wird der Wert der Variable x auf 100 gesetzt und dieser Variable wird als Parameter an die Funktion ModifyValue übergeben:

x = 100
Wscript.Echo ModifyValue(x)

Im Moment des Funktionsaufrufes hat x den Wert 100. Der Wert von x nach der Ausführung der Funktion hängt von zwei Dingen ab: Erstens, ob die Funktion den Wert ändert, und zweitens, ob der Wert by value(als Wert) oder by reference (als Referenz) übergeben wurde.

Um den Unterschied beider Übergabearten zu erkennen sehen Sie sich das folgende Script an. Es setzt den Wert von x auf 100. In der Funktion wird der Wert von x dann auf 99 geändert:

x = 100
Wscript.Echo ModifyValue(x) & VbTab & x
Function ModifyValue(x)
    ModifyValue = x / 25
    x = 99
End Function

Die Ausgabe des Scripts sehen Sie in Abbildung 2.26. Wie Sie sehen können, wurde x einmal durch 25 geteilt, und dann wurde x der neue Wert 99 zugewiesen.

Dn151187.65E762095188BA25C1EE0FDF8A306DFD(de-de,TechNet.10).png

Abbildung 2.26: In einer Funktion einem Parameter einen neuen Wert zuweisen

In vielen Scripten ist es völlig egal, ob die Funktion den Wert von x ändert. Wenn Sie jedoch den Originalwert von x später noch benötigen, dann geraten Sie möglicherweise in Schwierigkeiten.

Standardmäßig werden Variablen unter VBScript bei Funktionsaufruf by reference (als Referenz) übergeben. Das bedeutet, dass die Funktion nicht den Wert erhält, der in der Variable gespeichert ist, sondern einen Zeiger auf die Speicherstelle, in der der Wert der Variable gespeichert ist. Daher greift die Funktion natürlich auch auf den Originalwert selbst zu.

Um sicherzustellen, dass der Wert einer Variable nicht in einer Funktion geändert wird, übergeben Sie den entsprechenden Parameter by value (als Wert). In diesem Fall erhält die Funktion nicht einen Zeiger auf die Speicherstelle der Originalvariable, sondern nur den Wert, der in dieser gespeichert ist. Wenn die Funktion an diesem Wert Änderungen vornimmt, dann sind die Originalspeicherstelle (die Originalvariable) und deren Wert hiervon nicht betroffen.

Um eine Variable by value zu übergeben, verwenden Sie das Schlüsselwort ByVal in der Funktionsdefinition. Das folgende Script übergibt den Parameter x auf diese Art:

x = 100
Wscript.Echo ModifyValue(x) & VbTab & x
Function ModifyValue(ByVal x)
    ModifyValue = x / 25
    x = 99
End Function

Die Ausgabe des Scripts sehen Sie in Abbildung 2.27. Wie Sie sehen, wird die Variable x nicht verändert. Auch wenn es so scheint, dass ihr Wert in der Funktion auf 99 gesetzt wird. In Wirklichkeit arbeitet die Funktion nur mit einer Kopie der Originalvariablen - deren Wert wird auf 99 gesetzt. Nachdem die Funktion beendet ist wird diese Kopie verworfen.

Dn151187.CEF0CB6059A79D2DBD2E28E0D5DA7B75(de-de,TechNet.10).png

Abbildung 2.27: Parameter by value übergeben

Sie können für jeden Parameter einzeln festlegen ob er ByVal oder ByRef übergeben wird. Beide Varianten können in einer Funktionsdefinition beliebig gemischt werden:

Function TestFunction(ByVal x, ByRef y)

Rekursion

Rekursion ist eine Programmiertechnik, bei der eine Subroutine oder Funktion sich selbst aufruft. Möglicherweise haben Sie schon einmal ein Bild gesehen, bei der sich der Fotograf in einem Spiegel selbst fotografiert hat - der Fotograf fotografiert sein Spiegelbild, dass ein Spiegelbild fotografiert, dass wiederum sein Spiegelbild fotografiert usw. Bei der Rekursion passiert genau das gleiche: Subroutine A ruft Subroutine A auf, die wiederum Subroutine A aufruft, die wiederum Subroutine A aufruft usw.

Auch wenn das Konzept der Rekursion sehr bizarr erscheint und schwer zu verstehen ist, handelt es sich doch um ein wichtiges Konzept. Nehmen wird zum Beispiel an, Sie möchten alle Dateien in einem Ordner auflisten. Auf den ersten Blick ganz einfach - aber was machen Sie, wenn der Ordner weitere Unterordner enthält? Und was, wenn diese wiederum Unterordner enthalten? In diesem Fall haben Sie mit der Rekursion die Möglichkeit alle Ordner zu durchlaufen - auch wenn Sie die Ordnerstruktur nicht kennen.

Um die in Abbildung 2.28 zu sehende Ordnerstruktur zu durchlaufen, beginnen Sie beim Ordner Scripte und listen alle Unterordner auf. Für jeden der Unterordner listen Sie wiederum alle Unterordner auf, usw.

Dn151187.90F62341A2192EDA2BB94F1E3138104E(de-de,TechNet.10).png

Abbildung 2.28: Beispiel-Ordnerstruktur

Das folgende Script führt eine solche Rekursion durch. Hierzu verwendet es die Funktion ShowSubFolders. Diese wird so lange aufgerufen, bis alle Ordner durchlaufen wurden.

Set FSO = CreateObject("Scripting.FileSystemObject")
ShowSubfolders FSO.GetFolder("C:\Scripts")
Sub ShowSubFolders(Folder)
    For Each Subfolder in Folder.SubFolders
        Wscript.Echo Subfolder.Path
        ShowSubFolders Subfolder
    Next
End Sub

Die Funktion ShowSubFolders funktioniert folgendermaßen:

  1. Sie ruft eine Collection mit den Unterordnern des Startordners ab (c:\scripte). In dieser Collection gibt es zwei Elemente (Unterordner 1 und Unterordner 2).
  2. Dann gibt sie den Ordnerpfad für das erste Element (Unterordner 1) aus und ruft sich selbst mit dem Ordner als Parameter auf.
  3. Sie ruft eine Collection mit allen Unterordnern von Unterordner 1 ab. Diese Collection hat zwei Elemente: Unterordner 1A und Unterordner 1B.
  4. Sie nimmt das erste Element der Collection (Unterordner 1A) und gibt den Ordnerpfad aus. Dann ruft sie sich selbst mit dem Namen dieses Ordners als Parameter auf.
  5. Da Unterordner 1A keine weiteren Unterordner mehr besitzt, geht es mit dem nächsten Element der Collection weiter (Unterordner 1B). Die Funktion ruft sich nun selbst mit dem Namen dieses Ordners als Parameter auf.
  6. Da Unterordner 1B keine weiteren Unterordner mehr hat, ist die Rekursion von Unterordner 1 beendet. Die Funktion macht mit dem zweiten Element (Unterordern 2) der ersten Collection (Unterordner von c:\scripte) weiter und wiederholt den gesamten Vorgang.

Wenn Sie das Script ausführen, erhalten Sie die folgende Ausgabe:

C:\scripte\Unterordner 1
C:\scripte\Unterordner 1\Unterordner 1A
C:\scripte\Unterordner 1\Unterordner 1B
C:\scripte\Unterordner 2
C:\scripte\Unterordner 2\Unterordner 2A
C:\scripte\Unterordner 2\Unterordner 2B
C:\scripte\Unterordner 2\Unterordner 2C

Bei der Rekursion handelt es sich um eine extrem mächtige Technik, um Daten in Baumstrukturen (zum Beispiel in Active Directory oder im Dateisystem) zu durchsuchen und anzuzeigen.

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

COM-Objekte

Bei COM (Component Object Model) handelt es sich um einen Standardweg für Anwendungen (.exe-Dateien) und Bibliotheken (.dll-Dateien), um ihre Funktionalität anderen Anwendungen zur Verfügung zu stellen. Ohne COM müsste jeder, der die Systemadministration automatisieren will, ein erfahrener C++- oder Visual Basic-Programmierer sein und sich mit den Windows APIs (Application Programming Interfaces) auskennen.

COM-Komponenten sind Dateien (normalerweise .exe- oder .dll-Dateien), die Beschreibungen der Objekte enthalten, die eine Komponente zur Verfügung stellt (diese Beschreibungen werden auch Klassen genannt). Wenn Sie ein COM-Objekt in einem Script erstellen (dieser Prozess wird auch als Instanzierung bezeichnet), dann erstellen Sie eine neue Kopie dieses Objektes (eine Instanz) auf Basis der Objektbeschreibung (Klasse). Nachdem die Instanz erstellt wurde, können Sie auf die Eigenschaften, Methoden und Ereignisse zugreifen, die vom neuen Objekt zur Verfügung gestellt werden.

Objekte, die ihre Funktionalität so über COM zur Verfügung stellen, werden auch COM-Server genannt. Anwendungen oder Scripte, die diese Funktionalitäten nutzen, werden als COM-Clients bezeichnet. Wenn Sie zum Beispiel ein Script schreiben, das WMI verwendet, dann ist WMI der COM-Server und Ihr Script ist der COM-Client. COM-Server können auf zwei Arten implementiert werden:

  • Out-Of-Process-Server - Out-Of-Process-Server werden normalerweise über ausführbare Dateien implementiert und werden in einem anderen Prozess als das Script ausgeführt. Wenn Sie zum Beispiel ein Script starten, dann wird eine Instanz von Wscript.exe gestartet. Wenn Sie in dem Script dann eine Instanz des Microsoft Word-Objektes erstellen, dann wird diese in einem weiteren Prozess gestartet.
  • In-Process-Server - Bibliotheken (.dll-Dateien) sind normalerweise In-Process-Server - sie werden unter demselben Prozess ausgeführt wie die Anwendung oder das Script, dass sie aufgerufen hat. Wenn Sie zum Beispiel in einem Script eine neue Instanz des Objektes FileSystemObject erstellen, dann wird kein neuer Prozess für dieses Objekt gestartet. Dies liegt daran, dass es sich beim Objekt FileSystemObject (das in der DLL Scrrun.dll definiert ist) um einen In-Process-Server handelt - dieser wird im selben Prozess ausgeführt, wie das Script, das Ihn aufgerufen hat. In-Process-Server werden normalerweise schneller ausgeführt als Out-Of-Process-Server, da das Betriebssystem nicht über Prozessgrenzen hinweg arbeiten muss, um auf Methoden und Eigenschaften zuzugreifen.

Wie wir schon weiter oben in diesem Kapitel besprochen haben, arbeitet VBScript mit Objekten, die sich Automatisationsobjekte nennen. Alle COM-Objekte müssen eine oder mehrere Schnittstellen zur Verfügung stellen. Über diese Schnittstellen können die COM-Clients auf die COM-Server zugreifen. Alle Objekte, die die Schnittstelle IDispatch zur Verfügung stellen, werden Automatisationsobjekte genannt. Da nicht alle COM-Objekte diese Schnittstelle anbieten, kann VBScript auch auf alle COM-Objekte des Computers zugreifen.

Der COM-Prozess

Als Scriptautor müssen Sie nur wissen wie Sie eine Referenz auf ein Automatisationsobjekt erstellen. Sie müssen sich keine Sorgen über das Auffinden oder das Laden des Objekts machen, da dies das Windows-Betriebssystem für Sie erledigt. Dennoch ist es nützlich, wenn Sie wissen was passiert, wenn Sie in Ihrem Script die Methode CreateObject verwenden.

Die Referenzierung eines COM-Objektes ist sogar relativ simpel. Wenn Sie eine Anwendung oder eine Bibliothek installieren, die eine Objektklasse zur Verfügung stellt, dann registriert sich diese selbst im Betriebssystem. Bei dieser Registrierung teilt die Komponente dem Betriebssystem folgendes mit:

  • Dass es einen neuen COM-Server gibt.
  • Die Objektklassen, die der neue COM-Server zur Verfügung stellt.

Hierzu werden Registrierungsschlüssel unter dem Pfad HKEY_CLASSES_ROOT der Registrierung erstellt. Unter den neuen Registrierungsschlüsseln gibt es einen, der den Programmatic Identifier (ProgID) für jede neue Objektklasse definiert. Die ProgID ist ein kurzer String, der den Namen der Objektklasse angibt. Sie wird von den Methoden CreateObject und GetObject verwendet, um das Objekt anzugeben, das Sie erstellen möchten. In der folgenden Codezeile ist die ProgID zum Beispiel Excel.Application:

Set TestObject = CreateObject("Excel.Application")

Bei der ProgID handelt es sich um die Information, die das Betriebssystem benötigt, um das COM-Objekt zu finden und zu instanzieren.

Ein neues Objekt erstellen

Wenn die Methode CreateObject ausgeführt wird, dann liest die Script Engine die ProgID aus und übergibt sie der COM-API. Diese API erstellt die Objektreferenz. Mit der folgenden Codezeile wird ein neues Objekt mit der ProgIDScripting.FileSystemObject erstellt:

Set TestObject = CreateObject("Scripting.FileSystemObject")

Die COM-API sucht im Pfad HKEY_CLASSES_ROOT der Registrierung nach einem Unterschlüssel mit dem Namen der ProgID. Wenn ein solcher Schlüssel gefunden wird, dann liest die API einen Unterschlüssel mit dem Namen CLSID unter dem ProgID-Schlüssel aus.

Der Unterschlüssel CLSID enthält die GUID (Globally Unique Identifier) des zu erstellenden Automatisationsobjekts. Eine GUID sieht zum Beispiel so aus:

{172BDDF8-CEEA-11D1-8B05-00600806D9B6}

Mit der GUID findet und verwendet das Betriebssystem COM-Objekte tatsächlich - die ProgID ist nur ein Alias, damit der Scriptautor leichter auf die Komponente zugreifen kann.

Nachdem die GUID gefunden wird, wird im Schlüssel HKEY_LOCAL_MACHINE\Software\Classes\CLSID nach einem Unterschlüssel mit demselben Namen wie die GUID gesucht. Wenn das Betriebssystem diesen Schlüssel findet, sucht es hier nach dem Speicherort der ausführbaren Datei oder der Bibliotheksdatei der Komponente (im Fall des Objekts FileSystemObject ist das C:\Windows\System32\Scrrun.dll). Dann lädt die COM-API die Anwendung oder die Bibliothek, erstellt das Objekt und gibt eine Objektreferenz an das Script zurück.

Servermodus

Wenn ein Objekt über eine ausführbare Datei erstellt wird, dann wird die Anwendung in einem speziellen Modus gestartet - dem Servermodus oder auch Embedded-Mode. In diesem Modus wir die Anwendung ausgeführt und ist voll funktionsfähig, es werden nur keine GUI-Elemente angezeigt (Sie können trotzdem über den Taskmanager prüfen, ob die Anwendung ausgeführt wird). Der Servermodus ermöglicht es die Anwendung zu verwenden ohne dass der Benutzer hierdurch gestört wird.

Auch wenn der Servermodus oft sehr nützlich ist, möchten Sie vielleicht doch manchmal die Benutzerschnittstelle einer Anwendung anzeigen (zum Beispiel, wenn Sie Daten im Internet Explorer anzeigen). Wenn dies der Fall ist, dann müssen Sie dies dem COM-Objekt über den entsprechenden Befehl mitteilen. Das folgende Script erstellt zum Beispiel eine Instanz des Internet Explorer und verwendet die Eigenschaft Visible des Objektes, um die Anwendung für den Benutzer sichtbar zu machen:

Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True

Bindung

Mit Bindung wird die Art bezeichnet, auf die ein Script oder eine Anwendung auf ein COM-Objekt zugreift. Wenn Sie eine Objektreferenz auf ein Automatisationsobjekt erstellen, dann muss VBScript prüfen, ob das Objekt existiert und dass die Methoden und Eigenschaften, auf die Sie zureifen, vom Objekt zur Verfügung gestellt und korrekt verwendet werden. Dieser Prozess wird Bindung genannt.

COM unterstützt zwei Arten der Bindung: die frühe Bindung (early) und die späte Bindung (late). Bei der frühen Bildung werden Objekt, Eigenschaften und Methoden bereits bei der Compilierung der Anwendung überprüft. Wenn es zu diesem Zeitpunkt bereits Probleme gibt, schlägt die Compilierung fehl. Die frühe Bindung ist schneller als die späte Bindung, da das Objekt vor dem Ausführen der Anwendung überprüft wird. Außerdem ermöglicht die frühe Bindung einen Zugriff auf die Typenbibliothek des Objekts - diese enthält Informationen über die Methoden und Eigenschaften des Objektes.

Da es sich bei VBScript nicht um eine Compilersprache handelt, wird die frühe Bindung nicht unterstützt. Stattdessen müssen Sie die späte Bindung verwenden - sie wird erst dann durchgeführt, wenn das Script ausgeführt wird. Bei der späten Bindung muss das Script Informationen über Objekt, Methoden und Eigenschaften aus der Registrierung entnehmen. Da VBScript keinen Zugriff auf die Objektbibliothek des Objektes hat, muss der Registrierungszugriff bei jeder Verwendung des Objekts durchgeführt werden. Außerdem können fehlerhafte Zugriffe erst dann festgestellt werden, wenn das Script ausgeführt wird.

Eine Methode für die Bindung eines Automatisationsobjekts auswählen

Die Bindung an ein Automatisationsobjekt ist sehr einfach - der schwierigste Teil ist die Auswahl der geeigneten Methode (GetObject oder CreateObject?). In dem meisten Fällen hängt dies vom Objekt ab - einige generelle Richtlinien finden Sie jedoch in Tabelle 2.20.

Tabelle 2.20: Methoden zur Bindung von Automatisationsobjekten

Auszuführende Aufgabe

Methode

Binden an WMI oder ADSI.

GetObject mit dem entsprechenden Moniker.

Ein Moniker ist ein Zwischenobjekt, das es ermöglicht, eine Referenz auf ein Automatisationsobjekt zu finden, zu aktivieren und zu erstellen. Sowohl auf WMI als auch auf ADSI wird über Moniker zugegriffen. Ihre Scripte können so auf WMI- und ADSI-Objekte zugreifen, ohne dass Ihnen die physikalische Position dieser Objekte bekannt ist. Typischerweise werden Moniker für den Zugriff auf Objekte verwendet, die nicht im Dateisystem gespeichert sind.
Set TestObject = GetObject("winmgmts:")

Binden an eine neue Instanz eines Automatisationsobjekts.

CreateObject mit der entsprechenden ProgID.
Set TestObject = CreateObject("Word.Application")

Binden an eine bestehende Instanz eines Automatisationsobjekts.

GetObject mit der entsprechenden ProgID.
Set TestObject = GetObject("Word.Application")

Binden an ein Automatisationsobjekt über eine bestehende Datei.

GetObject mit der entsprechenden ProgID.
Set TestObject = GetObject("c:\scripts\test.xls")

Binden an eine neue Instanz eines Automatisationsobjekts mit der Möglichkeit auf Ereignisse des Objektes zu reagieren.

CreateObject mit der entsprechenden ProgID und einer Variable für die Ereigniszuordnung.
Set TestObject = Wscript.CreateObject _ ("Word.Application", "Word")

Binden an eine bestehende Instanz eines Automatisationsobjekts mit der Möglichkeit auf Ereignisse des Objektes zu reagieren.

GetObject mit der entsprechenden ProgID und einer Variable für die Ereigniszuordnung.
Set TestObject = Wscript.GetObject _ ("Word.Application", "Word")

Binden an eine neue Instanz eines Automatisationsobjekts auf einem Remotecomputer.

CreateObject mit der entsprechenden ProgID und dem Namen des Remotecomputers.
Set TestObject = CreateObject _ ("Word.Application", "atl-dc-01")

Überprüfen von Objektreferenzen

Die Funktion IsObject ermöglicht es Ihnen zu überprüfen, ob eine Referenzierung funktioniert hat. Wenn der Aufruf von GetObject oder CreateObject funktioniert, dann gibt IsObject den Wert True (-1) zurück - andernfalls erhalten Sie den Rückgabewert False (0). Das folgende Codestück verwendet die Methode CreateObject, um eine Objektreferenz auf ein nichtexistentes Objekt zu erstellen (diese wird der Variable TestObject zugewiesen). Da dies fehlschlägt, gibt eine Prüfung der Referenz über die Methode IsObject den Wert 0 zurück.

On Error Resume Next
Set TestObject = CreateObject("Fake.Object")
Wscript.Echo IsObject(TestObject)

Unglücklicherweise geht VBScript davon aus, dass eine einmal erstelle Objektreferenz für die gesamte Lebensdauer des Scripts gültig ist. Dies ist normalerweise kein Problem - speziell bei Objekten wie ADSI und WMI, die wohl kaum während der Scriptausführung verschwinden werden. Leider lässt sich dasselbe nicht über Automatisationsobjekte sagen. Sehen Sie sich zum Beispiel das folgende Script an. Es erstellt eine Instanz von Microsoft Word, beendet die Instanz und prüft dann über IsObject, ob die Objektreferenz noch gültig ist:

Set TestObject = CreateObject("Word.Application")
TestObject.Quit
Wscript.Echo IsObject(TestObject)

Wenn Sie das Script ausführen, behauptet IsObject, dass TestObject noch immer ein aktives Objekt ist - und zwar darum, weil TestObject ja tatsächlich noch eine Objektreferenz ist. Sie verweist nur nicht mehr auf eine Instanz von Microsoft Word, die ausgeführt wird.

Es gibt zwei Wege, um solche Probleme zu vermeiden. Ein Ansatz ist es, über WMI zu prüfen, ob der Prozess (in diesem Fall word.exe) noch ausgeführt wird. Diese Methode funktioniert zwar, Sie müssen jedoch permanent eine Abfrage der laufenden Prozesse durchführen - Ihr Script wird so langsamer. Außerdem treten weitere Schwierigkeiten auf, wenn mehrere Instanzen von word.exe ausgeführt werden.

Ein besserer Ansatz ist es auf Ereignisse des Objektes zu reagieren. Wenn Word geschlossen wird, dann wird ein Ereignis an Ihr Script gesendet - dieses kann dann entsprechend reagieren.

Weitere Informationen über die Verarbeitung von Ereignissen finden Sie im Abschnitt Creating Enterprise Scripts in Teil 3 in diesem Buch.

Objekte aus dem Speicher entfernen

In-Process-Server (Automatisationsobjekte, die über .dll-Dateien zur Verfügung stehen) werden beim Beenden des Scripts automatisch aus dem Speicher entfernt. Das liegt daran, dass diese Objekte im selben Prozess wie das Script ausgeführt werden. Das folgende Script erstellt eine Instanz des Objekts FileSystemObject und zeigt ein Nachrichtenfenster an. Sobald Sie das Nachrichtenfenster schließen, werden sowohl das Script als auch das Objekt aus dem Speicher entfernt.

Set TestObject = CreateObject("Scripting.FileSystemObject")
Wscript.Echo "Script beenden."

Für Out-Of-Process-Server gilt dies nicht - diese werden in einem anderen Prozess als das Script ausgeführt. Das folgende Script erstellt eine Instanz von Microsoft Word und zeigt dann ebenfalls ein Nachrichtenfenster an. Wenn Sie das Nachrichtenfenster schließen, dann wird zwar das Script beendet, der Microsoft Word-Prozess (word.exe) jedoch nicht:

Set TestObject = CreateObject("Word.Application")
Wscript.Echo "Script beenden."

Das liegt daran, dass es keine direkte Verbindung zwischen dem Script-Prozess und dem Word-Prozess gibt. Die Aktionen, die Sie mit dem Script-Prozess durchführen, betreffen den Word-Prozess nicht - andersrum gilt das gleiche. Über den Taskmanager können Sie überprüfen, ob der Prozess noch ausgeführt wird.

Dn151187.C66BBB7CB37406E30B09328B6F2BE4F1(de-de,TechNet.10).png

Abbildung 2.29: Automatisationsobjekt, dass auch nach der Beendigung des Scripts noch weiter ausgeführt wird

Bei Out-Of-Process-Servern müssen Sie normalerweise zum Entfernen aus dem Speicher eine Methode des Objekts verwenden (um diese Methode zu finden, werden Sie meistens in der Dokumentation des Objekts nachschlagen müssen) - bei Microsoft Word handelt es sich bei dieser Methode um Quit. Das folgende Script erstellt eine Instanz von Microsoft Word und entfernt diese sofort wieder aus dem Speicher:

Set TestObject = CreateObject("Word.Application")
TestObject.Quit
Das Schlüsselwort Nothing

Mit dem Schlüsselwort Nothing können Sie eine Objektreferenz und ein Objekt entfernen. Nachdem eine Objektvariable auf Nothing (Nichts) gesetzt wurde, enthält sie keine Objektreferenz mehr und kann nicht mehr zum Zugriff auf das Objekt verwendet werden. Das folgende Script erstellt eine Instanz von Microsoft Word und weist diese der Objektvariablen TestObject zu. Dann setzt es die Variable auf Nothing und versucht dann über Quit Word aus dem Speicher zu entfernen:

Set TestObject = CreateObject("Word.Application")
Set TestObject = Nothing
TestObject.Quit

Da Sie versuchen auf ein Objekt zuzugreifen, dessen Referenz vorher bereits mit Nothing entfernt wurde, erhalten Sie die Fehlermeldung aus Abbildung 2.30, wenn Sie das Script ausführen.

Dn151187.F6B51044F1D928B762CF24737893C11B(de-de,TechNet.10).png

Abbildung 2.30: Arbeiten mit ungültigen Objektreferenzen

Wenn Sie eine Objektvariable auf Nothing setzen, geben Sie zwar etwas Speicher frei, das Objekt selbst wird jedoch nicht aus dem Speicher entfernt - daher gibt es normalerweise keinen Grund Nothing zu verwenden. Der gleiche Vorgang wird auf jeden Fall beim Beenden des Scripts durchgeführt. Zeile 2 im folgenden Script ist also unnötig:

Set TestObject = CreateObject("Scripting.FileSystemObject")
Set TestObject = Nothing

Dn151187.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).pngZum Seitenanfang

| Home | Technische Artikel | Community