enumerate domain printers and their drivers

So… I’m trying to iterate through all domain computers, find out what printers they have installed, and determine the printer name, IP port, driver, and what’s still missing, the driver version, specifically PCL5 or 6.
So far, I have this one-liner that does most of this:

Get-ADComputer -Filter * | select -ExpandProperty Name | foreach {Get-WmiObject -Class Win32_Printer -ComputerName $_ |select Systemname, name, portName, drivername|Where-Object {$.name -ne “WebEx Document Loader” -and $.name -ne “Microsoft XPS Document Writer” -and $_.name -ne “Calyx Document Converter”}} |epcsv c:\dh\printers1.csv

I believe that to get the driver version I need driver.path from win32_printerdriver. How can I further nest this query to iterate the computers, for each computer iterate the printers, and then for each printer, enumerate the driver.path property?

Thanks!

If I’m not mistaken, I believe in most cases DriverName will specify whether it is PCL5 or 6. I also believe the version property in the win32_printerdriver class will almost always report 3 (meaning Win2k).

For DriverPath, it’s ugly but you could squeeze a hashtable into the select statement

@{n="DriverPath"; e = {$driverName = $_.drivername; (Get-WMIObject -Class Win32_PrinterDriver | Where {$_.Name -like "$driverName*"}).DriverPath}}

It may be easier to break out into a script:

Get-ADComputer -Filter * | select -ExpandProperty Name | ForEach-Object {
    $printers = Get-WmiObject -Class Win32_Printer -ComputerName $_
    $printerDrivers = Get-WmiObject -Class Win32_PrinterDriver -ComputerName $_
    $printers | ForEach-Object{
        $driverName = $_.DriverName
        $_ | Select SystemName, Name, PortName, DriverName, @{n="DriverPath";e={($printerDrivers | Where-Object {$_.Name -like "$driverName*"}).DriverPath}}
    }
}

You can, in theory, use the LanguagesSupported property of the Win32_Printer class, however, I have found that a lot of manufacturers do not populate the value.

Get-ADComputer -Filter * | select -ExpandProperty Name | foreach {Get-WmiObject -Class Win32_Printer -ComputerName $_ |select Systemname, name, portName, drivername, LanguagesSupported|Where-Object {$_.name -ne "WebEx Document Loader" -and $_.name -ne "Microsoft XPS Document Writer" -and $_.name -ne "Calyx Document Converter"}} |epcsv c:\dh\printers1.csv

https://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx

Skipping trying to shoehorn everything into a one-liner, here is my approach …

$excludeList = "WebEx Document Loader","Microsoft XPS Document Writer",
    "Calyx Document Converter","Fax","Send To OneNote 2010",
    "Send To OneNote 2013","CutePDF Writer","M2M PDFWriter","Adobe PDF"
$computers = Get-ADComputer -Filter {Enabled -eq "True"}
$results = foreach ($computer in $computers)
{
    $name = $computer.Name
    Write-Verbose "Checking $name"
    if (Test-Connection -ComputerName $name -Count 1 -Quiet)
    {
        $printers = Get-WmiObject -Class Win32_Printer -ComputerName $computer.Name
        foreach ($printer in $printers)
        {
            if ($printer.Name -notin $excludeList)
            {
                [PSCustomObject]@{
                    Systemname = $printer.SystemName
                    Name = $printer.Name
                    PortName = $printer.PortName
                    DriverName = $printer.DriverName
                }
            }
        }
    }
}

# Sample outputs - pick one or more, your choice
$results
$results | Format-Table -AutoSize
$results | sort -Property SystemName | Out-GridView
$results | Export-Csv -Path .\foo.csv -NoTypeInformation -Encoding ASCII
$results | Out-File -FilePath .\foo.txt -Encoding ASCII
$results | Export-Clixml -Path .\foo.xml -Encoding ASCII