How to Set Up a Print Server on Windows Server 2019

A print server centralizes printer management for an organization, allowing users to connect to shared printers without needing to install drivers individually on each workstation. Windows Server 2019 includes the Print and Document Services role which provides centralized printer deployment via Group Policy, driver management, print queue monitoring, Internet Printing Protocol (IPP) support, and the Print Management console. This guide covers installing the role, adding printers, managing drivers, deploying printers via Group Policy, and configuring print spooler security.

Installing Print and Document Services

# Install the Print Server role with management tools
Install-WindowsFeature `
    -Name Print-Server, Print-Internet `
    -IncludeManagementTools

# Verify installation
Get-WindowsFeature -Name Print*

# Start the Print Spooler service (should start automatically)
Start-Service Spooler
Set-Service Spooler -StartupType Automatic
Get-Service Spooler

Adding Print Drivers

Before adding a printer, install the appropriate driver. For network printers, use vendor-provided PCL6 or PS drivers for best compatibility. The print server must host both 64-bit and 32-bit drivers if Windows clients of both architectures will connect:

# List installed printer drivers
Get-PrinterDriver | Select-Object Name, Manufacturer, PrinterEnvironment | Sort-Object Name

# Add a printer driver from an INF file
Add-PrinterDriver -Name "HP Universal Printing PCL 6" -InfPath "C:DriversHPhpcu270u.inf"

# Add a built-in Windows driver
Add-PrinterDriver -Name "Microsoft Print to PDF"

# Install a driver for x86 (32-bit) clients as well
Add-PrinterDriver -Name "HP Universal Printing PCL 6" `
    -InfPath "C:DriversHP-x86hpcu270u.inf" `
    -PrinterEnvironment "Windows x86"

# Remove a driver
Remove-PrinterDriver -Name "Old Driver Name"

Adding Network Printers

Add TCP/IP ports for network printers and then associate a printer with each port:

# Create a Standard TCP/IP port for a network printer
Add-PrinterPort -Name "IP_192.168.1.100" -PrinterHostAddress "192.168.1.100"

# Add a printer using the port and driver
Add-Printer `
    -Name "HP LaserJet 4200 - Floor 3" `
    -DriverName "HP Universal Printing PCL 6" `
    -PortName "IP_192.168.1.100" `
    -Location "3rd Floor, Room 302" `
    -Comment "Main office printer" `
    -Shared $true `
    -ShareName "HP-Floor3"

# Add a printer with LPR port (for Unix/Linux print queues)
Add-PrinterPort -Name "LPR_192.168.1.101" -PrinterHostAddress "192.168.1.101" -PortNumber 515 -LprByteCounting $true

# Add an SMB printer from another server
Add-Printer -ConnectionName "\printserver02HP-Accounting"

# List all printers on the server
Get-Printer | Select-Object Name, DriverName, PortName, Shared, ShareName, Location | Format-Table -AutoSize

Configuring Printer Sharing and Permissions

Share the printer and configure who can print, manage documents, and manage the printer. By default, Everyone can print. Restrict this based on your security requirements:

# Share an existing printer
Set-Printer -Name "HP LaserJet 4200 - Floor 3" -Shared $true -ShareName "HP-Floor3"

# Configure printer permissions via the Win32_Printer WMI class
# View current permissions
$printer = Get-WmiObject -Class Win32_Printer -Filter "Name='HP LaserJet 4200 - Floor 3'"
$sd = $printer.GetSecurityDescriptor()

# Use the Print Management console (printmanagement.msc) for GUI-based permission management
# Or configure via the Security tab in Printer Properties

# Configure using the PrinterPermission module (third-party)
# Or using Security Descriptor Definition Language (SDDL) via SetSecurityDescriptor

# Restrict printing to a specific security group via SDDL
# Grant Print permission only to CORPPrint-Users group
# (This requires building SDDL string - typically done via GUI then exported)

Deploying Printers via Group Policy

The most efficient way to deploy printers to users is through Group Policy. Printers can be deployed per-computer (all users on those computers get the printer) or per-user (specific users get the printer regardless of which computer they log on to):

# Deploy a shared printer via Group Policy using Print Management
# Method 1: Through printmanagement.msc GUI (right-click printer > Deploy with Group Policy)

# Method 2: Using PowerShell to configure GPO printer deployment
Import-Module GroupPolicy

# Create a GPO for printer deployment
New-GPO -Name "Floor3-Printer-Deployment"

# The printer deployment settings are stored in the GPO as printer connection settings
# User Configuration > Preferences > Control Panel Settings > Printers
# or
# Computer Configuration > Windows Settings > Deployed Printers

# Use Group Policy Preferences to deploy per-user printer connections
# This is configured via GPME or by editing the GPO XML directly

# Link GPO to the appropriate OU
New-GPLink `
    -Name "Floor3-Printer-Deployment" `
    -Target "OU=Floor3-Users,DC=corp,DC=example,DC=com"

Managing Print Queues

Monitor and manage print jobs and queues from the command line or Print Management console:

# List all print jobs across all printers
Get-PrintJob -PrinterName "HP LaserJet 4200 - Floor 3"

# Remove a specific print job
Remove-PrintJob -PrinterName "HP LaserJet 4200 - Floor 3" -ID 15

# Clear all print jobs from a queue (useful when queue is stuck)
Get-PrintJob -PrinterName "HP LaserJet 4200 - Floor 3" | Remove-PrintJob

# Pause and resume a printer
Suspend-PrintQueue -PrinterName "HP LaserJet 4200 - Floor 3"
Resume-PrintQueue -PrinterName "HP LaserJet 4200 - Floor 3"

# Restart a stuck printer
Restart-Service Spooler
# Note: Restarting the spooler affects ALL printers on the server temporarily

# Clear stuck jobs when the spooler is stopped
Stop-Service Spooler
Remove-Item "C:WindowsSystem32spoolPRINTERS*.SHD" -Force
Remove-Item "C:WindowsSystem32spoolPRINTERS*.SPL" -Force
Start-Service Spooler

Configuring Printer Availability and Priority

Set printers to be available only during certain hours or assign priority to ensure urgent jobs print ahead of lower-priority jobs. This is useful for accounting departments that have time-sensitive reports at end of month:

# Set printer availability window (available 7 AM to 10 PM)
Set-Printer `
    -Name "HP LaserJet 4200 - Floor 3" `
    -StartTime ([TimeSpan]::FromHours(7).TotalMinutes) `
    -UntilTime ([TimeSpan]::FromHours(22).TotalMinutes)

# Create a second logical printer for urgent jobs with higher priority
Add-Printer `
    -Name "HP LaserJet 4200 - URGENT" `
    -DriverName "HP Universal Printing PCL 6" `
    -PortName "IP_192.168.1.100" `
    -Shared $true `
    -ShareName "HP-Floor3-URGENT"

# Set higher priority (99 = highest, 1 = lowest default)
Set-Printer -Name "HP LaserJet 4200 - URGENT" -Priority 99

Securing the Print Spooler

The Print Spooler (Spooler service) has historically been a target for privilege escalation exploits (e.g., PrintNightmare). Apply security hardening:

# Disable print spooler on servers that are NOT print servers
Stop-Service Spooler
Set-Service Spooler -StartupType Disabled

# On the print server, restrict spooler remote access via registry
# Prevent remote driver installation (mitigates PrintNightmare)
Set-ItemProperty `
    -Path "HKLM:SOFTWAREPoliciesMicrosoftWindows NTPrintersPointAndPrint" `
    -Name "NoWarningNoElevationOnInstall" `
    -Value 0 -Type DWord

Set-ItemProperty `
    -Path "HKLM:SOFTWAREPoliciesMicrosoftWindows NTPrintersPointAndPrint" `
    -Name "UpdatePromptSettings" `
    -Value 0 -Type DWord

# Restrict spooler to listen on localhost only (if remote print management not needed via RPC)
# Apply Group Policy: Computer Configuration > Administrative Templates > Printers
# "Allow Print Spooler to accept client connections" = Disabled
# This disables remote printing to this server, so only enable on dedicated print servers

# Restrict who can manage the spooler service
$sddl = (sc.exe sdshow Spooler)[1]
# Review SDDL and apply least-privilege service permissions

Monitoring Print Server Health

# View printer status
Get-Printer | Select-Object Name, PrinterStatus, JobCount | Format-Table

# Monitor print server via event logs
Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" -MaxEvents 50

# Enable operational print log (may be disabled by default)
wevtutil sl Microsoft-Windows-PrintService/Operational /e:true

# Generate a print usage report (count jobs per printer per day)
Get-WinEvent -LogName "Microsoft-Windows-PrintService/Operational" | `
    Where-Object {$_.Id -eq 307} | `
    Group-Object {$_.Properties[4].Value} | `
    Select-Object Name, Count | Sort-Object Count -Descending

A centralized print server simplifies printer management in medium to large organizations. Combine print server deployment with Universal Print Driver strategies to minimize the number of drivers you must manage, and use Branch Office Direct Printing for remote sites to reduce WAN traffic by having branch clients print directly to local printers without routing through the central print server.