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.
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]/Key | Beschreibung | Bemerkungen |
[Settings] | ||
OU | DN einer Organisationseinheit, als Suchbasis für die Auswahl der Gruppen zur Druckerverteilung | Default: Domain Root |
PrefixPrinterGrp | Präfix des Gruppennamens zur Filterung der Gruppen unterhalb der Suchbasis | Optional |
SuffixDefaultPrinter | Suffix des Gruppennamens zum setzen des Standarddruckers | Default: _Std |
UseRecursion | 0 – 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 |
MigrationTable | Pfad 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 |
RandomPS | Auswahl des für die Druckerverbindung primär zu verwendenden Printservers aus den in der INI-Datei angegebenen. 0 – Server1 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 |
ForcePriPS | Verbindung 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 |
Output | Fehlerausgabe am Bildschirm (MessageBox) 0 – aus 1 – an | |
LogFile | Pfad 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 |
InitDelay | Definition der Wartezeit auf d. Initialisierung d. Liste installierter Drucker (nach Benutzeranmeldung) in Millisekunden (Workaround Fehler 0x80070BC4) | Optional |
[Add] | ||
Server1 | Name des Servers auf dem die Drucker freigegeben sind | Optional |
Servern | Name weiterer Server mit Druckerfreigaben, die genutzt werden können, falls der primäre Printserver nicht verfügbar ist. | Optional |
[Remove] | ||
Server1 | Name des 1. Servers, dessen Druckerverbindungen vom Client komplett entfernt werden sollen /oder * für alle nicht per Gruppe zugewiesenen Drucker | Optional |
Servern | Name des n. Servers, dessen Druckerverbindungen vom Client komplett entfernt werden sollen | Optional |
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.
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:
Download
- Skript – AddNetworkPrinters2.vbs (ZIP) – Letzte Aktualisierung: 21.09.2016
8. November 2012 um 16:35 Uhr - -
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.
8. November 2012 um 23:33 Uhr - -
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.
16. November 2012 um 17:11 Uhr - -
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.
16. November 2012 um 17:16 Uhr - -
In der Richtlinie muss unter dem Skriptname, als Skriptparameter der UNC-Pfad zur Ini-Datei eingetragen werden 😉
17. November 2012 um 00:06 Uhr - -
@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?
19. November 2012 um 11:10 Uhr - -
Vielen Dank. Das war der entscheidene Hinweis. Das Script arbeitet super.
7. November 2013 um 11:53 Uhr - -
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?
13. November 2013 um 10:18 Uhr - -
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.
13. November 2013 um 17:09 Uhr - -
Hallo Andreas,
am Umlaut liegt’s nicht. Eher hieran:
„The memberOf attribute is a multi-valued attribute that contains groups of which the user is a direct member, except for the primary group, […]“
(MSDN – User Security Attributes)
Update 26.11.:
Mitgliedschaft PrimaryGroup wird jetzt erkannt
18. Februar 2014 um 09:01 Uhr - -
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
18. Februar 2014 um 20:10 Uhr - -
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.19. Februar 2014 um 06:34 Uhr - -
Perfekte Antwort, eine Leerzeile drunter und alles funktioniert.
Besser als per GPO, zumindest in meinem Umfeld.
Vielen Dank für deine super Arbeit.
26. März 2014 um 13:30 Uhr - -
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
26. März 2014 um 20:32 Uhr - -
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
2. Juli 2014 um 16:13 Uhr - -
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
2. Juli 2014 um 16:48 Uhr - -
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. Dezember 2014 um 16:50 Uhr - -
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
22. Juni 2016 um 17:54 Uhr - -
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
22. Juni 2016 um 20:04 Uhr - -
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…
24. April 2019 um 16:27 Uhr - -
Hallo Dennis,
saucooles Script, Funktioniert echt super! Komme mit GPO – Zuweisung bei weitem nicht so weit, grad bezügl. Druckerentfernung ist dein Script der Hammer! Läuft!! Mit dem Logs sieht man dann auch relativ schnell wenn was nicht so läuft!
Cool wäre noch, wenn man abhängig pro ComputerName die Drucker zusätzlich zuweisen könnte. Bedeutet, egal welcher User sich anmeldet wird immer Drucker xy zugewiesen. Hätte dann auch den charm, dass man den gleichen User für versch. PCs nehmen könnte (z.b. allgem. ProduktionsUser) wo die Drucker je nach Rechner-Gruppenzugehörigkeit gemappt werden und nicht nach User.
Hab mal getestet (ca. Zeile 155) wenn man anstatt …..objCurrentUser.UserName
>strADObject = objCurrentUser.ComputerName
nimmt würde es klappen, Computerkonten die in der entspr. Druckergruppe sind mappen den Drucker, wirft logischerweise halt die Benutzerbezogenen Drucker alle raus!
Bin Scripttechnisch noch nicht durchgestiegen was man anpassen müsste um beides (Benutzer- und Computerzuweisung) zu bewerkstelligen….
könnte man das Implementieren?
Viele Grüße
Andreas
6. Mai 2019 um 09:25 Uhr - -
Hallo,
ja, kann man machen. Habe ich vielleicht sogar bereits halbfertig irgendwo liegen; doch hat das Skript leider auch ein anderes Problem beim Auslesen der vorhandenen Drucker per WMI (Folgefehler ist: 0x80070BC4). Das kann man zwar durch Auslesen der Registry umgehen, doch wollte ich in VBS nicht mehr allzu viel Zeit investieren.
Ich habe von dem Skript auch eine Variante in PowerShell, die ich noch nicht veröffentlicht habe; schaue mal, ob die Funktion dort bereits implementiert ist und lasse Dir einen Link zukommen…