Print Server Migration Strategies for Windows Server 2003

Tyler Maginnis | January 15, 2024

Print ServerMigrationWindows Server 2022PrintNightmareLegacy SystemsWindows Server 2003Security

Need Professional Windows Server 2003?

Get expert assistance with your windows server 2003 implementation and management. Tyler on Tech Louisville provides priority support for Louisville businesses.

Same-day service available for Louisville area

Print Server Migration Strategies for Windows Server 2003

Critical Notice

⚠️ Windows Server 2003 print servers are vulnerable to PrintNightmare and other exploits. Immediate migration to Windows Server 2022 is essential for security.

Overview

Print server migration from Windows Server 2003 requires careful planning to ensure continuous printing services. This guide provides comprehensive strategies for migrating print services while minimizing disruption to users.

Current State Assessment

1. Print Server Inventory

@echo off
:: PrintServerInventory.bat - Document existing print infrastructure
echo Print Server Inventory Report > PrintInventory.txt
echo Generated: %date% %time% >> PrintInventory.txt
echo ================================ >> PrintInventory.txt

:: List all printers
echo. >> PrintInventory.txt
echo Installed Printers: >> PrintInventory.txt
cscript %WINDIR%\System32\Printing_Admin_Scripts\en-US\prnmngr.vbs -l >> PrintInventory.txt

:: List printer drivers
echo. >> PrintInventory.txt
echo Installed Drivers: >> PrintInventory.txt
cscript %WINDIR%\System32\Printing_Admin_Scripts\en-US\prndrvr.vbs -l >> PrintInventory.txt

:: List printer ports
echo. >> PrintInventory.txt
echo Configured Ports: >> PrintInventory.txt
cscript %WINDIR%\System32\Printing_Admin_Scripts\en-US\prnport.vbs -l >> PrintInventory.txt

:: Get spooler settings
echo. >> PrintInventory.txt
echo Spooler Configuration: >> PrintInventory.txt
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Print" /s >> PrintInventory.txt

echo Inventory saved to PrintInventory.txt

2. Print Queue Analysis

' AnalyzePrintQueues.vbs - Analyze print queue usage
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("PrintQueueAnalysis.csv", True)

' Write header
objFile.WriteLine "Printer Name,Jobs Printed,Total Pages,Average Pages/Job,Status"

' Get all printers
Set colPrinters = objWMI.ExecQuery("SELECT * FROM Win32_Printer")

For Each objPrinter In colPrinters
    ' Get job statistics
    jobCount = objPrinter.JobCountSinceLastReset
    If jobCount > 0 Then
        avgPages = objPrinter.TotalPagesPrinted / jobCount
    Else
        avgPages = 0
    End If

    ' Write data
    objFile.WriteLine objPrinter.Name & "," & jobCount & "," & _
                     objPrinter.TotalPagesPrinted & "," & avgPages & "," & _
                     objPrinter.PrinterStatus
Next

objFile.Close
WScript.Echo "Analysis saved to PrintQueueAnalysis.csv"

3. Driver Compatibility Check

# CheckDriverCompatibility.ps1
$drivers = Get-WmiObject Win32_PrinterDriver

$report = @()
foreach($driver in $drivers) {
    $driverInfo = @{
        Name = $driver.Name
        Version = $driver.DriverVersion
        Architecture = $driver.SupportedPlatform
        Date = $driver.DriverDate
        Provider = $driver.ProviderName
        Compatible2022 = "Unknown"
    }

    # Check known compatibility issues
    if($driver.DriverDate -lt (Get-Date "2010-01-01")) {
        $driverInfo.Compatible2022 = "Likely Incompatible - Too Old"
    }
    elseif($driver.SupportedPlatform -notmatch "x64") {
        $driverInfo.Compatible2022 = "Incompatible - 32-bit Only"
    }

    $report += New-Object PSObject -Property $driverInfo
}

$report | Export-Csv -Path "DriverCompatibility.csv" -NoTypeInformation
Write-Host "Driver compatibility report saved to DriverCompatibility.csv"

Migration Strategies

Strategy 1: Print Management Migration Tool

Prerequisites

@echo off
:: PrepareMigration.bat - Prepare for print server migration

:: Create migration directory
mkdir C:\PrintMigration

:: Export print configuration
echo Exporting print server configuration...
cd /d %WINDIR%\System32\spool\tools

:: Export printers
Printbrm -s \\%COMPUTERNAME% -b -f C:\PrintMigration\PrintConfig.printerExport

:: Backup registry
reg export "HKLM\SYSTEM\CurrentControlSet\Control\Print" C:\PrintMigration\PrintRegistry.reg

echo Migration files prepared in C:\PrintMigration

Migration Process

# MigratePrintServer.ps1 - Automated print server migration
param(
    [string]$SourceServer = "OLDPRINT",
    [string]$TargetServer = "NEWPRINT",
    [string]$BackupPath = "\\FileServer\PrintMigration"
)

# Step 1: Export from source
Write-Host "Exporting print configuration from $SourceServer..."
$exportFile = "$BackupPath\PrintExport_$(Get-Date -Format 'yyyyMMdd').printerExport"

# Use Print Management backup
$exportCmd = "printbrm -s \\$SourceServer -b -f $exportFile"
Invoke-Expression $exportCmd

# Step 2: Import to target
Write-Host "Importing to $TargetServer..."
$importCmd = "printbrm -s \\$TargetServer -r -f $exportFile"
Invoke-Expression $importCmd

Write-Host "Migration complete. Verify printer functionality."

Strategy 2: Manual Migration with Scripts

Export Individual Printers

' ExportPrinters.vbs - Export printer configurations
Dim objFSO, objFile, objWMI, colPrinters
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("PrinterExport.xml", True)
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")

objFile.WriteLine "<?xml version=""1.0""?>"
objFile.WriteLine "<PrinterConfigurations>"

Set colPrinters = objWMI.ExecQuery("SELECT * FROM Win32_Printer")
For Each objPrinter In colPrinters
    objFile.WriteLine "  <Printer>"
    objFile.WriteLine "    <Name>" & objPrinter.Name & "</Name>"
    objFile.WriteLine "    <DriverName>" & objPrinter.DriverName & "</DriverName>"
    objFile.WriteLine "    <PortName>" & objPrinter.PortName & "</PortName>"
    objFile.WriteLine "    <ShareName>" & objPrinter.ShareName & "</ShareName>"
    objFile.WriteLine "    <Location>" & objPrinter.Location & "</Location>"
    objFile.WriteLine "    <Comment>" & objPrinter.Comment & "</Comment>"
    objFile.WriteLine "    <Default>" & objPrinter.Default & "</Default>"
    objFile.WriteLine "    <Published>" & objPrinter.Published & "</Published>"
    objFile.WriteLine "  </Printer>"
Next

objFile.WriteLine "</PrinterConfigurations>"
objFile.Close

WScript.Echo "Printer configurations exported to PrinterExport.xml"

Create Printers on New Server

# CreatePrinters.ps1 - Recreate printers on Windows Server 2022
[xml]$printers = Get-Content "PrinterExport.xml"

foreach($printer in $printers.PrinterConfigurations.Printer) {
    Write-Host "Creating printer: $($printer.Name)"

    # Create printer port if needed
    $port = Get-PrinterPort -Name $printer.PortName -ErrorAction SilentlyContinue
    if(!$port) {
        if($printer.PortName -match "^\d+\.\d+\.\d+\.\d+") {
            # TCP/IP port
            Add-PrinterPort -Name $printer.PortName -PrinterHostAddress $printer.PortName
        }
    }

    # Add printer
    Add-Printer -Name $printer.Name `
                -DriverName $printer.DriverName `
                -PortName $printer.PortName `
                -Location $printer.Location `
                -Comment $printer.Comment

    # Share printer if needed
    if($printer.ShareName) {
        Set-Printer -Name $printer.Name -Shared $true -ShareName $printer.ShareName
    }

    # Publish in AD if needed
    if($printer.Published -eq "True") {
        Set-Printer -Name $printer.Name -Published $true
    }
}

Strategy 3: Side-by-Side Migration

Parallel Operation Setup

@echo off
:: ParallelSetup.bat - Configure parallel print servers

echo Setting up parallel print environment...

:: Configure old server to coexist
echo Modifying old server settings...
netsh firewall set service type=fileandprint mode=enable
net share print$ /grant:everyone,read

:: Create migration share
net share PrintMigration=C:\PrintMigration /grant:administrators,full

:: Document current connections
echo Current printer connections: > UserPrinters.txt
wmic printer where "Network=TRUE" get Name, SystemName >> UserPrinters.txt

echo Parallel environment ready.

Client Migration Script

' MigrateClientPrinters.vbs - Migrate user printer connections
Dim objNetwork, objWMI, colPrinters, dictMappings
Set objNetwork = CreateObject("WScript.Network")
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set dictMappings = CreateObject("Scripting.Dictionary")

' Define printer mappings (old to new)
dictMappings.Add "\\OLDPRINT\HP_Laser", "\\NEWPRINT\HP_Laser"
dictMappings.Add "\\OLDPRINT\Color_Printer", "\\NEWPRINT\Color_Printer"

' Get current network printers
Set colPrinters = objWMI.ExecQuery("SELECT * FROM Win32_Printer WHERE Network=True")

' Migrate each printer
For Each objPrinter In colPrinters
    oldPrinter = objPrinter.Name
    If dictMappings.Exists(oldPrinter) Then
        newPrinter = dictMappings.Item(oldPrinter)

        ' Remove old connection
        objNetwork.RemovePrinterConnection oldPrinter, True, True

        ' Add new connection
        objNetwork.AddWindowsPrinterConnection newPrinter

        ' Set as default if it was
        If objPrinter.Default Then
            objNetwork.SetDefaultPrinter newPrinter
        End If

        WScript.Echo "Migrated: " & oldPrinter & " -> " & newPrinter
    End If
Next

WScript.Echo "Printer migration complete"

Driver Management

1. Driver Extraction

@echo off
:: ExtractDrivers.bat - Extract printer drivers from Windows Server 2003

set DriverPath=C:\PrintDrivers
mkdir %DriverPath%

echo Extracting printer drivers...

:: Copy driver files
xcopy /E /H /Y "%WINDIR%\System32\spool\drivers\*.*" "%DriverPath%\Drivers\"

:: Export driver information
reg export "HKLM\SYSTEM\CurrentControlSet\Control\Print\Environments" "%DriverPath%\DriverRegistry.reg"

:: Create driver manifest
echo Driver Manifest > %DriverPath%\manifest.txt
dir /s /b "%DriverPath%\Drivers\*.inf" >> %DriverPath%\manifest.txt

echo Drivers extracted to %DriverPath%

2. Driver Compatibility Testing

# TestDrivers.ps1 - Test driver compatibility on Windows Server 2022
param(
    [string]$DriverPath = "C:\PrintDrivers"
)

$results = @()
$infFiles = Get-ChildItem -Path $DriverPath -Filter "*.inf" -Recurse

foreach($inf in $infFiles) {
    Write-Host "Testing driver: $($inf.Name)"

    $testResult = @{
        Driver = $inf.Name
        Path = $inf.FullName
        Compatible = $false
        Error = ""
    }

    try {
        # Attempt to stage driver
        pnputil /add-driver $inf.FullName
        $testResult.Compatible = $true
    }
    catch {
        $testResult.Error = $_.Exception.Message
    }

    $results += New-Object PSObject -Property $testResult
}

$results | Export-Csv -Path "DriverTestResults.csv" -NoTypeInformation

3. Universal Print Driver Deployment

@echo off
:: DeployUniversalDriver.bat - Deploy universal print drivers

echo Deploying Universal Print Drivers...

:: Download and install HP Universal Print Driver
powershell -Command "Invoke-WebRequest -Uri 'https://hp.com/upd' -OutFile 'HP_UPD.exe'"
HP_UPD.exe /quiet /norestart

:: Download and install Xerox Global Print Driver
powershell -Command "Invoke-WebRequest -Uri 'https://xerox.com/gpd' -OutFile 'Xerox_GPD.exe'"
Xerox_GPD.exe /quiet /norestart

:: Configure as defaults for unmatched printers
cscript %WINDIR%\System32\Printing_Admin_Scripts\en-US\prndrvr.vbs -a -m "HP Universal Printing PCL 6" -v 3 -e "Windows x64"

echo Universal drivers deployed.

Group Policy Migration

1. Export Print Policies

@echo off
:: ExportPrintGPO.bat - Export print-related Group Policy

:: Create export directory
mkdir C:\GPOExport

:: Export printer GPOs
echo Exporting printer deployment GPOs...
cscript %WINDIR%\System32\gpresult.vbs /s computer /scope computer > C:\GPOExport\ComputerGPO.txt
cscript %WINDIR%\System32\gpresult.vbs /s user /scope user > C:\GPOExport\UserGPO.txt

:: Export specific printer preferences
reg export "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers" C:\GPOExport\PrinterPolicies.reg

echo GPO export complete.

2. Create New Print Deployment GPO

# CreatePrintGPO.ps1 - Create printer deployment GPO for Windows Server 2022
Import-Module GroupPolicy

$gpoName = "Printer Deployment - Migrated"
$domain = Get-ADDomain

# Create new GPO
$gpo = New-GPO -Name $gpoName -Domain $domain.DNSRoot

# Configure printer deployments
$printers = @(
    @{Name="HP_Laser"; Path="\\NEWPRINT\HP_Laser"; Default=$false},
    @{Name="Color_Printer"; Path="\\NEWPRINT\Color_Printer"; Default=$false}
)

foreach($printer in $printers) {
    # Add printer connection
    Set-GPRegistryValue -Name $gpoName -Key "HKCU\Printers\Connections\$($printer.Path)" `
                        -ValueName "Server" -Type String -Value $printer.Path.Split('\')[2]
    Set-GPRegistryValue -Name $gpoName -Key "HKCU\Printers\Connections\$($printer.Path)" `
                        -ValueName "Provider" -Type String -Value "win32spl.dll"
}

Write-Host "Printer GPO created: $gpoName"

Testing and Validation

1. Print Test Automation

# TestPrintQueues.ps1 - Automated print queue testing
$testDocument = "C:\PrintTest.txt"
"Print Queue Test Document - $(Get-Date)" | Out-File $testDocument

$printers = Get-Printer
$results = @()

foreach($printer in $printers) {
    Write-Host "Testing printer: $($printer.Name)"

    $testResult = @{
        PrinterName = $printer.Name
        TestTime = Get-Date
        Success = $false
        JobId = $null
        Error = $null
    }

    try {
        # Send test print
        $job = Get-Content $testDocument | Out-Printer -Name $printer.Name -PassThru
        $testResult.JobId = $job.JobId
        $testResult.Success = $true

        # Wait and check job status
        Start-Sleep -Seconds 5
        $jobStatus = Get-PrintJob -PrinterName $printer.Name -JobId $job.JobId
        $testResult.JobStatus = $jobStatus.JobStatus
    }
    catch {
        $testResult.Error = $_.Exception.Message
    }

    $results += New-Object PSObject -Property $testResult
}

$results | Export-Csv -Path "PrintTestResults.csv" -NoTypeInformation
Remove-Item $testDocument

2. User Acceptance Testing

' UserPrintTest.vbs - Interactive print test for users
Dim objShell, objFSO, objNetwork
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = CreateObject("WScript.Network")

' Get user's printers
WScript.Echo "Available Printers:"
WScript.Echo "=================="

Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set colPrinters = objWMI.ExecQuery("SELECT * FROM Win32_Printer")

i = 1
Dim arrPrinters()
For Each objPrinter In colPrinters
    ReDim Preserve arrPrinters(i)
    arrPrinters(i-1) = objPrinter.Name
    WScript.Echo i & ". " & objPrinter.Name
    i = i + 1
Next

' Select printer
printerNum = InputBox("Enter printer number to test:", "Printer Test")
selectedPrinter = arrPrinters(CInt(printerNum) - 1)

' Create test page
Set objFile = objFSO.CreateTextFile("TestPage.txt", True)
objFile.WriteLine "PRINTER TEST PAGE"
objFile.WriteLine "================="
objFile.WriteLine "Date: " & Now
objFile.WriteLine "User: " & objNetwork.UserName
objFile.WriteLine "Computer: " & objNetwork.ComputerName
objFile.WriteLine "Printer: " & selectedPrinter
objFile.Close

' Print test page
objShell.Run "notepad /p TestPage.txt", 0, True

' Cleanup
objFSO.DeleteFile "TestPage.txt"

MsgBox "Test page sent to " & selectedPrinter, vbInformation, "Print Test"

Rollback Procedures

1. Quick Rollback Script

@echo off
:: RollbackPrint.bat - Emergency rollback to old print server

echo EMERGENCY PRINT SERVER ROLLBACK
echo ==============================
echo.

set /p confirm="This will revert to the old print server. Continue? (Y/N): "
if /i not "%confirm%"=="Y" exit

:: Stop new print spooler
sc \\NEWPRINT stop spooler

:: Update DNS if using print server alias
echo Updating DNS...
dnscmd /recorddelete domain.local printserver A /f
dnscmd /recordadd domain.local printserver A 192.168.1.10

:: Restart old server spooler
sc \\OLDPRINT start spooler

:: Notify users
msg * "Print services have been reverted to the old server. Please restart your applications."

echo Rollback complete.

2. Backup Restoration

# RestorePrintBackup.ps1 - Restore print configuration from backup
param(
    [string]$BackupFile = "\\FileServer\Backups\PrintConfig.printerExport",
    [string]$TargetServer = "localhost"
)

Write-Host "Restoring print configuration from backup..."

# Stop spooler
Stop-Service -Name Spooler -Force

# Clear existing configuration
Remove-Item -Path "$env:WINDIR\System32\spool\PRINTERS\*" -Force -ErrorAction SilentlyContinue

# Restore from backup
$restoreCmd = "printbrm -s \\$TargetServer -r -f $BackupFile"
Invoke-Expression $restoreCmd

# Restart spooler
Start-Service -Name Spooler

Write-Host "Print configuration restored."

Post-Migration Tasks

1. Decommission Old Server

@echo off
:: DecommissionOldPrint.bat - Safely decommission old print server

echo Decommissioning Windows Server 2003 Print Server
echo ===============================================

:: Export final configuration
Printbrm -s \\%COMPUTERNAME% -b -f "FinalBackup_%date:~-4,4%%date:~-10,2%%date:~-7,2%.printerExport"

:: Remove printer shares
echo Removing printer shares...
for /f "tokens=1" %%a in ('net share ^| findstr "Printer"') do (
    net share %%a /delete /y
)

:: Stop services
net stop spooler
sc config spooler start= disabled

:: Archive spool folder
echo Archiving spool folder...
xcopy /E /H /Y "%WINDIR%\System32\spool" "C:\PrintArchive\spool\"

:: Clear spool
del /f /s /q "%WINDIR%\System32\spool\PRINTERS\*.*"

echo.
echo Decommission complete. Server ready for shutdown.

2. Performance Monitoring

# MonitorNewPrintServer.ps1 - Monitor new print server performance
$counters = @(
    "\Print Queue(_Total)\Jobs",
    "\Print Queue(_Total)\Jobs Spooling",
    "\Print Queue(_Total)\Total Jobs Printed",
    "\Print Queue(_Total)\Total Pages Printed",
    "\Processor(_Total)\% Processor Time",
    "\Memory\Available MBytes"
)

while($true) {
    Clear-Host
    Write-Host "Print Server Performance Monitor" -ForegroundColor Green
    Write-Host "================================" -ForegroundColor Green
    Write-Host "Time: $(Get-Date)" -ForegroundColor Yellow
    Write-Host ""

    foreach($counter in $counters) {
        try {
            $value = (Get-Counter $counter).CounterSamples[0].CookedValue
            Write-Host "$counter : $([math]::Round($value, 2))"
        }
        catch {
            Write-Host "$counter : Error reading" -ForegroundColor Red
        }
    }

    Start-Sleep -Seconds 5
}

Best Practices Summary

Migration Checklist

  • [ ] Complete printer inventory
  • [ ] Test driver compatibility
  • [ ] Create comprehensive backups
  • [ ] Establish rollback procedures
  • [ ] Schedule migration window
  • [ ] Notify users in advance
  • [ ] Prepare support documentation
  • [ ] Test all printers post-migration
  • [ ] Monitor for 48 hours
  • [ ] Decommission old server

Common Issues and Solutions

Issue Solution
Driver incompatibility Use universal print drivers
Port configuration errors Verify IP addresses and port numbers
Permission issues Check share and NTFS permissions
Spool folder corruption Clear spool and restart service
Client connection failures Update GPO and login scripts

Conclusion

Print server migration from Windows Server 2003 requires careful planning and execution. Following these strategies ensures minimal disruption while improving security and reliability. Always maintain backups and test thoroughly before final cutover.

Support Resources

  • Tyler on Tech Louisville: (202) 948-8888
  • 24/7 Print Support: Available
  • Email: printsupport@tylerontechlouisville.com

Last Updated: January 2024
Author: Tyler Maginnis, Tyler on Tech Louisville