Get Printer Details From Multiple Servers

Recently it was necessary for me to catalogue some printer details accross a number of servers. The requested information was the printer’s name, driver, port IP address and the server name. I was able to write a PowerShell script fairly quickly for this and then run it against multiple computers with the help of Invoke-Command. I’ll break it down here. Full script at the bottom.

Collecting the printer details

The first step, obviously is to collect all of the printers, or the subset that you need.

$printers = Get-Printer

Then we’re going to loop through the printers and get the port and other details that we require.

$printers = Get-Printer

foreach($ptr in $printers){
#Get the printer port
$port = Get-PrinterPort | Where -Property Name -like $ptr.portname

#Create a new hash table to hold the information temporarily
$props = @{
'PrinterName' = $ptr.name;
'Driver' = $ptr.driver;
'IPAddress' = $port.printerhostaddress;
}
}

To cap it all off, we’ll create a new object and populate it from the hash table. Then output it

$printers = Get-Printer

foreach($ptr in $printers){
#Get the printer port
$port = Get-PrinterPort | Where -Property Name -like $ptr.portname

#Create a new hash table to hold the information temporarily
$props = @{
'PrinterName' = $ptr.name;
'Driver' = $ptr.driver;
'IPAddress' = $port.printerhostaddress;
}

$obj = New-Object -TypeName psobject -Property $props
Write-Output $obj
}

Run it against multiple servers

That will work fine the way it is, but we want to run the script against multiple servers. The simplest way to achieve this is to use the Invoke-Command cmdlet.
We can feed it a set of servers inline, from a variable, or using another cmdlet like Get-ADComputer, if you have Active Directory.

$servers = 'Server01','Server02','Server03'

$printers = invoke-command -cn $servers -ScriptBlock {$printers = get-printer | where name -like 'NHC_*'

foreach($ptr in $printers){
$port = Get-printerport | where Name -like $ptr.portname
$props = @{
'PrinterName' = $ptr.name;
'Driver'=$ptr.drivername;
'IPAddress'=$port.printerhostaddress;
}
$obj = new-object -TypeName psobject -Property $props
Write-Output $obj
}

}

Now, I deliberately haven’t stored the server name in the object yet. That’s because when we used Invoke-Command,
the returned objects automatically get a property called PSComputerName, and we can just use that in the output.

$servers = 'Server01','Server02','Server03'

$printers = invoke-command -cn $servers -ScriptBlock {$printers = get-printer | where name -like 'NHC_*'

foreach($ptr in $printers){
$port = Get-printerport | where Name -like $ptr.portname
$props = @{
'PrinterName' = $ptr.name;
'Driver'=$ptr.drivername;
'IPAddress'=$port.printerhostaddress;
}
$obj = new-object -TypeName psobject -Property $props
Write-Output $obj
}

}
$printers | select PrinterName,Driver,IPAddress,@{n='Server';e={$_.PSComputerName}}

That’s all there is to it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s