Hop*_*00b 10 scripting active-directory group-policy network-printer
由于我无法控制的原因,我的任务是设置 GPO/GPP 以将我们的 100 多台打印机部署到我们的 1000 多个客户。
好消息是我们有十多个站点,而且在大多数情况下,我可以将站点 X 的所有打印机推送到站点 X 的所有客户端 PC。
坏消息是,我知道的两种方法(“使用组策略部署...”,来自打印服务器”和使用 GPP/组策略首选项)涉及的手动工作比我愿意的要多得多这么多打印机。我什至似乎无法选择打印服务器上的所有打印机并使用该Deploy with Group Policy...选项,例如-它希望我逐一执行此操作,这不会发生。GPP 甚至更糟,因为它希望我从打印服务器中选择打印机的路径,然后手动输入它应该能够从打印机连接中获取的一堆信息(例如打印机 IP)。
我的用于将打印服务器上的所有打印机添加到 GPO/GPP 的脚本的 Google-Fu 是空的,我似乎看不到以半自动方式执行此操作的另一种方法,但我坚持相信我遗漏了一些东西,因为任何理智的人都不会选择手动将数百台打印机添加到 GPO 中。
理想情况下,我想找到一种使用 GPP 的编程方式,但在这种情况下,任何不涉及数十小时手动添加打印机的解决方案都会很棒。
有没有人有办法做到这一点,或者我是否需要构建一个 PowerShell 脚本和/或诱使下属这样做?
在我看来,组策略的 Powershell 管理在没有第三方(商业)产品的情况下很糟糕。
我认为您被困在组策略对象中的 XML(或HTML,如果您愿意)来做您正在寻找的事情。
幸运的是,XML 看起来并不那么可怕。每台打印机的 UID 值(我相信这是 @KatherineVillyard 在她的评论中所指的)只是为 XML 中引用的每台打印机生成的随机 GUID。
这是一些示例 Powershell 代码,无耻地模仿了 Katherine 的代码:
@"
<?xml version="1.0" encoding="utf-8"?>
<Printers clsid="{1F577D12-3D1B-471e-A1B7-060317597B9C}" disabled="0">
"@
$net = New-Object -COMObject WScript.Network
$printserver = 'print-server'
$printerlist = Get-WMIObject -class Win32_Printer -computer $printserver | Where-Object {$_.ShareName -ne $null} | Select-Object ShareName
foreach ($printer in $printerlist)
{
$date = Get-Date
echo ' <SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}"'
' name="' + $printer.ShareName + '"' | echo
' status="' + $printer.ShareName + '"' | echo
echo ' image="2"'
' changed="' + $date + '"' | echo
$ng = [GUID]::NewGuid().ToString('B')
' uid="' + $ng + '">' | echo
echo ' <Properties'
echo ' action="R"'
echo ' comment=""'
' path="\\' + $printserver + '\' + $printer.ShareName + '"' | echo
echo ' location=""'
echo ' default="1"'
echo ' skipLocal="1"'
echo ' deleteAll="0"'
echo ' persistent="0"'
echo ' deleteMaps="0"'
echo ' port=""/>'
echo ' </SharedPrinter>'
}
@"
</Printers>
"@
Run Code Online (Sandbox Code Playgroud)
(我写了非常非常丑陋的 Powershell 代码。)
我实际上并没有尝试让 GPP CSE 解析这个 XML。XML 确实验证,至少。
我开始考虑使用Get-GPO并解析 GUID 来编写一些怪物以获取 SYSVOL 中 GPO 的文件系统路径,但是,鉴于今晚我需要做一些实际工作,我想我要离开了作为读者的练习。>smile< 不过应该是非常可行的。
我非常努力地backup-GPO在谷歌上搜索,甚至希望能够破解生成的 XML 文件并重新导入它,但我怀疑 PowerShell 脚本是在你的未来。
它没有那么坏。您可以从最近的服务器生成打印机列表,然后循环遍历并映射它们。
像这样的东西:
$net = New-Object -COMObject WScript.Network
$printserver = 'yourserver'
$printerlist = Get-WMIObject -class Win32_Printer -computer $printserver | Where-Object {$_.ShareName -ne $null} | Select-Object ShareName
foreach ($printer in $printerlist)
{
$printerpath = '\\' + $printserver + '\' + $printer.ShareName
#echo $printerpath
$net.AddWindowsPrinterConnection($printerpath)
}
Run Code Online (Sandbox Code Playgroud)
如果打印机被命名为逻辑事物,并且有一些逻辑方法来识别机器,那么您可能能够对其进行更多改进。例如,我曾经根据提取客户端 IP 地址来选择最近的服务器。如果 IP 地址为 10.20.*,则转到 server1。等等。
我希望这有帮助。
编辑:
查看@EvanAnderson 的文档,我很确定 XML 是可破解的。
我导出的文件的相关部分(带有编辑):
<DSObject bkp:Path="CN={GUIDHERE},CN=PushedPrinterConnections,%GPO_MACH_DSPATH%" bkp:SourceExpandedPath="CN={13B9B596-452C-4652-A05D-78EF06610134},CN=PushedPrinterConnections,CN=Machine,CN={44A99FBA-0DB3-484C-808E-3DDAE9932A2B},CN=Policies,CN=System,DC=Domainname,DC=extension" bkp:ObjectClass="msPrint-ConnectionPolicy">
<DSAttributeMultiString bkp:DSAttrName="showInAdvancedViewOnly">
<DSValue><![CDATA[TRUE]]></DSValue>
</DSAttributeMultiString>
<DSAttributeMultiString bkp:DSAttrName="uNCName">
<DSValue><![CDATA[\\Servername\PrinterShareName]]></DSValue>
</DSAttributeMultiString>
<DSAttributeMultiString bkp:DSAttrName="serverName">
<DSValue><![CDATA[\\Servername]]></DSValue></DSAttributeMultiString>
<DSAttributeMultiString bkp:DSAttrName="printAttributes">
<DSValue><![CDATA[0]]></DSValue>
</DSAttributeMultiString>
<DSAttributeMultiString bkp:DSAttrName="printerName">
<DSValue><![CDATA[PrinterShareName]]></DSValue>
</DSAttributeMultiString>
</DSObject>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6716 次 |
| 最近记录: |