首页 > 解决方案 > 在 PowerShell 中获取打印机的驱动程序版本和打印机名称

问题描述

你好 :)

希望你今天过得很好。

好吧,我被要求拿出一份关于我们所有打印机和他们正在使用的驱动程序版本的报告(全球超过 1300 台打印机和 150 多台主机)。

那时,我可以检索到我需要的大部分信息。

这是到目前为止的代码:

$ReportFileName = "c:\SAC_IS\printerreport.csv" 
$PrintServersList="C:\SAC_IS\servlist_TEST.txt" 

$servers =  Get-Content -Path $PrintServersList 
$allprinters = @() 
foreach( $server in $servers ){ 
Write-Host "checking $server ..." 
$printers = $null 
$printers = Get-WmiObject -class Win32_Printer -computername $server | select Name,Shared,ShareName,Local, DriverName, PortName, @{n="HostName";e={$server}} ,@{n="Driver Version";e={Get-WmiObject Win32_PrinterDriver -ComputerName $server | select @{n="Version";e={(Get-Item $_.DriverPath).VersionInfo.ProductVersion}}}}, Location,Comment,SpoolEnabled,Published
$allprinters += $printers 
 } 

$allprinters | Export-CSV -Path $ReportFileName -Delimiter ";" -NoTypeInformation -Force -Encoding UTF8 

我的问题是我无法检索打印机使用的驱动程序版本:

CSV 输出

运行脚本完全没有返回错误:/

请问可以伸出援手吗?:D

辅助问题,为什么每个主机需要 5 分钟。这不能更快吗?

非常感谢所有可以提供帮助的人:)

标签: powershell

解决方案


您的代码的主要内容可能是,尽管您在远程机器上工作,但您使用本地DriverPath 来获取驱动程序版本,并且也没有指定您的目标驱动程序。

下面的代码使用一个小的帮助函数来使用 UNC 路径而不是本地路径从服务器上的实际驱动程序文件中获取驱动程序版本。另外,我认为在这里使用函数可以使代码更具可读性。

为了尝试加快速度,我使用Get-CimInstance而不是Get-WmiObject收集对象而不添加到预定义的数组:

$ReportFileName   = 'C:\SAC_IS\printerreport.csv' 
$PrintServersList = 'C:\SAC_IS\servlist_TEST.txt' 

function Get-PrinterProductVersion ($server, $printer) {
    $prn = Get-CimInstance -ClassName Win32_PrinterDriver -ComputerName $server | 
           Where-Object { ($_.Name -split ',')[0] -eq $($printer.DriverName) }
    if ($prn) { 
        # transform the local driver path into a UNC path
        $path = Join-Path -Path "\\$server" -ChildPath ($prn.DriverPath -replace ':', '$')
        (Get-Item $path).VersionInfo.ProductVersion 
    }
}

$allprinters = Get-Content -Path $PrintServersList | ForEach-Object {
    # capture the server name in a self-defined variable
    $server = $_
    Write-Host "checking server $server ..." 
    Get-CimInstance -ClassName Win32_Printer -ComputerName $server | 
        Select-Object Name,Shared,ShareName,Local,DriverName,PortName, 
                      @{Name = "HostName"; Expression = { $server }},
                      @{Name = "Driver Version"; Expression = { Get-PrinterProductVersion $server $_ }}, 
                      Location,Comment,SpoolEnabled,Published
 } 

# output on screen
$allprinters

# output to CSV file
$allprinters | Export-CSV -Path $ReportFileName -Delimiter ";" -NoTypeInformation -Force -Encoding UTF8 

PS 就我个人而言,我不想要一个名称中带有空格的标题,"Driver Version"但这取决于你


编辑

我自己无法对此进行测试,但是如果您让服务器自己收集所需的打印机信息,也许您可​​以加快速度。

像这样的东西:

$ReportFileName   = 'C:\SAC_IS\printerreport.csv' 
$PrintServersList = 'C:\SAC_IS\servlist_TEST.txt' 

# create a scriptblock for each server to execute
$scriptBlock = {
    function Get-PrinterProductVersion ($printer) {
        # or try with 'Get-WmiObject -Class Win32_PrinterDriver' if Get-CimInstance not available
        $prn = Get-CimInstance -ClassName Win32_PrinterDriver | 
               Where-Object { ($_.Name -split ',')[0] -eq $($printer.DriverName) }
        if ($prn) { (Get-Item $prn.DriverPath).VersionInfo.ProductVersion }
    }

    # or try with 'Get-WmiObject -Class Win32_Printer' if Get-CimInstance not available
    Get-CimInstance -ClassName Win32_Printer | 
        Select-Object Name,Shared,ShareName,Local,DriverName,PortName, 
                      @{Name = "HostName"; Expression = { $env:COMPUTERNAME }},
                      @{Name = "Driver Version"; Expression = { Get-PrinterProductVersion $_ }}, 
                      Location,Comment,SpoolEnabled,Published


}

# create a list to gather all results from the servers
$allprinters = New-Object System.Collections.Generic.List[object]

Get-Content -Path $PrintServersList | ForEach-Object {
    Write-Host "checking server $_ ..." 
    if (Test-Connection -ComputerName $_ -Count 1 -Quiet) {
        $printers = Invoke-Command -ScriptBlock $scriptBlock -ComputerName $_
        $allprinters.AddRange($printers)
    }
    else {
        Write-Warning "Server $_ cannot be reached"
    }
 } 

# output on screen
$allprinters

# output to CSV file
$allprinters | Export-CSV -Path $ReportFileName -Delimiter ";" -NoTypeInformation -Force -Encoding UTF8 

推荐阅读