PowerShell y Preferencias de directiva de grupo cuando las impresoras cuentan hasta cientos



Muchas copias se dividen en la administración de impresoras de red en las computadoras de los usuarios. Básicamente, los administradores se dividieron en dos campos: conectarse con secuencias de comandos de inicio de sesión (bat / vbs) y administrar a través de GPP. Ambos enfoques tienen sus ventajas: los scripts se procesan más rápido, y GPP es más flexible y se usa con más frecuencia que los usuarios que reinician las computadoras. Pero cuando hay más de cien impresoras y están dispersas en docenas de oficinas y ciudades, habrá dificultades en ambos casos.

Es necesario no solo conectar el conjunto correcto de impresoras a cada usuario, teniendo en cuenta su ubicación actual, sino también no olvidarse de ninguna. Y si a veces no solo se mueven los usuarios, sino también las impresoras mismas ...

En general, mis colegas y yo elegimos GPP para nosotros mismos, en primer lugar, para que alguien además de los administradores líderes pueda descubrir la configuración actual simplemente mirando el informe GPMC. Sin embargo, quien diga que su interfaz estándar es conveniente para administrar más de 100 dispositivos, deje que el primero me arroje una piedra. Además, durante la puesta en marcha del siguiente lote, debe realizar muchas rutinas para configurar el escaneo en red y agregarlo al servidor de impresión.

¡Y todo lo que se hace más de una vez se puede automatizar!

¿Qué haremos hoy?

  • mantener registros de todas las impresoras de red;
  • automatizar la adición de impresoras a GPP (PS / XML);
  • ¡Automatice la adición de impresoras al servidor de impresión y al clúster (BAT / VBS)!

Entonces comencemos.

1. Contabilidad para impresoras de red


El primer problema que surge al administrar una gran cantidad de objetos es la contabilidad. Sin él, es fácil confundirse acerca de dónde está instalado y a quién debe conectarse.
La solución más simple y universal es CSV. Al final, desde cualquier sistema de inventario, las hojas de cálculo de ServiceDesk o Excel pueden cargarse en CSV y luego importarse fácilmente a PowerShell, lo que haremos a continuación.

Nuestra descarga se ve así:

imagen

Explicaré de inmediato por qué hay tantos campos:

  • Nombre : el nombre de red de la impresora, está escrito en DNS y en el servidor de impresión
  • Por grupo : el campo determina si se debe conectar la impresora a todos los que están en la subred correspondiente o solo a aquellos que son miembros del grupo AD. El grupo también define las ACL.
  • Subred : la subred en la que debe estar el usuario para trabajar con la impresora
  • Ubicación : la línea de ubicación de la impresora por la que busca el asistente Agregar impresora de Windows
    Cómo se organiza la búsqueda de impresoras por ubicación
    Muchas personas no saben qué sucede cuando una impresora busca un asistente de configuración de impresora estándar. Y esto es lo que pasa. El asistente toma el campo Ubicación de los atributos de la computadora en AD, y selecciona de las impresoras publicadas en AD todas cuya ubicación comienza en la misma línea. Es decir, si la computadora del usuario en la ubicación indica "Omsk / Office on Lenin", entonces la búsqueda mostrará impresoras con las ubicaciones "Omsk / Office on Lenin /", "Omsk / Office on Lenin / Office 404" y "Omsk / Office on Lenin / Recepción »
  • Controlador : el nombre del controlador que se especificará al agregar al servidor de impresión. Este controlador ya debe estar instalado en el servidor. Por lo general, todos los fabricantes que suministran equipos de impresión más o menos serios tienen controladores universales, y se instalan como máximo una vez por lote, y luego si el proveedor ha cambiado, entonces no automaticé esta parte.
  • El tipo es solo una descripción de la impresora para que los usuarios puedan seleccionar fácilmente la impresora que necesitan según sus capacidades si es necesario.
  • Modelo : modelo de la impresora o MFP. Aquí, con la ayuda de tablas auxiliares, las dos anteriores se completan para este campo.
  • UID , y esto es parte del pastel de hoy. Este UID marca los objetos en el GPP, simplificado, para no reinstalar la impresora cada vez que se actualiza la Política de grupo.

Este conjunto de datos es suficiente para no codificarlos en Powershell. Puedes comenzar la diversión.

2. Automatizar GPP


En general, el archivo Printers.xml en un objeto GPP se parece a esto:

<?xml version="1.0" encoding="utf-8"?> <Printers clsid="{1F577D12-3D1B-471e-A1B7-060317597B9C}"> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BARAB-061" status="PRN-BARAB-061" image="2" uid="{43231EA0-A4A3-4F1A-8A25-95BC4FEFBCC6}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-BARAB-061" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-BARAB-061" sid="S-1-5-21-210359847-7924152125-768726458-48993" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.142.1" max="192.168.142.254" /> </Filters> </SharedPrinter> </Printers> 

La fuente del formato se puede estudiar aquí: [MS-GPPREF]: Impresoras y aquí: [MS-GPPREF]: Atributos XML comunes .

En la práctica, creo, puede comparar fácilmente los nombres de campo en este archivo con las casillas de verificación en la interfaz GPP, pero notaré puntos clave:

clsid son los valores fijos de las clases de Preferencias de directiva de grupo, pueden (y deben) dejarse como están.

Nombre / Estado son los nombres para mostrar de los elementos en la consola GPP.
uid , pero este es el identificador único del objeto que viste en la tabla anterior.

Si cambia cada vez que se actualiza la lista de impresoras, la impresora se volverá a conectar a todos los usuarios, lo que puede causar diferentes efectos secundarios.
Ruta : ruta UNC a la impresora
FilterGroup, FilterIpRange : orientar elementos por membresía de usuario en el grupo AD y al encontrar la computadora en el rango de direcciones IP.

2.1. Importamos los datos y creamos la estructura básica del documento XML:


Para hacer esto, use la clase de sistema [System.Xml.XmlDocument]:

 $PrintersCSV = Import-Csv -Delimiter ";" ".\Printers.csv" -Encoding Default [System.Xml.XmlDocument]$PrintersGPP = New-Object System.Xml.XmlDocument $PrintersGPP.PrependChild($PrintersGPP.CreateXmlDeclaration("1.0", "utf-8", $null)) | Out-Null $Printers = $PrintersGPP.AppendChild($PrintersGPP.CreateElement("Printers")) $Printers.SetAttribute("clsid","{1F577D12-3D1B-471e-A1B7-060317597B9C}") 

2.2. Agregue algunas funciones auxiliares para crear los elementos XML necesarios y establecer sus atributos


Crear un elemento de impresora:

 Function NewSharedPrinter { [CmdletBinding()] param ( $SharedPrinter, $clsid = "{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}", $uid, $name, $action ) $image switch ($action){ "C" {$image = 0} "R" {$image = 1} "U" {$image = 2} "D" {$image = 3} } $SharedPrinter.SetAttribute("clsid",$clsid) $SharedPrinter.SetAttribute("name",$name) $SharedPrinter.SetAttribute("status",$name) $SharedPrinter.SetAttribute("image",$image) $SharedPrinter.SetAttribute("uid",$uid) $SharedPrinter.SetAttribute("userContext",1) $SharedPrinter.SetAttribute("bypassErrors",1) $SharedPrinterProperties = $SharedPrinter.AppendChild($PrintersGPP.CreateElement("Properties")) $SharedPrinterProperties.setattribute("action",$action) $SharedPrinterProperties.setattribute("comment","") $SharedPrinterProperties.setattribute("path","\\print-cluster-1.common.domain\$name") $SharedPrinterProperties.setattribute("default",0) $SharedPrinterProperties.setattribute("port","") } 

Crear elementos de filtrado (segmentación) por grupo y por subred:
 Function NewFilterGroup{ [CmdletBinding()] param ( $FilterGroup, $bool = "AND", $not = 0, $name, $sid ) $FilterGroup.SetAttribute("bool",$bool) $FilterGroup.SetAttribute("not",$not) $FilterGroup.SetAttribute("name","COMDOM\"+$name) $FilterGroup.SetAttribute("sid",$sid) $FilterGroup.SetAttribute("userContext",1) } Function NewFilterSubnet{ [CmdletBinding()] param ( $FilterIPRange, $bool = "AND", $not = 0, $start, $end ) $FilterIPRange.SetAttribute("bool",$bool) $FilterIPRange.SetAttribute("not",$not) $FilterIPRange.SetAttribute("min",$start) $FilterIPRange.SetAttribute("max",$end) } 

Las tres funciones funcionan directamente con el objeto PS transferido y no devuelven nada. Nota para los perfeccionistas: al momento de escribir el guión fue más fácil y rápido, no intenté escribir el código orientado a objetos perfecto, solo lo necesitaba para funcionar. Entonces, sí, el código tiene algo que mejorar, pero lo más importante: ¡funciona!

2.3. Y finalmente, el bucle principal, que agrega controles de impresora


Se crean dos elementos para cada impresora: uno para agregar si el usuario está en un grupo y una subred, y uno para eliminar una impresora si el usuario no es miembro del grupo o está en una subred diferente.

Si por alguna razón no hay UID de impresora en el archivo CSV, se generará y se mostrará en la consola.

Para traducir la subred de la notación CIDR al rango de direcciones, tomé prestado el maravilloso cmdlet PSipcalc .

 ForEach ($PrinterItem in ($PrintersCSV | Sort-Object Name)) { if (!$PrinterItem.uid){ $uid = "{"+([guid]::NewGuid()).Guid.ToUpper()+"}" Write-Host "Printer $($PrinterItem.Name) is new. Policy item ID: $uid" } else { $uid = $PrinterItem.uid } $SharedPrinter = $PrintersGPP.CreateElement("SharedPrinter") NewSharedPrinter -SharedPrinter $SharedPrinter -name $PrinterItem.Name -action "U" -uid $uid $Filters = $SharedPrinter.AppendChild($PrintersGPP.CreateElement("Filters")) if ($PrinterItem.ByGroup -ieq "yes") { try { Get-ADGroup -Identity $PrinterItem.Name | Out-Null } catch { Write-Host "Creating group $($PrinterItem.Name)" New-ADGroup -Name $PrinterItem.Name ` -Path "OU=    ,OU=User Groups,DC=DOM,DC=COM" -GroupScope DomainLocal } $FilterGroup = $PrintersGPP.CreateElement("FilterGroup") NewFilterGroup -FilterGroup $FilterGroup -name $PrinterItem.Name -sid (Get-ADGroup -Identity $PrinterItem.Name).SID.Value $Filters.AppendChild($FilterGroup) | Out-Null } $FilterNetwork = .\PSipcalc.ps1 -NetworkAddress $PrinterItem.Subnet $FilterIPRange = $PrintersGPP.CreateElement("FilterIpRange") NewFilterSubnet -FilterIPRange $FilterIPRange -start $FilterNetwork.HostMin -end $FilterNetwork.HostMax $Filters.AppendChild($FilterIPRange) | Out-Null $Printers.AppendChild($SharedPrinter) | Out-Null $RevertSharedPrinter = $PrintersGPP.CreateElement("SharedPrinter") NewSharedPrinter -SharedPrinter $RevertSharedPrinter -name $PrinterItem.Name -action "D" -uid $uid if ($PrinterItem.ByGroup -ieq "yes") { $bool = "OR" } else { $bool = "AND" } $Filters = $RevertSharedPrinter.AppendChild($PrintersGPP.CreateElement("Filters")) if ($PrinterItem.ByGroup -ieq "yes") { $FilterGroup = $PrintersGPP.CreateElement("FilterGroup") NewFilterGroup -FilterGroup $FilterGroup -name $PrinterItem.Name -sid (Get-ADGroup -Identity $PrinterItem.Name).SID.Value -bool "AND" -not 1 $Filters.AppendChild($FilterGroup) | Out-Null } $FilterIPRange = $PrintersGPP.CreateElement("FilterIpRange") NewFilterSubnet -FilterIPRange $FilterIPRange -start $FilterNetwork.HostMin -end $FilterNetwork.HostMax -bool $bool -not 1 $Filters.AppendChild($FilterIPRange) | Out-Null $Printers.AppendChild($RevertSharedPrinter) | Out-Null } 

2.4. Y ahora imprimimos el resultado en un archivo


No veo nada malo en ahorrar unos minutos e inmediatamente escribir a la política:

 $PrintersGPP.Save("\\COMDOM\SysVol\COMMON.DOMAIN\Policies\{f985a9ae-cb71-468b-8a99-e2c7f428aa2f}\User\Preferences\Printers\Printers.xml") 

3. Agregar impresoras al servidor de impresión


Windows tiene un conjunto bastante poco conocido de scripts vbs para administrar impresoras. Además, incluso en versiones de cliente. Se encuentra en el %SystemRoot%\System32\Printing_Admin_Scripts\en-US . Puede leer el Murzilka aquí .

Estamos interesados ​​en tres utilidades del conjunto:

prnport.vbs : para crear un puerto de impresora en el servidor de impresión
prnmngr.vbs : para crear la impresora en sí
prncnfg.vbs : para configurar opciones y habilitar el uso compartido de impresoras
También necesitamos la utilidad SetACL para establecer derechos de acceso para impresoras.

3.1. Crear una impresora en el servidor de impresión


Para hacer esto, cree el script CreateRemotePrinter.bat.

Como argumentos, tomará, en orden:
% 1: el nombre de la impresora;
% 2: el nombre del controlador;
% 3 - Ubicación
% 4 - Descripción de la impresora.

 @echo off SET PRTOOLS="c:\Windows\System32\Printing_Admin_Scripts\en-US" SET SETACL="SetACL.exe" cscript /nologo %PRTOOLS%\prnport.vbs -s print-cl-node-1 -a -r %1 -h %1.common.domain -t -o raw -me cscript /nologo %PRTOOLS%\prnmngr.vbs -s print-cl-node-1 -a -p %1 -m %2 -r %1 cscript /nologo %PRTOOLS%\prncnfg.vbs -s print-cl-node-1 -t -p %1 -h %1 -l %3 -m %4 +shared %SETACL% -on \\print-cl-node-1\%1 -ot prn -actn ace -ace "n:STN-TN\%1;p:man_docs,print" 

En el caso general, esto es suficiente. Pero nuestro servidor de impresión está ubicado en el clúster MSCS, y el conjunto anterior de scripts vbs no funciona con clústeres. Por lo tanto, hay que hacer algo más.

3.2. Transferencia de una impresora de un servidor de impresión normal a uno agrupado


Al acceder al clúster, los scripts del conjunto anterior simplemente crean el puerto y la impresora en el nodo activo actual, y no aparecen en el clúster. Solo para tal caso, Microsoft tiene otra herramienta en la tienda: PrintBRM (Copia de seguridad / recuperación / migración de la cola de impresión). No encontré documentación oficial para ello, por lo que comparto lo que es: Ayuda sobre parámetros en SS64 .

Continuando con el script CreateRemotePrinter.bat.

La utilidad PrintBRM puede copiar correctamente la configuración de la impresora junto con los puertos al clúster, sin embargo, si solo hace una copia (comience con la opción -b) y restaure (-r), no habrá ningún milagro.

Entonces ahora habrá un poco de magia. Se describe en detalle en el Blog de MS Performance Team .
Primero, hacemos una copia de seguridad de la impresora en el archivo temp.printerexport.

Luego desempaquetamos el subdirectorio printerexport, eliminamos los directorios LMONS y PRTPROCS y también ponemos a cero el contenido de varios archivos XML. No entraré en detalles, pero estos archivos contienen una configuración específica para un servidor específico e interfieren con la recuperación de la impresora a otro servidor, especialmente uno de clúster.

Después de eso, empaquetamos la configuración editada nuevamente en el archivo temp.printerexport y la subimos al clúster:

 SET PRNBRM="C:\Windows\System32\spool\tools\PrintBrm.exe" %PRNBRM% -b -nobin -s print-cl-node-1 -f temp.printerexport %PRNBRM% -r -d printerexport -f temp.printerexport del /f /q temp.printerexport del /s /f /q printerexport\LMONS printerexport\PRTPROCS echo ^<SpoolerAttrib /^> > printerexport\BrmSpoolerAttrib.xml echo ^<PPROCS /^> > printerexport\PProcs.xml echo ^<PRINTERDRIVERS /^> > printerexport\BrmDrivers.xml echo ^<LMONS Arch="Windows x64"/^> > printerexport\BRMLMons.xml %PRNBRM% -b -d printerexport -f temp.printerexport del /s /f /q printerexport %PRNBRM% -r -s print-cluster-1 -f temp.printerexport -p all -o force del /f /q temp.printerexport cscript /nologo %PRTOOLS%\prnmngr.vbs -s print-cl-node-1 -d -p %1 cscript /nologo %PRTOOLS%\prnport.vbs -s print-cl-node-1 -d -r %1 

3.3. Agregue impresoras simultáneamente a GPP y servidor / clúster


Ahora debe ajustar perfectamente este script en la lista de impresoras CSV.

Agregue antes del bucle principal una solicitud de una lista de los existentes en el servidor:

 $ActualPrintersList = Get-WmiObject -Class win32_share -computer print-cluster-1 | Where-Object Name -like "*PRN*" | Select-Object -ExpandProperty Name 

Y en el cuerpo del bucle, ejecute nuestro apodo Bat:

  if ("\\print-cluster-1\$($PrinterItem.Name)" -NotIn $ActualPrintersList) { Write-Host "Adding printer $($PrinterItem.Name) to print-cluster-1..." Start-Process -FilePath .\CreateRemotePrinter.bat -ArgumentList "$($PrinterItem.Name) `"$($PrinterItem.Driver)`" `"$($PrinterItem.Location)`" `"$($PrinterItem.Type)`"" -Wait } 

4. Poniendo todo junto, lanzándolo, obteniendo el resultado


Datos de origen en CSV
Name;ByGroup;Subnet;Location;Driver;Type;Model;uid
PRN-NALTA-028;yes;192.168.192.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M425dn;HP LaserJet Pro M425dn;{35F6CF36-2A24-4A81-B061-8BE71CEC27EA}
PRN-TARUS-002;yes;192.168.128.0/23;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet M3027 MFP;HP LaserJet M3027 MFP;{398F4A94-530C-4E3B-8A30-4288D5E8854D}
PRN-KIRILL-081;;192.168.196.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet 3390;HP LaserJet 3390;{421FC2DE-2E97-49FC-AEB0-3070B0166AD5}
PRN-BARAB-061;yes;192.168.142.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M425dn;HP LaserJet Pro M425dn;{43231EA0-A4A3-4F1A-8A25-95BC4FEFBCC6}
PRN-PYSHM-004;;192.168.143.0/24; /;KX DRIVER for Universal Printing; 4 — Kyocera ECOSYS M2540dn;Kyocera ECOSYS M2540dn;{45509B48-E7BC-4497-9665-86D4E1E96FE1}
PRN-BUY---001;yes;192.168.44.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M402dn;HP LaserJet Pro M402dn;{457DB3FE-E35F-450E-B1D6-912F0D831573}
PRN-BATAY-042;yes;192.168.128.0/23;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet P2015 Series;HP LaserJet P2015 Series;{4740604B-C403-4511-91B0-689A197260F3}
PRN-EMPTY-002;yes;192.168.199.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M425dn;HP LaserJet Pro M425dn;{475578CB-689F-463B-9710-AE207973146C}
PRN-LIPKI-003;;192.168.44.0/24;/;KX DRIVER for Universal Printing; 4 — Kyocera ECOSYS M2540dn;Kyocera ECOSYS M2540dn;{4794D22E-6586-4A81-A85D-A21FB8B209CF}
PRN-KOTOV-013;yes;192.168.128.0/23;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M425dn;HP LaserJet Pro M425dn;{4DFFBA1F-48D2-4824-B2EB-0AAD12B6A9D6}
PRN-ELAB-064;;192.168.140.0/24;/;HP Universal Printing PCL 6 (v5.6.0); 4 — HP LaserJet Pro M425dn;HP LaserJet Pro M425dn;{52069D45-EF86-442D-A157-368D7510A1CF}
GeneratePrintersXml.ps1
 $PrintersCSV = Import-Csv -Delimiter ";" ".\Printers.csv" -Encoding Default [System.Xml.XmlDocument]$PrintersGPP = New-Object System.Xml.XmlDocument $PrintersGPP.PrependChild($PrintersGPP.CreateXmlDeclaration("1.0", "utf-8", $null)) | Out-Null $Printers = $PrintersGPP.AppendChild($PrintersGPP.CreateElement("Printers")) $Printers.SetAttribute("clsid","{1F577D12-3D1B-471e-A1B7-060317597B9C}") $DelPrinters = $Printers.AppendChild($PrintersGPP.CreateElement("SharedPrinter")) NewSharedPrinter -SharedPrinter $DelPrinters -name "Delete All" -action "D" -uid "{21097DBD-285D-48C3-B042-7746D7E6DA1B}" $Filters = $DelPrinters.AppendChild($PrintersGPP.CreateElement("Filters")) $FilterRunOnce = $Filters.AppendChild($PrintersGPP.CreateElement("FilterRunOnce")) $FilterRunOnce.SetAttribute("id","{F2537B78-C7D7-43DF-98D6-B32E90644825}") $FilterRunOnce.SetAttribute("hidden",1) $FilterRunOnce.SetAttribute("not",0) $FilterRunOnce.SetAttribute("bool","AND") Function NewSharedPrinter { [CmdletBinding()] param ( $SharedPrinter, $clsid = "{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}", $uid, $name, $action ) $image switch ($action){ "C" {$image = 0} "R" {$image = 1} "U" {$image = 2} "D" {$image = 3} } $SharedPrinter.SetAttribute("clsid",$clsid) $SharedPrinter.SetAttribute("name",$name) $SharedPrinter.SetAttribute("status",$name) $SharedPrinter.SetAttribute("image",$image) $SharedPrinter.SetAttribute("uid",$uid) $SharedPrinter.SetAttribute("userContext",1) $SharedPrinter.SetAttribute("bypassErrors",1) $SharedPrinterProperties = $SharedPrinter.AppendChild($PrintersGPP.CreateElement("Properties")) $SharedPrinterProperties.setattribute("action",$action) $SharedPrinterProperties.setattribute("comment","") $SharedPrinterProperties.setattribute("path","\\print-cluster-1.common.domain\$name") $SharedPrinterProperties.setattribute("default",0) $SharedPrinterProperties.setattribute("port","") } Function NewFilterGroup{ [CmdletBinding()] param ( $FilterGroup, $bool = "AND", $not = 0, $name, $sid ) $FilterGroup.SetAttribute("bool",$bool) $FilterGroup.SetAttribute("not",$not) $FilterGroup.SetAttribute("name","COMDOM\"+$name) $FilterGroup.SetAttribute("sid",$sid) $FilterGroup.SetAttribute("userContext",1) } Function NewFilterSubnet{ [CmdletBinding()] param ( $FilterIPRange, $bool = "AND", $not = 0, $start, $end ) $FilterIPRange.SetAttribute("bool",$bool) $FilterIPRange.SetAttribute("not",$not) $FilterIPRange.SetAttribute("min",$start) $FilterIPRange.SetAttribute("max",$end) } $ActualPrintersList = Get-WmiObject -Class win32_share -computer print-cluster-1 | Where-Object Name -like "*PRN*" | Select-Object -ExpandProperty Name ForEach ($PrinterItem in ($PrintersCSV | Sort-Object Name)) { if (!$PrinterItem.uid){ $uid = "{"+([guid]::NewGuid()).Guid.ToUpper()+"}" Write-Host "Printer $($PrinterItem.Name) is new. Policy item ID: $uid" } else { $uid = $PrinterItem.uid } $SharedPrinter = $PrintersGPP.CreateElement("SharedPrinter") NewSharedPrinter -SharedPrinter $SharedPrinter -name $PrinterItem.Name -action "U" -uid $uid $Filters = $SharedPrinter.AppendChild($PrintersGPP.CreateElement("Filters")) if ($PrinterItem.ByGroup -ieq "yes") { try { Get-ADGroup -Identity $PrinterItem.Name | Out-Null } catch { Write-Host "Creating group $($PrinterItem.Name)" New-ADGroup -Name $PrinterItem.Name ` -Path "OU=    ,OU=User Groups,DC=DOM,DC=COM" -GroupScope DomainLocal } $FilterGroup = $PrintersGPP.CreateElement("FilterGroup") NewFilterGroup -FilterGroup $FilterGroup -name $PrinterItem.Name -sid (Get-ADGroup -Identity $PrinterItem.Name).SID.Value $Filters.AppendChild($FilterGroup) | Out-Null } $FilterNetwork = .\PSipcalc.ps1 -NetworkAddress $PrinterItem.Subnet $FilterIPRange = $PrintersGPP.CreateElement("FilterIpRange") NewFilterSubnet -FilterIPRange $FilterIPRange -start $FilterNetwork.HostMin -end $FilterNetwork.HostMax $Filters.AppendChild($FilterIPRange) | Out-Null $Printers.AppendChild($SharedPrinter) | Out-Null $RevertSharedPrinter = $PrintersGPP.CreateElement("SharedPrinter") NewSharedPrinter -SharedPrinter $RevertSharedPrinter -name $PrinterItem.Name -action "D" -uid $uid if ($PrinterItem.ByGroup -ieq "yes") { $bool = "OR" } else { $bool = "AND" } $Filters = $RevertSharedPrinter.AppendChild($PrintersGPP.CreateElement("Filters")) if ($PrinterItem.ByGroup -ieq "yes") { $FilterGroup = $PrintersGPP.CreateElement("FilterGroup") NewFilterGroup -FilterGroup $FilterGroup -name $PrinterItem.Name -sid (Get-ADGroup -Identity $PrinterItem.Name).SID.Value -bool "AND" -not 1 $Filters.AppendChild($FilterGroup) | Out-Null } $FilterIPRange = $PrintersGPP.CreateElement("FilterIpRange") NewFilterSubnet -FilterIPRange $FilterIPRange -start $FilterNetwork.HostMin -end $FilterNetwork.HostMax -bool $bool -not 1 $Filters.AppendChild($FilterIPRange) | Out-Null $Printers.AppendChild($RevertSharedPrinter) | Out-Null if ("\\print-cluster-1\$($PrinterItem.Name)" -NotIn $ActualPrintersList) { Write-Host "Adding printer $($PrinterItem.Name) to print-cluster-1..." Start-Process -FilePath .\CreateRemotePrinter.bat -ArgumentList "$($PrinterItem.Name) `"$($PrinterItem.Driver)`" `"$($PrinterItem.Location)`" `"$($PrinterItem.Type)`"" -Wait } } $PrintersGPP.Save("\\COMDOM\SysVol\COMMON.DOMAIN\Policies\{f985a9ae-cb71-468b-8a99-e2c7f428aa2f}\User\Preferences\Printers\Printers.xml") $PrintersGPP.Save(".\Printers.xml") 
CreateRemotePrinter.bat
 @echo off SET PRTOOLS="c:\Windows\System32\Printing_Admin_Scripts\en-US" SET SETACL="SetACL.exe" SET PRNBRM="C:\Windows\System32\spool\tools\PrintBrm.exe" cscript /nologo %PRTOOLS%\prnport.vbs -s print-cl-node-1 -a -r %1 -h %1.common.domain -t -o raw -me cscript /nologo %PRTOOLS%\prnmngr.vbs -s print-cl-node-1 -a -p %1 -m %2 -r %1 cscript /nologo %PRTOOLS%\prncnfg.vbs -s print-cl-node-1 -t -p %1 -h %1 -l %3 -m %4 +shared %SETACL% -on \\print-cl-node-1\%1 -ot prn -actn ace -ace "n:STN-TN\%1;p:man_docs,print" %PRNBRM% -b -nobin -s print-cl-node-1 -f temp.printerexport %PRNBRM% -r -d printerexport -f temp.printerexport del /f /q temp.printerexport del /s /f /q printerexport\LMONS printerexport\PRTPROCS echo ^<SpoolerAttrib /^> > printerexport\BrmSpoolerAttrib.xml echo ^<PPROCS /^> > printerexport\PProcs.xml echo ^<PRINTERDRIVERS /^> > printerexport\BrmDrivers.xml echo ^<LMONS Arch="Windows x64"/^> > printerexport\BRMLMons.xml %PRNBRM% -b -d printerexport -f temp.printerexport del /s /f /q printerexport %PRNBRM% -r -s print-cluster-1 -f temp.printerexport -p all -o force del /f /q temp.printerexport cscript /nologo %PRTOOLS%\prnmngr.vbs -s print-cl-node-1 -d -p %1 cscript /nologo %PRTOOLS%\prnport.vbs -s print-cl-node-1 -d -r %1 
El archivo resultante Printers.xml
 <?xml version="1.0" encoding="utf-8"?> <Printers clsid="{1F577D12-3D1B-471e-A1B7-060317597B9C}"> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="Delete All" status="Delete All" image="3" uid="{21097DBD-285D-48C3-B042-7746D7E6DA1B}" bypassErrors="1" disabled="1"> <Properties action="D" path="" default="0" deleteAll="1" port="" /> <Filters> <FilterRunOnce id="{F2537B78-C7D7-43DF-98D6-B32E90644825}" hidden="1" not="0" bool="AND" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BARAB-061" status="PRN-BARAB-061" image="2" uid="{43231EA0-A4A3-4F1A-8A25-95BC4FEFBCC6}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-BARAB-061" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-BARAB-061" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.142.1" max="192.168.142.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BARAB-061" status="PRN-BARAB-061" image="3" uid="{43231EA0-A4A3-4F1A-8A25-95BC4FEFBCC6}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-BARAB-061" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-BARAB-061" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.142.1" max="192.168.142.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BATAY-042" status="PRN-BATAY-042" image="2" uid="{4740604B-C403-4511-91B0-689A197260F3}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-BATAY-042" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-BATAY-042" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BATAY-042" status="PRN-BATAY-042" image="3" uid="{4740604B-C403-4511-91B0-689A197260F3}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-BATAY-042" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-BATAY-042" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BUY---001" status="PRN-BUY---001" image="2" uid="{457DB3FE-E35F-450E-B1D6-912F0D831573}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-BUY---001" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-BUY---001" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.44.1" max="192.168.44.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-BUY---001" status="PRN-BUY---001" image="3" uid="{457DB3FE-E35F-450E-B1D6-912F0D831573}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-BUY---001" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-BUY---001" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.44.1" max="192.168.44.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-ELAB-064" status="PRN-ELAB-064" image="2" uid="{52069D45-EF86-442D-A157-368D7510A1CF}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-ELAB-064" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="0" min="192.168.140.1" max="192.168.140.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-ELAB-064" status="PRN-ELAB-064" image="3" uid="{52069D45-EF86-442D-A157-368D7510A1CF}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-ELAB-064" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="1" min="192.168.140.1" max="192.168.140.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-EMPTY-002" status="PRN-EMPTY-002" image="2" uid="{475578CB-689F-463B-9710-AE207973146C}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-EMPTY-002" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-EMPTY-002" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.199.1" max="192.168.199.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-EMPTY-002" status="PRN-EMPTY-002" image="3" uid="{475578CB-689F-463B-9710-AE207973146C}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-EMPTY-002" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-EMPTY-002" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.199.1" max="192.168.199.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-KIRILL-081" status="PRN-KIRILL-081" image="2" uid="{421FC2DE-2E97-49FC-AEB0-3070B0166AD5}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-KIRILL-081" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="0" min="192.168.196.1" max="192.168.196.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-KIRILL-081" status="PRN-KIRILL-081" image="3" uid="{421FC2DE-2E97-49FC-AEB0-3070B0166AD5}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-KIRILL-081" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="1" min="192.168.196.1" max="192.168.196.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-KOTOV-013" status="PRN-KOTOV-013" image="2" uid="{4DFFBA1F-48D2-4824-B2EB-0AAD12B6A9D6}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-KOTOV-013" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-KOTOV-013" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-KOTOV-013" status="PRN-KOTOV-013" image="3" uid="{4DFFBA1F-48D2-4824-B2EB-0AAD12B6A9D6}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-KOTOV-013" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-KOTOV-013" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-LIPKI-003" status="PRN-LIPKI-003" image="2" uid="{4794D22E-6586-4A81-A85D-A21FB8B209CF}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-LIPKI-003" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="0" min="192.168.44.1" max="192.168.44.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-LIPKI-003" status="PRN-LIPKI-003" image="3" uid="{4794D22E-6586-4A81-A85D-A21FB8B209CF}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-LIPKI-003" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="1" min="192.168.44.1" max="192.168.44.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-NALTA-028" status="PRN-NALTA-028" image="2" uid="{35F6CF36-2A24-4A81-B061-8BE71CEC27EA}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-NALTA-028" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-NALTA-028" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.192.1" max="192.168.192.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-NALTA-028" status="PRN-NALTA-028" image="3" uid="{35F6CF36-2A24-4A81-B061-8BE71CEC27EA}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-NALTA-028" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-NALTA-028" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.192.1" max="192.168.192.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-PYSHM-004" status="PRN-PYSHM-004" image="2" uid="{45509B48-E7BC-4497-9665-86D4E1E96FE1}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-PYSHM-004" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="0" min="192.168.143.1" max="192.168.143.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-PYSHM-004" status="PRN-PYSHM-004" image="3" uid="{45509B48-E7BC-4497-9665-86D4E1E96FE1}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-PYSHM-004" default="0" port="" /> <Filters> <FilterIpRange bool="AND" not="1" min="192.168.143.1" max="192.168.143.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-TARUS-002" status="PRN-TARUS-002" image="2" uid="{398F4A94-530C-4E3B-8A30-4288D5E8854D}" userContext="1" bypassErrors="1"> <Properties action="U" comment="" path="\\print-cluster-1.common.domain\PRN-TARUS-002" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="0" name="COMDOM\PRN-TARUS-002" sid="" userContext="1" /> <FilterIpRange bool="AND" not="0" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="PRN-TARUS-002" status="PRN-TARUS-002" image="3" uid="{398F4A94-530C-4E3B-8A30-4288D5E8854D}" userContext="1" bypassErrors="1"> <Properties action="D" comment="" path="\\print-cluster-1.common.domain\PRN-TARUS-002" default="0" port="" /> <Filters> <FilterGroup bool="AND" not="1" name="COMDOM\PRN-TARUS-002" sid="" userContext="1" /> <FilterIpRange bool="OR" not="1" min="192.168.128.1" max="192.168.129.254" /> </Filters> </SharedPrinter> </Printers> 
Resultado en el servidor de impresión
imagen

Source: https://habr.com/ru/post/es421211/


All Articles