PowerShell脚本抛出错误但仍会产生结果

时间:2017-04-20 22:24:33

标签: powershell printing remote-server windows-server-2012-r2

我有一台打印服务器,大约有50台打印机安装了各种驱动程序,并非所有配置都设置相同。我正在基于新的IP架构将打印机移动到新的IP地址,我需要跟踪每台打印机,旧IP和新IP。然后我需要捕获每个配置的现有配置,以便我可以添加打印机并保持设置与以前相同。

所以,情况就是这样。我使用了以下内容:

PS C:\Users\a> Get-Printer | Where-Object -Property Name -match seattle | Get-PrintConfiguration

输出结果为:

Get-PrintConfiguration : An error occurred while performing the specified operation.  See the error details for more information.
At line:1 char:60
+ Get-Printer | Where-Object -Property Name -match seattle | Get-PrintConfiguratio ...
+                                                            ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (MSFT_PrinterConfiguration:ROOT/StandardCi...erConfiguration) [Get-PrintConfiguration], CimException
+ FullyQualifiedErrorId : HRESULT 0x8000ffff,Get-PrintConfiguration

Get-PrintConfiguration : An error occurred while performing the specified operation.  See the error details for more information.
At line:1 char:60
+ Get-Printer | Where-Object -Property Name -match seattle | Get-PrintConfiguratio ...
+                                                            ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (MSFT_PrinterConfiguration:ROOT/StandardCi...erConfiguration) [Get-PrintConfiguration], CimException
+ FullyQualifiedErrorId : HRESULT 0x8000ffff,Get-PrintConfiguration


PrinterName     ComputerName    Collate    Color      DuplexingMode       
-----------     ------------    -------    -----      -------------       
Seattle_Coun...                 False      True       OneSided            
SeattleWhsLaser                 True       True       OneSided            
Seattle Ware...                 False      False      OneSided            
Seattle_Seco...                 True       False      OneSided            
Seattle_Test...                 True       True       OneSided            
SeattleCoun                     True       True       OneSided            
Seattle - SH...                 True       True       OneSided           

如果我将该行缩短为:

PS C:\Users\a> Get-Printer | Where-Object -Property Name -match $city 

输出是我期望的全部9台打印机:

Name                           ComputerName    Type         DriverName                PortName        Shared   Published 
----                           ------------    ----         ----------                --------        ------   --------- 
Seattle_Test_Printer-Seattl...                 Local        HP Universal Printing PS  192.168.100.25  True     True      
Seattle_Second_Floor                           Local        HP Universal Printing ... IP_192.168.1... True     True      
Seattle_Counter_Laser                          Local        HP Universal Printing ... IP_192.168.1... True     False     
SeattleWhsLaser                                Local        HP Universal Printing ... 192.168.100.82  True     True      
SeattleCoun                                    Local        HP Universal Printing ... IP_192.168.1... True     True      
Seattle Warehouse ZDesigner...                 Local        ZDesigner 110XiIII Plu... 192.168.100.... True     True      
Seattle Upstairs OKI PCL6 C...                 Local        OKI PCL6 Class Driver     192.168.100.14  True     True      
Seattle - SHARP MX-5141N PCL6                  Local        SHARP MX-5141N PCL6       192.168.100.30  True     False     
Seattle (new) HP LaserJet P...                 Local        HP LaserJet P3011/P301... 192.168.100.25  True     True      

我应该总共得到9台打印机,但是我不明白为什么我得到2台打印机的错误并且其余部分得到了好的结果?最终目标是使其自动化并记录所有更改。

1 个答案:

答案 0 :(得分:0)

Get-PrinterGet-PrintConfiguration实际上只是Get-CimInstance次调用的包装器,可以让我们更轻松。我们可以使用CIM对象来完成所有这些,有时候它会更好地运行。要获得打印机,请使用:

Get-CimInstance -ClassName MSFT_Printer -Namespace 'ROOT/StandardCimv2'

然后你可以将它传递到Where语句(由你提供),以将结果细化为你想要的结果:

Get-CimInstance -ClassName MSFT_Printer -Namespace 'ROOT/StandardCimv2' | where {($_.location -split '\.')[2] -eq $locationNumber -or ($_.sharename -match $city) -or ($_.name -match $city) -or ($_.location -match $city)}

之后,您可以调用MSFT_PrinterConfiguration类的GetByPrinterName方法来获取每个打印机的配置(在ForEach循环中),如下所示:

|%{Invoke-CimMethod -ClassName MSFT_PrinterConfiguration -Namespace 'ROOT/StandardCimv2' -MethodName GetByPrinterName -Arguments @{'PrinterName'=$_.Name} |% cmdletOutput}

所以,如果是我,我会做这样的事情:

$Printers = Get-CimInstance -ClassName MSFT_Printer -Namespace 'ROOT/StandardCimv2' | where {($_.location -split '\.')[2] -eq $locationNumber -or ($_.sharename -match $city) -or ($_.name -match $city) -or ($_.location -match $city)}
$Output = @{}
ForEach($Printer in $Printers){
    $Config = Invoke-CimMethod -ClassName MSFT_PrinterConfiguration -Namespace 'ROOT/StandardCimv2' -MethodName GetByPrinterName -Arguments @{'PrinterName'=$Printer.Name} |% cmdletOutput
    $Printer | Add-Member 'ConfigInfo' $Config
    $Output.add($Printer.Name,$Printer)
}

那么它的作用是获取所有打印机,以及仅指定分支的过滤器。然后它创建一个空的哈希表。然后它循环通过打印机,并为每个打印机恢复该打印机的配置信息。然后它将其作为' ConfigInfo'添加到打印机对象中。属性。最后,它为该打印机的名称添加了一个记录,并将修改后的打印机对象作为值。所以最后你可以做到:

$Output['Seattle_Counter_Laser']

这会向您显示打印机的信息,例如其运行的驱动程序以及端口上列出的IP地址。

或者如果您想通过PortName属性中的IP查找它,您可以执行以下操作:

$Output.values|Where{$_.PortName -match '192.168.100.82'}

然后获取您可以执行的配置信息:

$Output['Seattle_Counter_Laser'].ConfigInfo

我会使用Export-CliXml导出整个哈希表并保持安全,因为如果事情横向移动并且打印机都停止工作,那么您将拥有该文件中所需的一切,以便将它们恢复到现在的状态