Вероятно, главное в вашем коде состоит в том, что, хотя вы работаете на удаленных машинах, вы используете local DriverPath для получения версии драйвера, а также не указываете драйвер, на который вы нацелены.
Приведенный ниже код использует небольшую вспомогательную функцию для получения версии драйвера из фактического файла драйвера на сервере, используя путь UN C вместо локального пути. Кроме того, я думаю, что использование здесь функции может сделать код более читабельным.
Чтобы попытаться ускорить процесс, я использую 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