zurückInhaltvorwärts Perl Einführung: Win32::Registry

12.6. Das Win32::Registry Modul

Mit diesem Modul kann man die Registry von lokalen und entfernten Rechnern manipulieren (ach, nee). Es gibt noch zwei weitere Module zur Registry: Win32API::Registry und Win32::TieRegistry. Das erste Modul gibt einen wesentlichen Win32 API näheren, low-level Zugriff auf die Registry.

Der Umgang mit diesem Modul ist etwas komplexer und wird häufig von anderen Perl Modulen genutzt, die Zugriff auf Registry Funktionen benötigen. Ein Beispiel hierfür ist das Modul Win32::TieRegistry, das das Win32API::Registry Modul benötigt, und eine leistungsfähige Schnittstelle zur Registry bereitstellt.

Das Win32::TieRegistry werden wir gesondert besprechen (in ungefähr zehn Jahren). Der Nachteil des Win32::Registry Moduls ist, daß man für Dokumentation direkt in die Registry.pm schauen muß (wer andere Doku kennt, soll uns mal mailen). Warum also dieses Modul? Ganz einfach, ein paar von unseren Skripten nutzen es!

Die Anwendungsmöglichkeiten sind vielfältig und vor allen Dingen für Administratoren interessant. Ein Beispiel aus der Praxis: Bestimmten Rechnern soll die Möglichkeit genommen werden, als Browser in einem Windows NT Netzwerk zu fungieren.

Den entsprechenden Registrierungsschlüssel kennt man (nicht frau): MaintainServerList, der sich unter HKEY_LOCAL_\MACHINE\CurrentControlSet\Services\Browser\Parameters befindet. Dieser Schlüssel kann entweder yes,no oder auto sein. Der Default für diesen Schlüssel ist auto auf jeder NT Workstation.
Wir wollen ihn jetzt auf no. setzen (der Computer Browser Dienst sollte dann ebenfalls auf diesen Maschinen deaktiviert werden sonst gibt es beim nächsten Start eine Fehlermeldung durch diesen Dienst, aber das klammern wir hier aus).

Wir gehen hier davon aus, daß eine Datei DisableMaintainServerList.txt existiert, in der die Namen der Maschinen stehen, deren Registry bearbeitet werden soll. Sie sieht so aus:

Name1
Name2
Name3

Eine solche Liste kann man auch leicht mit einem Perl Skript automatisch erzeugen (natürlich muß man hinterher die Maschinen rausnehmen, die man nicht manipulieren möchte).
Damit der arme Admin hinterher weiß, welche Maschinen er erreicht hat und welche nicht (weil irgendeine Dumpfglocke schon um drei nach Hause gegangen ist und den Rechner runtergefahren hat. Henning sagt gerade "schön geschrieben", find' ich auch), werden die Ergebnisse in die Dateien MaintainServerListFailed.txt und MaintainServerListSuccess.txt abgelegt.

Es folgt wie immer das Skript, das wir anschließend besprechen. Wir erwähnen nur der Vollständigkeit halber, daß wir ABSOLUT KEINE Verantwortung für irgendwelche Schäden übernehmen.

use Win32::Registry;

system("cls");

if (-e "DisableMaintainServerList.txt") {
  print "Öffne Datei mit Maschinen, die keine Browser sein sollen ...\n";
  open(MASCH,"DisableMaintainServerList\.txt") || die "Konnte Datei nicht öffnen";
  @Maschinen = <MASCH>;
  close(MASCH) || die "Konnte Datei nicht schließen";
  foreach $Maschine (@Maschinen) {
    chomp($Maschine);
    &DisableMaintainServerList($Maschine);
  }
}
else {
 print "Datei DisableMaintainServerList\.txt existiert nicht.\n";
}


sub DisableMaintainServerList {
  my $Server = @_[0];
  my $MaintainServerListValue ="no";
  my $Browser_Service_Sub_Key = "System\\CurrentControlSet\\Services\\Browser\\Parameters";

  # Der Parameter $Remote_Registry in nächsten Ausdruck ist ein Handle auf den
  # HKEY_LOCAL_MACHINE Teil der Registry.
  $HKEY_LOCAL_MACHINE->Win32::Registry::Connect($Server,$Remote_Registry);

  if ($Remote_Registry) {
    # Der Handle ist nicht undef also haben wir eine Verbindung zum HKEY_LOCAL_MACHINE Teil
    # der Registry von $Server.
    print ("Verbunden mit HKLM Zweig in Registry von $Server\n");

    # $Browser_Key ist ein Handle auf
    # HKEY_LOCAL_MACHINESystem\\CurrentControlSet\\Services\\Browser\\Parameters
    $Remote_Registry->Open($Browser_Service_Sub_Key,$Browser_Key);
    if ($Browser_Key) {
        # Der Handle ist nicht undef
        print ("Verbunden mit Browser\\Parameters Zweig der Registry auf $Server\n");
        print "Versuche Schlüssel MaintainServerList auf $MaintainServerListValue zu setzen\n";

        if ($Browser_Key->SetValueEx("MaintainServerList",0,REG_SZ,$MaintainServerListValue)){
          print "Schlüssel MaintainServerList auf Wert $MaintainServerListValue gesetzt.\n";
          print ("---------------------------------------\n");
          open(SUCCESS, ">>MaintainServerListSuccess.txt");
          print SUCCESS $Server."\n";
          close(SUCCESS);
          $Browser_Key->Close();
        }     # if $Browser_Key->SetValueEx ...
        else {
          print "Konnte MaintainServerList nicht auf $MaintainServerListValue setzen\n";
          print ("---------------------------------------\n");
          open(FAILED, ">>MaintainServerListFailed.txt");
          print FAILED $Server."\n";
          close(FAILED);
        }
      }       # Ende if ($Browser_Key->SetValueEx...)
    else {
      print ("Keine Verbindung zum Browser\\Parameters Unterschlüssel auf $Server\n");
      print ("---------------------------------------\n");
      open(FAILED, ">>MaintainServerListFailed.txt");
      print FAILED $Server."\n";
      close(FAILED);
    }
   }          # Ende if ($Remote_Registry)

  else {
    print ("Keine Verbindung zur Registry von $Server\n");
    open(FAILED, ">>MaintainServerListFailed.txt");
    print FAILED $Server."\n";
    close(FAILED);
  }
}

Wir kommentieren nur den Code in der Subroutine. Der restliche vorherige Code dient nur der Einbindung des Moduls und der Abfrage, ob die Datei mit den Maschinennamen existiert. Das Arbeiten mit Dateien wurde in Kapitel 10 behandelt.

Die Zeilen

my $Server = @_[0];
my $MaintainServerListValue ="no";
my $Browser_Service_Sub_Key = "System\\CurrentControlSet\\Services\\Browser\\Parameters";
my $Remote_Registry;

definieren den Namen der Maschine, dessen entsprechender Registry-Zweig verändert werden soll, den Name des Schlüssels sowie der Zweig, der zu diesem Schlüssel hinführt. Man beachte hierbei die doppelten backslashes sowie der Tatsache, daß der entsprechende Hauptzweig der Registry, wo der Schlüssel MaintainServerList verändert werden soll, gar nicht aufgeführt wird: Von HKEY_LOCAL_MACHINE ist hier noch gar nicht die Rede. Das kommt erst jetzt:

$HKEY_LOCAL_MACHINE->Win32::Registry::Connect($Server,$Remote_Registry);

$HKEY_LOCAL_MACHINE ist keine von uns definierte Variable, sondern ein fest definiertes Schlüsselwort, das ein von Win32::Registry erzeugtes Objekt bezeichnet, das auf den HKEY_LOCAL_MACHINE Registry-Zweig der Maschine $Server zeigt. Die wird über die Connect() Methode der Win32::Registry Klasse erreicht. Analog gibt es weitere entsprechende Schlüsselwörter wie HKEY_CURRENT_USER etc. Was hat es mit der Variable $Remote_Registry auf sich? Ganz einfach, das ist ein Handle auf den HKEY_LOCAL_MACHINE Zweig der remote Maschine $Server. Mit diesem Handle operieren wir weiter. Als nächste überprüfen wir mit einer if-Abfrage, ob der Handle definiert ist, also ob wir ein gültiges Handle auf den HKEY_LOCAL_MACHINE Zweig der Maschine $Server haben. Dies wäre z.B. dann nicht der Fall, wenn die Maschine nicht erreichbar wäre.

Die nächste interessante Zeilte ist

$Remote_Registry->Open($Browser_Service_Sub_Key,$Browser_Key);

Über die Open-Methode wird der Schlüssel System\CurrentControlSet\Services\Browser\Parameters, der unter HKEY_LOCAL_MACHINE liegt, geöffnet. Die Variable $Browser_Key ist ein Handle auf diesen nun geöffneten Zweig. In der nächsten if-Abrage wird wieder abgefragt, ob der Handle definiert ist. Falls ja, geht es weiter mit

$Browser_Key->SetValueEx("MaintainServerList",0,REG_SZ,$MaintainServerListValue

Der Aufruf der Methode SetValueEx() geschieht innerhalb einer if-Abfrage, um eventuelle Fehler sofort abzufangen. SetValueEx() setzt einen Schlüssel auf einen bestimmten Wert. Existiert der Schlüssel nicht, wird er erzeugt.

SetValueEx() nimmt mehrere Parameter: Als erster den Name des Schlüssels, der verändert werden soll: MaintainServerList. Der Wert 0, der als nächstes kommt ist reserviert und wird immer auf Null gesetzt.

Als Nächstes kommt der Typ des Werts des Schlüssels. Hier ist das REG_SZ. Über die verschiedenen Typen kann man sich leicht über das Tool REGEDT32.EXE informieren.

Bei REG_SZ handelt es sich um einen String, nämlich den String "No", der in $MaintainServerListValue abgelegt ist, dem nächsten Parameter. Wurde der Wert erfolgreich auf "No" gesetzt, wird eine Erfolgsmeldung in eine Datei geschrieben. Falls nicht, wird eine entsprechende Mißerfolgsmeldung geschrieben.

Zum Abschluß wird über die Close() Methode der Schlüssel wieder geschlossen. Die if und else Abfragen, die das ganze Skript so schön übersichtlich machen, sind nicht ein wesentlich inhaltlicher Bestandteil des Skripts. Sie dienen nur dazu Fehler abzufangen.

Perl Einführung: Win32::Registry zurückInhaltvorwärts