Hey, Scripting Guy!Lokale Benutzer und Gruppen naiv übernehmen

Die Microsoft Scripting Guys

Laden Sie den Code für diesen Artikel herunter: HeyScriptingGuy2007_04.exe (151KB)

Wie kann ich Sicherheitsdeskriptoren in Dateien und Ordnern verwalten?

Ob Sie es glauben oder nicht, es gab eine Zeit – lang, lang ist's her –, in der die Scripting Guys wirklich nicht ganz so schlau waren. Wirklich kaum zu glauben. Ach, Sie meinen, vielleicht doch nicht ganz so unglaublich? Und noch gar nicht so lange her? Na, da will ich Ihnen aber sagen ... Ok, ok, ich geb' auf. Offensichtlich haben Sie mitgekriegt, wie einer der Autoren von den Scripting Guys neulich versuchte, ein neues Fernsehgerät anzuschließen.

Zu seiner Verteidigung würde dieser Scripting Guy allerdings vorbringen, dass das Anschließen eines neuen Fernsehgeräts nicht einfache Intelligenz erfordert, sondern eher ein Genie. Allein um das Fernsehgerät anzuschließen, sind drei Videokabel und ein paar Audiokabel nötig. Darüber hinaus müssen Sie dann noch einen Videorecorder, einen DVD-Player und eine Xbox® anschließen, ganz zu schweigen vom Eintippen zufälliger Zahlenfolgen in die „universelle“ Fernbedienung, damit diese den ganzen Gerätesalat erkennt. Im Vergleich dazu ist es ein Kinderspiel, einen Satelliten in eine Umlaufbahn um den Mars zu bringen.

Bemerkenswerterweise brachte es der Scripting Guy tatsächlich fertig, alle diese Verbindungen richtig herzustellen. Als er dann aber die Geräte einschaltete, geschah nichts. Pflichtbewusst überprüfte er jede Verbindung doppelt und dreifach. Er las alle Benutzerhandbücher durch und prüfte sogar online, ob es Informationen geben könnte, die ihm entgangen waren. Nichts. Er war schon drauf und dran, dem Elektronikgott einen MP3-Player zu opfern, als er bemerkte, dass er einen kleinen, aber wichtigen Schritt vergessen hatte: das Einstecken des Kabels in die Steckdose.

Anmerkung: Vielleicht hat Ihrer Meinung nach die Scripting-Familie einfach zuviel Elektronikzeug, wenn das Ganze denn so schwierig ist. Dem würde dieser Scripting Guy tatsächlich zustimmen. Wenn jedoch die Familie über den Erwerb von noch mehr Geräten abstimmt, wird der Scripting Guy regelmäßig mit 2:0 überstimmt. Nicht etwa 2:1, sondern 2:0. Aus irgendwelchen Gründen scheint die Stimme des Vaters bei Familienwahlen der Scriptings nie mitzuzählen, und Stimmzettel gibt es ja nicht.

Um Ihre nächste Frage zu beantworten: ja, er hat schon alles versucht. Aber bisher haben die Vereinten Nationen es abgelehnt, Wahlbeobachter in sein Haus zu entsenden.

Wenn man es sich richtig überlegt, waren die Scripting Guys (na ja, vor allem der mit dem neuen Fernsehgerät) eher naiv als dumm. Als sie z. B. das Microsoft ®Windows ® 2000 Scripting-Handbuch entwarfen, baten sie einige so genannte ... Fachleute ... um Hilfe beim Schreiben der verschiedenen Kapitel. Eines der Kapitel, das unter den Tisch fiel, war ein Kapitel über die Verwaltung lokaler Benutzer und Gruppen. „Verwaltung lokaler Benutzer und Gruppen?!?” fragten die Fachleute. „Warum wird darüber überhaupt nachgedacht? Wen interessiert schon die Verwaltung lokaler Benutzer und Gruppen?“

Zu unserem großen Leidwesen haben wir seither feststellen müssen, dass sich jeder (mit Ausnahme unserer innerbetrieblichen „Fachleute“) für lokale Benutzer und Gruppen interessiert. Jede Woche erhalten wir Unmengen von E-Mails mit der Frage, wie man beispielsweise einer lokalen Gruppe einen Benutzer hinzufügt, einen Benutzer aus einer lokalen Gruppe löscht oder auf einem Computer das Kennwort des lokalen Administrators ändert.

Klar gibt es im Script Center Script Repository einige Beispielskripts für das Durchführen dieser Aufgaben, aber die meisten dieser Skripts funktionieren jeweils nur für einen Computer. Das reicht aber nicht: Die Leute wollen wissen, wie sie dies auf mehreren Computern bewerkstelligen können, und zwar gleichzeitig. Das Kennwort des lokalen Administrators auf einem einzigen lausigen Computer ändern? Jetzt aber mal im Ernst, Scripting Guys, wir wollen das auf allen unseren Computern durchführen, oder auf allen Computern in einer Organisationseinheit, oder auf allen unseren Mailservern oder ... na ja, Sie verstehen schon.

Wenn man bedenkt, dass das Scripting-Handbuch bereits 2003 veröffentlicht wurde, so werden wir seit beinahe vier Jahren von diesen immer gleichen E-Mails überschwemmt. „Hier ist noch ein Leser, der wissen will, wie er Computernamen aus einer Excel®-Tabelle lesen und dann das Kennwort des lokalen Administrators auf jedem dieser Computer ändern kann“, bemerkte kürzlich einer der Scripting Guys. „Wie schaffen wir dieses Problem denn endlich aus der Welt?“

Wir haben zwar vier Jahre gebraucht, aber jetzt haben wir die Lösung. Abbildung 1 zeigt genau, wie sich dieses Problem aus der Welt schaffen lässt.

Figure 1 Endlich haben wir das Problem gelöst

On Error Resume Next

Set objExcel = CreateObject(“Excel.Application”)
Set objWorkbook = objExcel.Workbooks.Open(“C:\Scripts\Test.xls”)
objExcel.Visible = True

i = 2

Do Until objExcel.Cells(i, 1).Value = “”
    strComputer = objExcel.Cells(i, 1).Value   
    Set objUser = GetObject(“WinNT://” & strComputer & “/Administrator”)
    If Err = 0 Then
         objUser.SetPassword “egTY634!alK2”
         objExcel.Cells(i, 2).Value = Now
    End If
    Err.Clear
    i = i + 1
Loop

Anmerkung: Sie haben wahrscheinlich schon gemerkt, dass wir nicht deshalb vier Jahre für das Skript gebraucht haben, weil es so kompliziert war, sondern weil wir einfach für alles so lange brauchen. Deshalb sollten Sie sich die alljährliche Sylvesterparty der Scripting Guys nicht entgehen lassen, denn schließlich weiß man bei ihnen nie, wann oder ob überhaupt wieder eine Party stattfindet.

Wir haben hier ein Skript, das Computernamen aus einer Tabelle entnimmt und dann das Kennwort des lokalen Administrators auf jedem dieser Computer ändert. Für diesen Zaubertrick nehmen wir einmal an, dass Ihnen eine sehr einfache kleine Tabelle vorliegt, die in etwa so aussieht wie Abbildung 2. (Wenn nicht, erstellen Sie schnell eine.)

Abbildung 2 Obligatorische Computerliste

Abbildung 2** Obligatorische Computerliste **(Klicken Sie zum Vergrößern auf das Bild)

So weit, so gut. In Spalte 1 (Spalte A) listen wir die Namen aller Computer auf, deren Kennwörter zu ändern sind. In Spalte 2 (Spalte B) verfolgen wir einfach Datum und Uhrzeit, zu denen das Administratorkennwort auf jedem Computer zuletzt geändert wurde. Auf diese Weise können Sie leicht verfolgen, ob die Administratorkennwörter alle übereinstimmen.

Was das Skript selbst betrifft, starten wir mit der Anweisung „On Error Resume Next“. Gewöhnlich machen wir uns nicht die Mühe, Fehlerbehandlung in unseren Skripts einzubeziehen. Nicht, weil wir gegen Fehlerbehandlung wären, sondern weil wir die Skripts so kurz und einfach wie möglich halten wollen. In diesem Fall aber ist die Anweisung „On Error Resume Next“ entscheidend. Schließlich soll unser Skript versuchen, eine Verbindung zu Dutzenden von verschiedenen Computern herzustellen. Was geschieht, wenn einer der Computer ausgeschaltet ist? Nun ja, mit Fehlerbehandlung wird nichts geschehen. Es wird sicher ein Fehler auftreten, aber das Skript kann ihn ignorieren und fortfahren. Ohne Fehlerbehandlung wird Ihnen so ziemlich das Gleiche passieren wie dem Scripting Guy, als er den neuen Fernseher zum ersten Mal einschaltete: Nichts.

Als Nächstes verwenden wir den folgenden Codeblock, um eine Instanz des Excel.Application-Objekts zu erstellen, machen diese Excel-Instanz auf dem Bildschirm sichtbar und öffnen die Tabelle C:\Scripts\Test.xls:

Set objExcel = CreateObject _
    (“Excel.Application”)
Set objWorkbook = objExcel.Workbooks.Open _
    (“C:\Scripts\Test.xls”)
objExcel.Visible = True

Last not least weisen wir einer i genannten Zählervariablen den Wert 2 zu. Diese Variable wird verwendet, um die aktuelle Zeile in der Tabelle zu verfolgen.

Anmerkung: Aber warum wird i der Wert 2 zugewiesen? Ganz einfach: Die Daten in der Tabelle beginnen nämlich in Zeile 2. Zeile 1 ist nur eine Kopfzeile.

Alles klar? Das Anschließen von YPbPr1-Kabeln liegt uns vielleicht nicht so, aber wir verstehen etwas von Skriptprogrammierung.

Jedenfalls ab und an.

Jetzt kann es losgehen. Zuerst richten wir eine „Do Until“-Schleife ein, die solange ausgeführt wird, bis in Spalte 1 eine leere Zelle auftaucht. Sie dürfen also auf keinen Fall Zeilen in Spalte 1 leer lassen. Wenn das Skript auf eine leere Zeile stößt, nimmt es nämlich an, dass das Ende der Daten erreicht wurde, sodass die Schleife (und das Skript) beendet werden. Obwohl es Möglichkeiten gibt, dieses Problem zu umgehen, ist es leichter, einfach leere Zeilen in der Tabelle zu vermeiden.

Innerhalb der Schleife weisen wir zunächst den in der Zeile i von Spalte 1 gefundenen Wert einer „strComputer“ genannten Variablen zu. Denken Sie daran, dass beim ersten Durchlaufen der Schleife i gleich 2 ist. Folglich arbeiten wir mit dem Wert in Zeile 2, Spalte 1. Mithilfe der folgenden Codezeile wird dann ein Objektverweis (objUser) zum lokalen Administratorkonto auf dem Computer erstellt, der durch die Variable „strComputer“ dargestellt wird:

Set objUser = GetObject(“WinNT://” & _
    strComputer & “/Administrator”)

Wenn mit diesem Skript irgendetwas schief geht, passiert es genau an dieser Stelle. Nehmen Sie z. B. an, dass Netzwerkprobleme vorliegen, dass der Computer ausgeschaltet wurde, dass einer der Scripting Guys seinen DVD-Player falsch angeschlossen und im halben Land einen Stromausfall verursacht hat. Wenn irgendeines dieser Ereignisse eintritt, kann keine Verbindung zu diesem Computer hergestellt werden. Daher muss der Wert des VBScript Err-Objekts sofort überprüft werden:

If Err = 0 Then

Wenn das Err-Objekt gleich 0 ist, konnte problemlos eine Verbindung zum Computer (und zum Administratorkonto) hergestellt werden. Wenn Err einen anderen Wert als 0 hat, kann dies nur eines bedeuten: Der Verbindungsversuch ist fehlgeschlagen. Im diesem Fall lohnt sich die Mühe natürlich nicht, das Kennwort auf dem Computer zu ändern. Wenn keine Verbindung vorliegt, kann auch das Kennwort nicht geändert werden.

Wenn alles gut geht und kein Fehler auftritt, werden die folgenden zwei Codezeilen ausgeführt:

objUser.SetPassword “egTY634!alK2”
objExcel.Cells(i, 2).Value = Now

In Zeile 1 verwenden wir die SetPassword-Methode, um dem lokalen Administratorkonto ein neues Kennwort (z. B. TY634!alK2) zuzuweisen. (Uns ist nämlich hinlänglich bekannt, dass man den Namen seines Kindes nicht als Kennwort verwenden sollte ...) In Zeile 2 schreiben wir dann das aktuelle Datum und die Uhrzeit (mithilfe der VB­Script Now-Funktion) in Zeile i, Spalte 2. Beachten Sie, dass die Spalte „Password Changed“ (Kennwort geändert) nur dann aktualisiert wird, wenn tatsächlich eine Verbindung zum Remotecomputer hergestellt und das Kennwort geändert wurde. Wenn keine Verbindung möglich ist, wird das entsprechende Feld „Password Changed“ nicht aktualisiert. So kann man auf einen Blick feststellen, welche Vorgänge erfolgreich waren und welche nicht.

Und was bedeutet das nun alles? Das bedeutet, dass unsere Tabelle nach dem ersten Durchlaufen der Schleife etwa so aussieht wie Abbildung 3.

Abbildung 3 Computerliste nach dem Zurücksetzen des ersten Kennworts

Abbildung 3** Computerliste nach dem Zurücksetzen des ersten Kennworts **(Klicken Sie zum Vergrößern auf das Bild)

Soweit zu Computer 1. Jetzt müssen wir nur ein wenig Organisationsarbeit leisten, bevor es weiter geht:

Err.Clear
i = i + 1

So kurz sie auch sein mögen, diese beiden Codezeilen sind sehr wichtig. (Als ob die Scripting Guys irgendwelche Codezeilen schreiben würden, die nicht sehr wichtig sind!) Die erste Zeile setzt das Err-Objekt auf 0 zurück. Wenn kein Fehler aufgetreten ist, ist dies redundant. Schließlich ist in diesem Fall Err bereits 0. Wenn jedoch ein Fehler aufgetreten ist, hat Err einen anderen Wert als 0. In diesem Fall ist es wichtig, dass das Err-Objekt manuell zurückgesetzt wird. Warum? Weil dies die Eigenschaft des Fehlerobjekts ist: Es verfolgt nur die Fehler, nicht die Erfolge. Nehmen wir z. B. an, dass ein Problem mit Computer 1 aufgetreten ist und keine Verbindung hergestellt werden konnte. Nehmen wir weiterhin rein theoretisch an, dass dadurch das Fehlerobjekt auf 99 gesetzt wurde.

Wir fahren mit der Ausführung der Schleife fort und stellen erfolgreich eine Verbindung zu Computer 2 her. Was glauben Sie, welchen Wert Err jetzt hat? Genau: Sie können sich auf den Kopf stellen, aber Err lautet nach wie vor 99. Der Err-Objektwert ändert sich nämlich nur, wenn ein Fehler auftritt. Wenn kein Fehler auftritt, behält das Err-Objekt seinen aktuellen Wert bei.

Ist das wirklich von Bedeutung? Ja, ist es. Schließlich ändern wir technisch gesehen das Kennwort auf einem Computer nicht, wenn wir erfolgreich eine Verbindung herstellen, sondern wir ändern das Kennwort nur, wenn Err gleich 0 ist. Moment mal, was sagt der Rechner – ja, stimmt genau: 99 ist nicht gleich 0 (außer natürlich bei Wahlen in der Scripting-Familie, wo sich 99 Stimmen des Vaters auf 0 summieren.) Obwohl eine Verbindung zu Computer 2 hergestellt wurde, ist Err nicht gleich 0. Und da Err nicht gleich 0 ist, wird erst gar nicht versucht, das Kennwort des lokalen Administrators zu ändern.

Anders gesagt: wann immer der Wert von Err sich ändert, müssen Sie ihn auf 0 zurücksetzen, damit das Skript nicht glaubt, dass von dem Zeitpunkt an ein Fehler aufgetreten ist. Und wie wird das Err-Objekt auf 0 zurückgesetzt? Ganz genau: Sie rufen einfach Err.Clear auf.

Als Nächstes erhöhen wir den Wert von i um 1. Warum? Nun, beim ersten Durchlaufen der Schleife war die Variable i gleich 2, denn wir wollten ja eine Verbindung herstellen zu dem in Zeile 2 der Spalte 1 aufgelisteten Computer. Beim zweiten Durchlaufen der Schleife wollen wir eine Verbindung zu dem in Zeile 3 der Spalte 1 aufgelisteten Computer herstellen. Da i die Variable ist, die die gewünschte Zeile anzeigt, müssen wir folglich i auf 3 setzen. Wie jeder weiß, ist 2 + 1 = 3. (Wie gut, dass der Rechner noch läuft ...) Erst dann wird die Schleife erneut durchlaufen und der Prozess mit dem nächsten Computer in der Tabelle wiederholt.

Das ist schon cool, aber da wir nicht mehr so naiv wie früher sind, ist uns bewusst, dass unser Posteingang durch dieses Skript allein nur wenig schrumpfen wird. „Die Sache mit Excel war ja ganz nett,“ werden die Leute sagen, „aber ich muss immer noch das Kennwort des lokalen Administrators für alle Computer in einer Organisationseinheit oder für alle in einer Textdatei aufgelisteten Computer ändern. Eine Liste von Computern wäre auch prima, damit ich einen aus einem Listenfeld auswählen kann. Das Allerbeste wäre allerdings ... “

Immer mit der Ruhe. Ihr Wunsch ist den Scripting Guys Befehl. (Dabei gehen wir allerdings davon aus, dass Sie ohne weiteres vier Jahre auf die Erfüllung Ihrer Wünsche warten.) Wie sich herausstellt, liegen im Script Center Dutzende von Computervorlagen bereit, die es äußerst leicht machen, ein Skript für mehrere Computer auszuführen. Nehmen Sie z. B. an, dass Sie das Kennwort des lokalen Administrators für alle Computer in einer Organisationseinheit ändern wollen. Überhaupt kein Problem. Die Vorlage zum Ausführen eines Skripts für alle Computer in einer Organisationseinheit sieht aus wie Abbildung 4.

Figure 4 Ausführen eines Skripts für eine Organisationseinheit

On Error Resume Next

Set objOU = GetObject(“LDAP://OU=Finance,dc=fabrikam,dc=com”)
objOU.Filter = Array(“Computer”)

For Each objComputer in objOU
    strComputer = objComputer.CN

    ‘ 
=====================================================================
    ‘ Insert your code here
    ‘ 
=====================================================================

    Set objComputer = GetObject(“WinNT://” & strComputer & “”)
    objComputer.Filter = Array(“User”)
    For Each objUser in objComputer
        Wscript.Echo objUser.Name
    Next

    ‘ 
=====================================================================
    ‘ End
    ‘ 
=====================================================================

Next

Sehen Sie in der Vorlage den Abschnitt mit der Aufschrift „Insert your code here“ („Geben Sie hier Ihren Code ein“)? Sie müssen nur noch den Beispielcode in diesem Abschnitt löschen und ihn durch den Code ersetzen, der das Kennwort des lokalen Administrators ändert (und den Sie aus dieser Spalte kopieren können). Ersetzen Sie, anders gesagt, den Beispielcode durch folgenden Code:

Set objUser = GetObject(“WinNT://” & _
    strComputer & “/Administrator”)
If Err = 0 Then
    objUser.SetPassword “egTY634!alK2”
End If
Err.Clear

Dieses besondere Beispiel protokolliert zwar nicht die Ergebnisse für Sie, aber Sie können den dafür erforderlichen Code leicht selbst hinzufügen. Ersetzen Sie den Beispielcode, ändern Sie die Verbindungszeichenfolge LDAP: //OU=Finance,dc=fabri­kam,dc=com so, dass sie auf eine Ihrer Organisationseinheiten zeigt, und fertig.

Um die Wahrheit zu sagen, haben wir diese Vorlagen bereits vor über einem Jahr bereitgestellt und rechneten damit, dass sie zu einer der beliebtesten Komponenten im Script Center würden. Doch damit lagen wir falsch: Sie werden fast nie verwendet, obwohl uns jeden Tag eine Menge Leute schreiben und fragen, wie sie Skripts für mehrere Computer ausführen können. Wahrscheinlich wusste niemand, dass diese Vorlagen überhaupt zur Verfügung standen. Aber jetzt wissen Sie es. Zumindest dann, wenn wir Ihnen sagen, wo sie zu finden sind: microsoft.com/technet/scriptcenter/scripts/templates. Hmmm, vielleicht hat deswegen nie jemand diese Vorlagen verwendet ...

Die Scripting Guys sind zwar nicht mehr so naiv wie früher, aber sind sie immer noch so ungeschickt? Sagen wir es mal so: Vor nicht allzu langer Zeit beschloss einer der Scripting Guys, am Wochenende ein paar Dinge im Haus zu reparieren. Als er montags zur Arbeit zurückkam, hatte er einen blutigen Daumen und eine Fleischwunde am Bein.

Also eigentlich gar nicht so schlimm. Wenigstens nicht für einen Scripting Guy.

Die Microsoft Scripting Guys arbeiten für Microsoft (oder sind zumindest dort angestellt). Wenn sie nicht gerade ihrem Hobby, dem Baseball (oder verschiedenen anderen Aktivitäten) nachgehen, betreiben sie das TechNet Script Center. Besuchen Sie es unter www.scriptingguys.com.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.