Netzwerkdrucker mit PowerShell verteilen


#1
Hallo zusammen

Ich brauche wieder mal Hilfe von experten, und zwar ist die Situation folgende:

Im Unternehmen müssen wir ca. 60/70 Drucker auf ca. 180 PC Mappen. Alle Drucker sind auf einem Druckserver bereits installiert und vorhanden, haben eigene Namen, IP-Adressen, Einstellungen etc.

Die Verteilung soll via PowerShell anhand einer Liste geschehen, nicht via GPO oder ähnliches, da die Bedingungen (Standarddrucker, Anzahl Drucker etc.) je nach Maschine und Benutzer sehr variieren können. Zudem sind wir so viel flexibler beim deployen.

Bisher machten wir dies via Kix-Script und einer .ini Datei. Wollen aber von Kix weg und ein PowerShell Script via GPO beim Systemstart benutzen.

Ich hab nun ein PowerShell Script mal zusammen geschustert, und eine CSV erstellt, in welcher die PCs mit den entsprechenden Drucker und die Standard angegeben werden. Jedoch funzt der nicht.

Deshalb hier miene Frage....wo mach ich was falsch? Gibt es auch eine bessere, elegantere, übersichtlichere Variante das CSV File zu erstellen?

Hier mal das CSV, bzw. ein Ausschnitt wie es aussieht:

#TYPE Selected.System.Management.ManagementObject.Data.DataRow
Name
PC0001
\\SV0002\PR0001, True
\\SV0002\PR00002

Name
PC0002
\\SV0002\PR0001, True
\\SV0002\PR00002

Und das ist das PS-Script den ich anwenden möchte:

Get–WMIObject Win32_Printer | where{$_.Network -eq ‘true‘} | foreach{$_.delete()}

$Printers=IMPORT-CSV \\server\$env:username\printers.csv

FOREACH ($Printer in $Printers) {
Invoke-Expression 'rundll32 printui.dll PrintUIEntry /in /q /n $($Printer.Name)'

}

Das vor dem anhängen der Drucker alle zuerst gelöscht werden ist Absicht, so kann ich gewährleisten, dass bei einer Servermigration oder ähnliches, alle alte Drucker zuerst entfernt werden.

Bedanke mich jetzt schon für eure Hilfe und wünsche einen ruhigen Montagmorgen.


Gruss
Svisseroo
 

HonniCilest

Erfahrenes Mitglied
#2
Halt mich für verrückt, aber ich finde nicht, dass dein Ausschnitt der CSV Datei sonderlich nach CSV aussieht.

Ich würde eher so einen Inhalt erwarten:

name;printer;default
PC001;\\SV0002\PR0001;true
PC001;\\SV0002\PR00002;false
PC002;\\SV0002\PR0001;true
PC002;\\SV0002\PR00002;false
 
#3
Hallo

Danke für die Antwort, mittlerweile sieht das ganze bereits wieder anders aus.

CSV:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004

PS Script:
$csv = "\\server\Netlogon\Subfolder\printers.csv" $Computers = Import-Csv $csv foreach ($Computer in $Computers){ If ($Computer.name -eq $env:computername) { $Printers = ($Computer.printers).split(";") foreach ($Printer in $Printers) {Add-Printer $Printer -ErrorAction SilentlyContinue} (New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)") } }

Nur erhalte ich da folgenden Fehler:
Add-Printer : Der Parametersatz kann mit den angegebenen benannten Parametern nicht aufgelöst werden. In \\SV0010\NETLOGON\printermapping.ps1:7 Zeichen:42 + ... ch ($Printer in $Printers) {Add-Printer $Printer -ErrorAction Ignore} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: :)) [Add-Printer], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameterSet,Add-Printer Add-Printer : Der Parametersatz kann mit den angegebenen benannten Parametern nicht aufgelöst werden. In \\SV0010\NETLOGON\printermapping.ps1:7 Zeichen:42 + ... ch ($Printer in $Printers) {Add-Printer $Printer -ErrorAction Ignore} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: :)) [Add-Printer], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameterSet,Add-Printer

So wie es scheint fehlt da der -ConnectionName, weiss aber nicht was ich da dann platzieren muss.

Gruss
Svisseroo
 
#5
Hey! HERZLICHEN DANK!

Das war's. Jetzt funzt alles wie es muss.

Hier noch die komplette Lösung, für jene die sowas brauchen könnten, also...

Das CSV sieht so aus:
Code:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004


Das Script zum Verbinden anhand der CSV:
Code:
$csv = "\\server\Netlogon\Subfolder\printers.csv" $Computers = Import-Csv $csv foreach ($Computer in $Computers){ If ($Computer.name -eq $env:computername) { $Printers = ($Computer.printers).split(";") foreach ($Printer in $Printers) {Add-Printer-ConnectionName $Printer -ErrorAction SilentlyContinue} (New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)") } }


Und hier noch das PowerShell Script um die verbundenen Drucker wieder zu löschen:
Code:
Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}


Das Verbinden Script haben wir in einer GPO gepackt, unter Computerkonfiguration/Windows Einstellungen/Skripts/Starten und jenes für das löschen natürlich unter Herunterfahren. Die CSV liegt im Netlogon des DC bereit und beim einloggen des Users werden die Drucker verbunden.

Das einzige was ich mir jetzt noch wünschen würde, aber das ist absolut Detail, ist das CSV etwas "Editier-Freundlicher" zu gestalten. Bei ca. 200 PCs und 60/70 Drucker wird das ziemlich ein Wirrwarr an buschstaben und Zahlen. Aber da schau ich noch, ob und wie ich das mache.

Nochmals Dankeschön
Svisseroo
 
#6
Hey! HERZLICHEN DANK!

Das war's. Jetzt funzt alles wie es muss.

Hier noch die komplette Lösung, für jene die sowas brauchen könnten, also...

Das CSV sieht so aus:
Code:
name,printers,defaultprinter
PC0001,\\SV0001\PR0001;\\SV0001\PR0002,PR0002
PC0002,\\SV0001\PR0001;\\SV0001\PR0003,PR0003
PC0003,\\SV0001\PR0001;\\SV0001\PR0004,PR0004


Das Script zum Verbinden anhand der CSV:
Code:
$csv = "\\server\Netlogon\Subfolder\printers.csv" $Computers = Import-Csv $csv foreach ($Computer in $Computers){ If ($Computer.name -eq $env:computername) { $Printers = ($Computer.printers).split(";") foreach ($Printer in $Printers) {Add-Printer-ConnectionName $Printer -ErrorAction SilentlyContinue} (New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)") } }


Und hier noch das PowerShell Script um die verbundenen Drucker wieder zu löschen:
Code:
Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}


Das Verbinden Script haben wir in einer GPO gepackt, unter Computerkonfiguration/Windows Einstellungen/Skripts/Starten und jenes für das löschen natürlich unter Herunterfahren. Die CSV liegt im Netlogon des DC bereit und beim einloggen des Users werden die Drucker verbunden.

Das einzige was ich mir jetzt noch wünschen würde, aber das ist absolut Detail, ist das CSV etwas "Editier-Freundlicher" zu gestalten. Bei ca. 200 PCs und 60/70 Drucker wird das ziemlich ein Wirrwarr an buschstaben und Zahlen. Aber da schau ich noch, ob und wie ich das mache.

Nochmals Dankeschön
Svisseroo
Hab da noch einen Nachtrag, und zwar einerseits für das Script welches die Verbindungen löscht, da benötigt es vorher noch einen Eintrag, welches den Standarddrucker ändert, ansonsten wird der Standarddrucker nicht getrennt.

Somit sieht das Script folgendermassen aus:
Code:
#$a = Get-WMIObject -query "Select * From Win32_Printer Where Name = 'Microsoft Print to PDF'"
#$a.SetDefaultPrinter()
$TargetPrinter = "Microsoft Print to PDF"
$ErrorActionPreference = “SilentlyContinue”
$LocalPrinter = GWMI -class Win32_Printer | Where {$_.Name -eq $TargetPrinter}
$LocalPrinter.SetDefaultPrinter()
$ErrorActionPreference = “Stop”

Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}
Danach stellten wir fest, dass die Scripte als Machine GPOs bei Startup oder Shutdown nicht funktionieren. Diese Müssen unter einer User GPO sein und zwar unter Benutzerkonfiguration\Windows-Einstellungen\Skripts bei Anmelden, bzw. Abmelden.

Zusätzlich muss dann noch unter Computerkonfiguration\Administrative Vorlagen\System\Gruppenrichtlinie bei Anmldeskriptverzögerung konfigurieren auf Aktiviert setzen und den Standardwert von 5 auf 0 Minuten setzen, sonst werden die Skripte erst 5 Minuten nach der Anmeldung ausgeführt.

Als Tipp, sollte es immer noch nicht gehen, gibt es 2 Fehlerquellen, zum einen, kann es sein, dass GPOs welche auf einem Win 7 Rechner erstellt wurden auf einem 2008R2, 2012R2 Server, oder Win 8 oder 10 Rechner nicht greifen. Am besten also die GPOs direkt auf dem Server/DC erstellen.

Zum anderen, kann eine Fehlerquelle gelöst werden, indem man beim erstellen der GPO im Fenster für den Skript, als Skriptname powershell.exe eingibt, und als Skriptparameter folgendes: -F "\\SERVER\FREIGABE\meinskript.ps1"

Dann sollte es funzen.

Hoffe, dass diese Anleitung anderen hilft.


Gruss
Svisseroo