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...