Monday, August 6, 2018

Compare Print Queues on Two Print Servers

In an active-active print servers scenario, we would like to make sure all print queues are identical. This means:
1. Print queue names are same
2. The same named print queue is on the same IP address

The first one is normally easy. But the second one could be violated frequently due to support redirecting a print queue to an active printer, while a printer is in maintenance, without reverting back to correct IP address when the printer is back to normal.

The following script runs on any network server and generates a print queue discrepancy table. The table will list print server name, print queue name and IP address, for example:

SERVER1PRINTER1192.168.100
SERVER2PRINTER1192.168.101
SERVER1PRINTER4192.168.104
SERVER2PRINTER4192.168.105

Support can use the table to check and fix the discrepancies.

The PowerShell techniques used are:

1. Hash table. We have added print queue as the key and its IP address as the value into the hash table.
2. Hash table comparision. We compare the keys, and then compare the value of the same key on both print servers. Thanks for the reference here.
3. .NET System.Printing is used. This is used to get the Printer Port name from the queue. It is used due to its fast speed to get the queue objects.
4. .NET RegistryKey is used to retrieve print port IP address. This is used against PowerShell PS Drive due to its direct access to the item value.

As for the performance, it takes about 5 seconds to compare two print servers with 200 print queues each.

Thanks.

Script: PrintServerQueuesComparison.ps1

Sunday, July 29, 2018

Create Shared Print Queue On All Print Servers

This script is to create print queue on an array of servers with following checks:

* Check printer name is unique on each print server
* Check printer port
    - IP Address is a valid IP (please note this script is using .NET IPAddress class, which takes 0.0.0.1 as valid IP)
    - IP Address is unique on each print server
* Create printer port on each print server
* Create print queue on each print server

To run this script, please change:
1. Print server names
2. Print driver name

Script: Add-Print_Queue.ps1

Tuesday, July 24, 2018

Create a Shared Printer Queue Remotely in PowerShell

There are a couple of ways to create printer port and printer queue with PowerShell, depending on the OS, performance and personal preferences.

The following scripts are creating a shared printer queue on a remote print server.

1. Print Management Cmdlets

If you are with Windows 2012 or later OS, you can use print management cmdlets.

Add-PrinterPort -ComputerName $ServerName -Name $PrinterIP -PrinterHostAddress $PrinterIP  
Add-Printer -ComputerName $ServerName -Name $PrintQName -Shared -ShareName $PrintQName -Comment $PrinterIP -Location $PrintLocation -DriverName $DriverName -PortName $PrinterIP
2. WMI

On Windows Server 2008 R2 or lower, we can use WMI for printer tasks. The good thing with WMI is its simplicity, which takes strings as parameters.

Part one of this section is to create a printer port on the remote server (reference).
$ip = "10.0.0.10"
$port = [WMIClass]"\\$ComputerName\Root\cimv2:Win32_TcpIpPrinterPort"
$port.psbase.scope.options.EnablePrivileges = $true
$newport = $port.CreateInstance()
$newport.name = "$ip"
$newport.Protocol = 1
$newport.HostAddress = $ip
$newport.PortNumber = "9100"
$newport.SnmpEnabled = $false
$newport.Put()
Part two of this section is to create a printer queue using the above-created printer port (reference).
$wmi = ([WMIClass]"\\$ComputerName\Root\cimv2:Win32_Printer")
$Printer = $wmi.CreateInstance()
$Printer.Caption = $PrinterCaption
$Printer.DriverName = $DriverName (e.g. "PCL6 for Univeral Print")
$Printer.PortName = $PrinterPortName
$Printer.DeviceID = $PrinterCaption
$Printer.Network = $True
$Printer.Shared = $True
$Printer.ShareName = $PrinterCaption
$Printer.Put()

3. .NET System.Printing

.NET has a few overload methods and it is not easy to get examples for all of them. (reference)

Currently, I have not found a direct .NET method to create printer port, please use the WMI method above.

InstallPrintQueue() with 11 parameters
Add-Type -AssemblyName System.Printing

[string[]]$PrintPorts = $IPAddress # one single port
$PrintProcessorName = "winprint"
$PrintQueueSeperatorFile = ""
$PrintQueueAttributes = @()
$PrintQueueAttributes += [System.Printing.PrintQueueAttributes]::Shared

[System.Printing.PrintServer]("\\$ComputerName").InstallPrintQueue( `
$PrinterName, $QueueDriver, $PrintPorts, $PrintProcessorName, `
$PrintQueueAttributes, $PrinterName, `
$Comment, $Location, $PrintQueueSeperatorFile,1,0)

Thanks.

Monday, July 23, 2018

List Print Queues on Print Server with .NET for Performance in PowerShell

Using .NET to query print queues is much faster, here is the difference running the script on two print servers:

Print Queue CountWMI.NET
20210.77 seconds 0.475 seconds 
166796.87 seconds 3.2 seconds

WMI Script:

Measure-Command {
    Get-WMIObject -Class Win32_Printer | Select Name
}

.NET Script:

Measure-Command {
     Add-Type -AssemblyName System.Printing
    $PrintServer = New-Object System.Printing.PrintServer
    $PrintQueues =$PrintServer.GetPrintQueues()

    foreach ($Queue in $PrintQueues) {
        Write-Host ($Queue.Name)
    }
}

Compare Print Queues on Two Print Servers

In an active-active print servers scenario, we would like to make sure all print queues are identical. This means: 1. Print queue names are...