因此,我尝试使用 PowerShell 添加打印机。在此之前,我确实研究过使用 GPO 来部署打印机,但一直收到错误。我的前任创建了一个 VBS 脚本来部署它们,但我正在将它们全部转换为 PowerShell。现在,我首先使用带有 -ConnectionName 参数的 Add-Printer cmdlet。这起初有效,但经过多次尝试后,我不断收到错误消息,提示无法访问打印机。然后我想到使用 COM 对象,这很有效。但是我遇到了一个障碍。如果打印机已经添加,它们就会消失,然后我收到一条错误消息,提示“值不在预期范围内”。
该脚本通过 GPO 登录调用。我以这种方式部署它们的原因是所有用户配置文件都被清除(使用 WMI 对象),并且每个登录会话对于用户来说都应该是新的。此外,他们没有管理权限。但是,他们确实可以访问打印服务器,并且他们确实有能力添加打印机。我知道这一点,因为我可以在用户的上下文中手动运行脚本,并且它运行得很好。我还可以看到正在添加的打印机,如果它们还不在那里。只是如果用户注销,然后重新登录,打印机就在那里,但随后它们会一个接一个地消失,即使每次都是第一次创建配置文件。所以我想我可以删除所有打印机(Microsoft PDF 除外),但这似乎也行不通。
这是我使用的代码。显然,名称已更改,但在实际脚本中,名称没有问题。我也在实际脚本中使用 FQDN。
Start-Transcript -Path C:\Temp\PowerShellLog.txt
$printers = Get-Printer
Get-Printer | Where-Object Name -NotLike "*PDF*" | Remove-Printer
$var = New-Object -COM WScript.Network
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A P1") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A P1") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A P2") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A P2") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A Duplex") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A Duplex") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A Color") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A Color") }
#Makes default printer
$var.setdefaultprinter("\\printerserver.company.com\LAB A P1")
如果打印机已安装(但随后消失),则会收到以下错误:
Value does not fall within the expected range. At \\server\Hidden$\printer.ps1:12 char:87 + ... Duplex") { $var.AddWindowsPrinterConnection("\\printerserver ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], ArgumentException + FullyQualifiedErrorId : System.ArgumentException
答案1
因此,经过过去 3 个小时的研究,我弄清楚了问题所在可能是。在启动时,我们会清理所有用户配置文件。这需要管理访问权限,因此它在系统级别关闭。由于打印机是在用户上下文中添加的,因此配置文件清理不会同时清理打印机。我认为存在一些冲突,打印机陷入了困境。因此,如果我去添加具有相同网络路径的同一台打印机,它就会消失。
话虽如此,我有一个注销脚本来清空回收站,因为这也在用户空间中。就在那下面,我添加了Get-WmiObject -Class Win32_Printer | Where-Object { $_.Network -eq 'true' } | ForEach-Object { $_.delete() }
一个应该在注销期间清理网络打印机的脚本。就脚本而言,COM 对象可以工作,但我想使用WMI 对象会同样有效。这是登录时添加打印机的脚本。我希望这能在未来帮助其他人。
$printclass = [wmiclass]"win32_printer"
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A P1")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A P2")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A Color")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A Duplex")
#Makes default printer
$P1Printer = Get-WmiObject -Class Win32_Printer | Where-Object { $_.Network -eq 'true' -and $_.Name -like "*LAB A P1*" }
$P1Printer.SetDefaultPrinter()