通过GPO / GPP部署打印机-是否有编程选项?


10

由于我无法控制的原因,我的任务是设置GPO / GPP,以将我们的100多台打印机部署到我们的1000多台客户端。

好消息是,我们有十几个站点,在大多数情况下,我被允许将站点X的所有打印机推送到站点X的所有客户端PC。

坏消息是,我知道怎么做的两种方式(“从打印服务器部署组策略...”使用GPP /组策略首选项)涉及的手动工作要比我愿意做的要多得多。这么多的打印机,例如,我什至似乎都无法选择打印服务器上的所有打印机并使用该Deploy with Group Policy...选项-它希望我一步一步地做到这一点,这不会发生。GPP更加糟糕,因为它希望我从打印服务器中选择打印机的路径,然后手动打入一堆应该能够从打印机连接中获取的信息(例如打印机IP)。

我的Google-Fu脚本将打印服务器上的所有打印机添加到GPO / GPP时显示为空,我似乎看不到另一种以半自动方式执行此操作的方法,但我坚持相信我会丢失某些东西,因为任何理智的人都不会选择将几百台打印机手动添加到GPO中。

理想情况下,我想找到一种编程方式来使用GPP,但是在这种情况下,任何不涉及数十小时手动添加打印机的解决方案都很好。

有没有人可以做到这一点,或者我是否需要构建PowerShell脚本和/或欺骗下属来做到这一点?


1
正如我在今天早些时候的聊天中向您提到的那样,有一个COM界面,用于以编程方式创建和链接GPO ...都以开头$GPM = New-Object -ComObject GPMgmt.Gpm。我认为该接口虽然是绝对可以使用的工具,但它可能会为您提供比其他简单地破解看起来像真正的GPO的XML更受支持的方法。没有人喜欢COM。我们所有的Powershellers最少。
瑞安·里斯

1
@RyanRies是的,我仍在想一想,我尚未决定的一件事是我的股票是否需要支撑,或者只是一次将其设置为第一名。不管我做什么,我都可以肯定地将它张贴在这里。
HopelessN00b 2014年

当您说您需要部署100台打印机时,并不是说所有计算机(1..1000)都应该拥有所有100台打印机,对吗?
2014年

1
@AdilHindistan否。每台计算机都应在其站点上获得所有可用的打印机。(或多或少。)但是将它们分开并不是难事。首先,这使打印机成为GPO,这比您想象的要痛苦得多。
HopelessN00b 2014年

Answers:


7

我非常努力地搜索谷歌,甚至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)
}

如果打印机被命名为逻辑事物,并且有某种逻辑方法可以识别机器,那么您也许可以对其进行进一步完善。例如,我以前通常基于拉出客户端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>

这是一个很好的答案(我可能最终会使用类似的方式来满足我们的某些截止日期),但是我怀疑这个问题的未来实际上是实习生或下属,因为我们被要求使用GPO / GPP进行分配打印机。尽管PS登录脚本从技术上来说可以满足该要求,但我希望管理层能够烦恼于我,以至于我不值得花那么多时间这样做。
HopelessN00b 2014年

唉。:(该GPO PowerShell命令似乎备份,还原,创建空白的对象......但不会增加GPO时,有打印机策略看XML对象。完全被破解除了GUID。
凯瑟琳Villyard

1
是的,如果没有第三方工具,则通过PowerShell进行GPO / GPP自动化将非常痛苦。 我发现了一些看起来不错的东西,但事实是它需要第三方软件套件,我们可能不被允许购买...因此可能是一些脚本,例如您在现有站点特定的XML中进行编辑GPO ...我想我会在完成后在这里发布。
HopelessN00b 2014年

8

组策略的PowerShell的管理太烂 W / O第三方(商业)产品,在我看来。

我认为您无法在组策略对象中遍历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>
"@

(我编写了非常非常丑陋的Powershell代码。)

我实际上并没有尝试让GPP CSE解析此XML。XML至少会进行验证。

我开始考虑编写一些怪异的东西,Get-GPO并使用GUID解析出SYSVOL中GPO的文件系统路径,但是鉴于我今晚需要做一些实际工作,我想我要离开了作为读者的练习。>微笑<但这应该是高度可行的。


如果它是随机的GUID,则肯定是可入侵的。我也刚刚更新了我的。h
Katherine Villyard 2014年

在组策略备份中修改XML当然可以,但是在SYSVOL中“实时”更改XML也应该是可行的(前提是要么勇敢,愚蠢,要么像我一样)。由于我今晚有真正的工作要做(并且由于本季度我再次回到@ewwhite进行代表排名),我认为我将省去装载那把特定枪支并将其对准其他人的脚步。>咯咯地笑
Evan Anderson

我很勇敢,但我并不那么勇敢。;)生成的文件,测试其导入测试环境等
凯瑟琳Villyard

2
Powershell确实需要更多GPO选项。Get-Link,Set-Link,New-GPO和Set-GPORegistry不够好……
Mark Henderson

内置的PowerShell命令有时还不够。在这种情况下,我建议您看一下“ GPO Guy的解决方案”。他拥有一家公司:sdmsoftware.com
Adil Hindistan 2014年

0

我最近进行了一个类似的项目,在研究了良好的GPO推送方法与较新的GPP与脚本编写之后,我选择了对整个脚本进行编写。我不知道哪种方法最适合您,但是这里有一些建议:

  • 理想情况下,使用具有新操作系统(Windows 8/2012 +)的客户端连接到打印服务器并从打印服务器获取打印机信息:

    Get-Printer-计算机PrintServerName

  • 使用AD安全组将打印队列映射到计算机。因此,假设您有一个名为\ PrintServer1 \ MyColorPrinter123的打印队列(从上述命令中收集),创建了一个安全组(例如printer.group.PrintServer1.MyColorPrinter123),并将计算机添加到该组中

  • 在启动脚本中,具有一项功能,可以在启动计算机时检查计算机的组成员身份,并查看它是否属于任何打印机组。如果是,请使用内置的printui.exe(或printui.dll)命令来映射打印机,如下所示

    调用表达式'rundll32 printui.dll,PrintUIEntry / ga / n“ \ PrintServer1 \ MyColorPrinter123” / q'

  • 一旦计算机启动,该打印后台处理程序服务将向所有要登录的用户推送“打印连接”,这是GPO过去所做的。

您可以进行更详细的描述**,但是从总体上讲,这是需要的。

**我创建了一个GUI,允许用户(实际上是技术人员)选择任何打印服务器,并为他们提供该服务器上的打印机列表。如果他们选择一个,则可以看到它的所有属性。该信息来自我上面提到的Get-Printer。如果将该数据导出为csv,则可以重新使用它以显示信息。

**技术人员使用该GUI发送请求,以将计算机添加到应该连接的打印机上。这是一个“请求”,因为他们在AD中没有权限。

**一个简单的后端脚本监视文件夹并将计算机添加到我上面提到的打印机组中。因此,如果您已经知道谁应该购买哪台打印机,那太好了,您可以轻松实现。使用AD Cmdlet将计算机添加到组是一项简单的工作。

**您还可以安排作业以检查打印服务器,以查看是否有任何新的打印队列,并将它们与AD组进行比较。

因此,创建一个“托管”解决方案有点麻烦,但是从基础知识开始很容易,然后继续添加即可拥有一个非常灵活,易于使用且不涉及GPO的系统...只是一点点PowerShell

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.