Verteilung von Netzwerkdruckern die Zweite…

Ein weiteres VB-Script, das zur relativ komfortablen Verteilung von Netzwerkdruckern über das Active Directory genutzt werden kann. Es basiert auf dem zuvor veröffentlichten Skript AddNetworkPrinters.vbs, bietet jedoch mehr Funktionen und Flexibilität.
Für diejenigen, die sich mit der alten Version bereits beschäftigt haben, hier die Neuerungen kurz zusammengefasst:

+ rekursive Überprüfung der Gruppenmitgliedschaft möglich
+ Konfiguration über eine INI-Datei
+ Protokolldatei
+ Netzwerkdrucker werden ausschließlich bei Änderung der Gruppenmitgliedschaft hinzugefügt/entfernt
+ Nutzung mehrerer Printserver

Wie funktioniert’s?

Zu allererst benötigt man, neben dem Skript, für jeden zu verteilenden Netzwerkdrucker eine AD-Gruppe (2) (ggf. abgelegt einer für diesen Zweck angelegten Organisationseinheit (1)). In der Beschreibung der Gruppe ist jeweils der <Freigabename> oder <Druckername> (3) hinterlegt. Soll ein Drucker für den Benutzer auch automatisch als Standarddrucker gesetzt werden können, muss noch eine zweite Gruppe mit gleichem Namen + Suffix (4) angelegt werden.

AddNetworkPrinters2.vbs - OU mit Gruppen zur Druckerverteilung

Die Konfiguration des Skripts erfolgt über Parameter in einer INI-Datei.

Die Auswahl der Gruppen aus dem Active Directory kann über die Angabe der OU (Default: Domain Root) und eines Prefix des Gruppennamens (PrefixPrinterGrp) festgelegt werden.

Den primär für die Druckerverbindung zu verwendenden Printserver wählt das Skript aus der INI-Datei aus (Default: Server1). Über RandomPS kann auch für jede Skriptausführung (=1), oder je Druckerverbindung (=2) ein zufälliger Printserver verwendet werden. Soll für einzelne Drucker immer ein bestimmter Printserver primär genutzt werden, kann der Printserver über einen Zusatz in der Gruppenbeschreibung (<Printserver>,<Druckerfreigabename>) für diese Geräte überschrieben werden.

Das Skript überprüft nun, ob eine Differenz zwischen den laut Gruppenzugehörigkeit (bei Bedarf rekursiv UseRecursion) zugewiesenen und den aktuell installierten Netzwerkdruckern besteht. Ist ein Drucker bereits von einem der in der INI angegebenen Printserver verbunden, so wird diese Verbindung per Default beibehalten, auch wenn es sich nicht um den primären Printserver handelt. Bei Nutzung von ForcePriPS jedoch, werden diese Verbindungen entfernt und erneut vom primären Printserver installiert.

Sind bei einer Migration Freigabename und Gruppenbeschreibung verschieden, können die Namen aus der Gruppenbeschreibung über die MigrationTable in die neuen Freigabenamen „übersetzt“ werden.

Schlägt nun die Verbindung eines Druckers über den primären Printserver fehl, wird automatisch versucht diese über einen der anderen unter [Add] angegebenen Server herzustellen (sofern vorhanden).

Zum Schluss werden die Netzwerkdrucker entfernt, die
– von unter [Add] angegebenen Servern verbunden sind, sofern keine Gruppenmitgliedschaft besteht.
– von unter [Remove] angegebenen Servern verbunden sind.

Alle anderen Netzwerkdrucker bleiben erhalten; sollen diese auch gelöscht werden, also nur die über Gruppen zugewiesenen Netzwerkdrucker verbunden bleiben, kann dies mit dem Eintrag Server1=* im Bereich [Remove] erreicht werden.

Die INI-Datei

Die INI-Datei selbst besteht aus 3 Sektionen mit folgenden Parametern:

[Section]/KeyBeschreibungBemerkungen
[Settings]
OUDN einer Organisationseinheit, als Suchbasis für die Auswahl der Gruppen zur DruckerverteilungDefault: Domain Root
PrefixPrinterGrpPräfix des Gruppennamens zur Filterung der Gruppen unterhalb der SuchbasisOptional
SuffixDefaultPrinterSuffix des Gruppennamens zum setzen des StandarddruckersDefault: _Std
UseRecursion0 – es wird nur geprüft, ob der Benutzer direktes Mitglied der Druckerverteilungsgruppe ist
1 – die Gruppenmitgliedschaft wird rekursiv geprüft (Nutzung verschachtelter Gruppen)
Default: 0
MigrationTablePfad und Dateiname der Migrationsdatei.
Nutzbar, wenn in der Gruppenbeschreibung nicht der genutzte Druckername enthalten ist (bspw. bei Migration zwischen zwei Servern mit Wechsel der Druckernamen).
Format:
<AD-Gruppenbeschreibung><Tab><Druckername>
Optional
RandomPSAuswahl des für die Druckerverbindung primär zu verwendenden Printservers aus den in der INI-Datei angegebenen.
0Server1
1 – zufälliger Server je Skriptdurchlauf
2 – zufälliger Server je Druckerverbindung
Bei Bedarf kann der primäre Printserver für einzelne Drucker über die Gruppenbeschreibung festgelegt werden. Statt nur des Druckernamens, wird in der Gruppenbeschreibung der Name dieses Printservers mit Komma getrennt vorangestellt:
<Printserver>,<Druckerfreigabename>
Default: 0
ForcePriPSVerbindung vom primären Printserver erzwingen.
0 – Verbindungen von beliebigem Printserver aus INI-Datei beibehalten
1 – Verbindung von primärem Printserver bevorzugt herstellen (andere trennen)
Default: 0
OutputFehlerausgabe am Bildschirm (MessageBox)
0 – aus
1 – an
LogFilePfad und Dateiname der Logdatei
(Nutzung von Umgebungsvariablen möglich)
Der Umfang des Logs wird bestimmt durch die Konstante OUT_LOGLVL(Z. 22):
0 – Normal (Änderungen an Druckerverbindungen, Fehler)
1 – Erweitert
Optional
InitDelayDefinition der Wartezeit auf d. Initialisierung d. Liste installierter Drucker (nach Benutzeranmeldung) in Millisekunden (Workaround Fehler 0x80070BC4)Optional
[Add]
Server1Name des Servers auf dem die Drucker freigegeben sindOptional
ServernName weiterer Server mit Druckerfreigaben, die genutzt werden können, falls der primäre Printserver nicht verfügbar ist.Optional
[Remove]
Server1Name des 1. Servers, dessen Druckerverbindungen vom Client komplett entfernt werden sollen
/oder * für alle nicht per Gruppe zugewiesenen Drucker
Optional
ServernName des n. Servers, dessen Druckerverbindungen vom Client komplett entfernt werden sollenOptional

Hier noch eine einfache Beispiel-INI:

[Settings]
OU=ou=Netzwerkdrucker,ou=Gruppen,DC=bistron,DC=eu
UseRecursion=1
ForcePriPS=1
Output=1
LogFile=\\server1\Client-Logs\AddNetworkPrinters\%username%.txt

[Add]
Server1=server1
Server2=server2

[Remove]
Server1=server3

In diesem Beispiel befinden sich nur Gruppen zur Druckerverteilung unterhalb der angegebenen OU, so dass eine Filterung mit PrefixPrinterGrp nicht notwendig ist; auch wird der Standardwert von SuffixDefaultPrinter _Std für die Standarddruckerzuweisung verwendet.

Um den Druckerverteilgruppen nicht einzelne User zuweisen zu müssen, sondern bestehende Gruppen verwendet werden sollen, wurde UseRecursion aktiviert.

Es stehen zwei Server mit den gleichen Druckerfreigaben bereit und wurden im Abschnitt [Add] hinterlegt. Server1 soll primär und Server2 als StandBy genutzt werden (Default RandomPS); fällt Server1 aus, werden die Drucker von Server2 verbunden. Damit die Drucker nach Behebung der Störung auch wieder von Server2 getrennt und von Server1 verbunden werden, wurde ForcePriPS aktiviert.

Alle Druckerverbindungen zum im Abschnitt [Remove] hinterlegten alten Server3 sollen entfernt werden.

Im Fehlerfall sollen Benutzer mit einer benachrichtigt werden (Output=1) und es soll unter einer Freigabe von jedem User ein LogFile erstellt werden.

AddNetworkPrinters2.vbs - Überblick

Neben diesem Beispiel zum Failover auf einen sekundären Printserver im Störungsfall, sind auch eine Lastverteilung und Migrationen von Clients zwischen Printservern recht einfach realisierbar. Weitere Beispiele für INI-Dateien finden sich im Download.

Ausführung

Der Aufruf des Skripts über die Kommandozeile erfolgt mit der erstellten INI-Datei als Parameter:

cscript.exe <Pfad>\AddNetworkPrinters2.vbs <Pfad>\AddNetworkPrinters2.ini

Die Zuweisung per Gruppenrichtlinie als Benutzer-Anmeldeskript kann z.B. so aussehen:

AddNetworkPrinters2 - GPO Benutzer-Anmeldeskript

Download

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne
(5 Bewertungen, ⌀: 5,00 / 5)
Loading...

19 Kommentare

  1. Jetta

    Super Idee das Skript, allerdings funktioniert es bei mir nicht richtig. D.h. er ignoriert die Gruppenmitgliedschaften und verbindet den Drucker dessen Gruppe als erstes Ergebnis der LDAP Query kommt. Haben Sie eine Idee woran das liegt ?? Gruppen, OUs etc. habe ich geprüft.

    • Dennis Bistron

      Hallo Jetta,

      spontan kann ich Ihnen nicht sagen, woran genau es scheitert. Bei Bedarf können Sie mir über das Kontaktformular nähere Informationen zu den verwendeten OUs, Gruppen und der von Ihnen verwendeten INI-Datei zusenden – evtl. kann damit die Ursache ein wenig eingegrenzt werden…

      MfG

      /Update 03.09.: Bug wurde behoben.

  2. Kai

    Hallo Dennis;

    ich hatte Ihr erstes Script bereits getestet und im Einsatz. Nun wollte ich das aktuelle Script testen und bekomme immer die Meldung, dass Parameter fehlen und AddNetworkprinters.vbs .

    Irgendwo ist da der Wurm drin. Vielleicht könnten Sie freundlicherweise die Vorgehensweise näher erläutern.

  3. Jetta

    In der Richtlinie muss unter dem Skriptname, als Skriptparameter der UNC-Pfad zur Ini-Datei eingetragen werden 😉

  4. Dennis Bistron

    @Kai
    Es muss – wie Jetta schon schreibt – der Pfad zur INI-Datei als Parameter an das Skript übergeben werden. Habe den Beitrag noch kurz um den Abschnitt Ausführung ergänzt…

    @Jetta
    Das Problem von letzter Woche hat sich erledigt?

  5. Kai

    Vielen Dank. Das war der entscheidene Hinweis. Das Script arbeitet super.

  6. Christian

    Script läuft soweit…vielen Dank dafür.

    Was ich nicht verstehe ist die „Beschreibung“ = „Kommentar“ denn das hat überhaupt keinen Einfluss auf die erfolgreiche Druckerzuweisung.
    Entscheidend ist bei mir dass der „Freigabename“ in der Beschreibung der ADS Gruppe steht.
    Sobald ich es mit dem Kommentar versuche gehts nicht.
    Umgebung ist ein Windows 2008 R2 Printserver mit Windows 7 x64 Client.

    Geht das anderen auch so?

  7. Andreas Zahrl

    Script läuft super.

    Nur ein Problem:

    Ich habe einer Drucker-Gruppe die Gruppe „Domänen-Benutzer“ hinzugefügt, diese wird allerdings nicht rekursiv ausgewertet. Kann es hier ein Problem mit dem „ä“ im Namen geben? Andere Gruppen werden problemlos rekursiv aufgelöst.

  8. Oliver Oelkers

    Hallo Dennis, vielen Dank für dieses super konzipierte Script.
    Offensichtlich habe ich einen Fehler in die .ini gebastelt, ich erhalte bei der Ausführung den Fehler:
    \FFM01-015P01 Connect – Error: 0x8007007B

    Die Sicherheitsgruppen enthalten als Name und Beschreibung den Freigabenamen des jeweiligen Drucker, die .ini sieht wie folgt aus:

    [Settings]
    Output=1
    UseRecursion=0
    LogFile=\xxx-P-DS01Log%username%.txt
    OU=ou=Drucker-Groups,ou=Groups,ou=RZ,DC=lokal,DC=de
    SuffixDefaultPrinter=-STD

    [Add]
    Server=xxx-v-druck01

    Die User sind Mitglied der jeweiligen Sicherheitsgruppe, irgendwie scheint der Printserver nicht übernommen zu werden.

    Vielleicht hast du eine Idee

    • Dennis Bistron

      Hallo Oliver,

      ich vermute, dass bei Dir Server=xxx-v-druck01 in der letzten Zeile der INI-Datei steht!? Leider wird diese vom Skript nicht verarbeitet, so dass Du am Ende noch eine Leerzeile einfügen müsstest…

      MfG

      Nachtrag:
      Habe die Funktion readIni() gegen eine aktuellere Variante getauscht, bei der das Problem nicht mehr auftreten sollte.

      • Oliver Oelkers

        Perfekte Antwort, eine Leerzeile drunter und alles funktioniert.
        Besser als per GPO, zumindest in meinem Umfeld.
        Vielen Dank für deine super Arbeit.

  9. Sven Heer

    Hallo Dennis,

    von mir auch Vielen Dank für das Skript.

    Ich möchte mit dem Skript gerne Drucker von zwei unterschiedlichen Druckerservern verteilen.

    Die grundsätzliche Funktion ist mir klar und funktioniert bei mir/ uns auch.

    Gibt es dazu einen Lösungsvorschlag ?

    Danke im Voraus.

    Grüße
    Sven

    • Dennis Bistron

      Hallo Sven,
      z.Z. ist es mit dem Skript nicht möglich einem Benutzer in einem Durchlauf Drucker von unterschiedlichen Printservern zuzuweisen.

      Möglich wäre:
      – Für jeden Printserver eine eigene OU anlegen, die die jeweiligen Druckerverteilgruppen enthält.
      – Entsprechend auch für jeden Server eine INI-Datei anlegen.
      – Die User das Skript mit jeder der INI-Dateien ausführen lassen.

      Hoffe, dass Dir das reicht, um Dein Vorhaben umsetzen; andernfalls kannst Du Dich auch über das Kontaktformular noch mal melden…

      MfG

  10. Oliver Oelkers

    Moin Dennis,
    das Script arbeitet (noch immer) tadellos.
    Im Zuge einer versuchten Optimierung habe ich, leider erfolglos, getestet ob es möglich ist dass das Script erst prüft ob der zu verbindende Drucker nicht schon vorhanden ist. Manche Benutzer haben einen freigegebenen Drucker bereits im Profil, das Script wirft dann:
    Connect – Error: 0x80070BC4
    raus, da die Verbindung bereits besteht.
    Hast du hierzu eventuell einen Denkansatz?

    MfG
    Oliver

    • Dennis Bistron

      Hallo Oliver,

      das Skript gleicht bereits die Liste installierter Drucker (objInstalledPrinters) mit den zu installierenden Druckern ab – ist ein Drucker bereits vorhanden, dürfte auch kein Verbindungsversuch stattfinden.
      Um das Problem einzugrenzen, kannst Du für die erweiterte Protokollierung die Konstante OUT_LOGLVL = 1 setzen (Z. 43); das Log kannst Du mir bei Bedarf auch mal über das Kontaktformular zusenden…

      MfG

  11. Thomas

    Hi Dennis,

    dein Skript hat mir viel Zeit und Mühe erspart habe jetzt die Woche ~200 User auf die Druckverteilung nach deiner Lösung umgestellt hat bestens funktioniert DANKE!

    lG
    Thomas

  12. Torsten Höllermann

    Hallo Dennis.
    Es gibt ein kleines Problem mit dem Script seit die Verarbeitung der Gruppenrichtlinien mit dem Patch MS16-072 umgestellt wurde. Die Funktion GetNetworkprinters() liefert keine Ergebnisse. So werden nicht benötigte Drucker nicht mehr gelöscht und es erscheint wieder die Fehlermeldung Connect – Error: 0x80070BC4 im Logfile.

    Gruß
    Torsten

    • Dennis Bistron

      Hallo Torsten, vielen Dank für den Hinweis. Dass durch den Patch einige Sachen ohne Anpassung nicht mehr laufen, habe ich zwar auch bereits festgestellt, doch dass das Skript auch betroffen ist, war mir noch nicht bekannt.

      Werde es mir sobald möglich mal anschauen…

Kommentar verfassen

Neue Beiträge Oft gelesene BeiträgeNeueste KommentareBlog abonnieren

Gib Deine E-Mail-Adresse an, um diesen Blog zu abonnieren und Benachrichtigungen über neue Beiträge via E-Mail zu erhalten.