Printers
2 TopicsHelp with Powershell scripts to backup and restore printers
Hello all. I'm rather new to PowerShell. I hope I'm not causing any grief here. I whipped together a proof of concept because I need to protect certain computers' printing abilities as they are crucial to our business. I know I can use Print Migration to export and import the set of printers. I don't know how to start Printer Migration giving it a destination of the UNC to the server, the current computer's name. It does not seem to restore all the printers either. I really would appreciate the ability to clone an existing printer to a new name and new IP address. I wanted to see how far Perplexity.AI could take this. It made a start but then started forgetting requirements, re-writing whole scripts, and losing functionality already obtained. My premise is that copying is backup, change, and restore. So I made Backup-SinglePrinter, Restore-SinglePrinter, and Copy-ExistingPrinter. A settings file is included. I expect that once backup-singleprinter and restore-singleprinter work, I could make a BackupPrinters and RestorePrinters to handle all existing printers. One final thing is I would like to have the scripts locate each other by using the single settings file or by knowing the starting location of the first script. Mike Copy-ExistingPrinter.ps1 <# .SYNOPSIS Copies an existing printer to a new printer with a different name and a new IP address. .DESCRIPTION This script copies an existing printer by backing it up, modifying the backup, and then restoring it with a new name and a new IP address. .PARAMETER ExistingPrinterName The name of the existing printer to copy from. .PARAMETER NewPrinterName The name of the new printer to create. .EXAMPLE .\Copy-ExistingPrinter.ps1 -ExistingPrinterName "Printer1" -NewPrinterName "Printer2" #> param ( [Parameter(Mandatory=$true)] [string]$ExistingPrinterName, [Parameter(Mandatory=$true)] [string]$NewPrinterName ) # Import settings $settingsPath = Join-Path $PSScriptRoot "settings.ps1" if (Test-Path $settingsPath) { . $settingsPath } else { Write-Error "Settings file not found at $settingsPath" exit 1 } # Verify that $BaseFolder is set in settings.ps1 if (-not $BaseFolder) { Write-Error "BaseFolder is not set in settings.ps1" exit 1 } # Manually import required modules $modulesToImport = @( "Backup-SinglePrinter.psm1", "Restore-SinglePrinter.psm1", "Find-AvailableIPPort.psm1", "Get-PrinterExtendedConfig.psm1" ) foreach ($module in $modulesToImport) { $modulePath = Join-Path $BaseFolder $module if (Test-Path $modulePath) { Import-Module $modulePath -Force Write-Host "Imported module: $module" -ForegroundColor Green } else { Write-Error "Module $module not found at $modulePath" exit 1 } } # Verify that the functions are available $requiredFunctions = @("Backup-SinglePrinter", "Restore-SinglePrinter", "Find-AvailableIPPort", "Get-PrinterExtendedConfig") foreach ($func in $requiredFunctions) { if (-not (Get-Command -Name $func -ErrorAction SilentlyContinue)) { Write-Error "Required function $func is not available." exit 1 } else { Write-Host "Function $func is available." -ForegroundColor Green } } try { # Create backup folder structure $backupsFolder = Join-Path $BaseFolder "Backups" $computerName = $env:COMPUTERNAME $computerBackupFolder = Join-Path $backupsFolder $computerName $driversFolder = Join-Path $computerBackupFolder "Drivers" if (-not (Test-Path $computerBackupFolder)) { New-Item -ItemType Directory -Path $computerBackupFolder -Force | Out-Null } if (-not (Test-Path $driversFolder)) { New-Item -ItemType Directory -Path $driversFolder -Force | Out-Null } # Backup the existing printer Write-Host "Backing up existing printer: $ExistingPrinterName" -ForegroundColor Cyan $backupFileName = "$ExistingPrinterName.xml" $backupFile = Join-Path $computerBackupFolder $backupFileName $backupResult = Backup-SinglePrinter -PrinterName $ExistingPrinterName -BackupFile $backupFile if (-not $backupResult) { throw "Failed to backup the existing printer." } # Get the IP address of the existing printer $existingPrinter = Get-Printer -Name $ExistingPrinterName $existingPort = Get-PrinterPort -Name $existingPrinter.PortName $BaseIP = $existingPort.PrinterHostAddress if ([string]::IsNullOrEmpty($BaseIP)) { Write-Error "Unable to retrieve IP address for existing printer $ExistingPrinterName" exit 1 } Write-Host "Existing printer IP address: $BaseIP" -ForegroundColor Cyan # Find an available IP port for the new printer Write-Host "Finding an available IP port for the new printer" -ForegroundColor Cyan $NewIPAddress = Find-AvailableIPPort -BaseIP $BaseIP if ($NewIPAddress) { Write-Host "Available IP port found: $NewIPAddress" -ForegroundColor Green } else { throw "No available IP address found." } # Create a new port with the new IP address $NewPortName = $NewIPAddress Add-PrinterPort -Name $NewPortName -PrinterHostAddress $NewIPAddress # Restore the modified backup as a new printer Write-Host "Restoring modified backup as new printer: $NewPrinterName" -ForegroundColor Cyan $restoreResult = Restore-SinglePrinter -BackupFile $backupFile -NewPrinterName $NewPrinterName -NewPortName $NewPortName if ($restoreResult) { Write-Host "Printer '$ExistingPrinterName' successfully copied to '$NewPrinterName' with IP $NewIPAddress." -ForegroundColor Green # Create a backup summary $summaryFile = Join-Path $computerBackupFolder "BackupSummary.txt" $summaryContent = @" Backup performed on: $(Get-Date) Original Printer: $ExistingPrinterName New Printer: $NewPrinterName New IP Address: $NewIPAddress "@ Add-Content -Path $summaryFile -Value $summaryContent } else { throw "Failed to restore the new printer." } } catch { Write-Error "An error occurred during the printer copying process: $_" # Clean up the new printer if it was created if (Get-Printer -Name $NewPrinterName -ErrorAction SilentlyContinue) { Remove-Printer -Name $NewPrinterName -ErrorAction SilentlyContinue } # Clean up the new port if it was created if ($NewPortName -and (Get-PrinterPort -Name $NewPortName -ErrorAction SilentlyContinue)) { Remove-PrinterPort -Name $NewPortName -ErrorAction SilentlyContinue } } # Script Version: 3.9 Backup-SinglePrinter.psm1 function Backup-SinglePrinter { param ( [Parameter(Mandatory=$true)] [string]$PrinterName, [Parameter(Mandatory=$true)] [string]$BackupFile ) # Import settings $settingsPath = Join-Path $PSScriptRoot "settings.ps1" if (Test-Path $settingsPath) { . $settingsPath } else { Write-Error "Settings file not found at $settingsPath" return $false } # Import printer properties $propertiesModulePath = Join-Path $BaseFolder "Get-PrinterExtendedConfig.psm1" if (Test-Path $propertiesModulePath) { Import-Module $propertiesModulePath -Force } else { Write-Error "Get-PrinterExtendedConfig module not found at $propertiesModulePath" return $false } $computerName = $env:COMPUTERNAME $computerBackupFolder = Join-Path $BackupsFolder $computerName $driversFolder = Join-Path $computerBackupFolder "Drivers" if (-not (Test-Path $computerBackupFolder)) { New-Item -ItemType Directory -Path $computerBackupFolder -Force | Out-Null } if (-not (Test-Path $driversFolder)) { New-Item -ItemType Directory -Path $driversFolder -Force | Out-Null } try { $printer = Get-Printer -Name $PrinterName -Full $printerConfig = Get-PrintConfiguration -PrinterName $PrinterName $printerProperties = Get-PrinterProperty -PrinterName $PrinterName $backupObject = @{ Printer = $printer Configuration = $printerConfig Properties = $printerProperties IsShared = $printer.Shared ShareName = $printer.ShareName } $backupObject | Export-Clixml -Path $BackupFile -Depth 10 # Backup driver files $driverName = $printer.DriverName $driverInfo = Get-PrinterDriver -Name $driverName $driverPath = $driverInfo.InfPath if ($driverPath) { Copy-Item -Path $driverPath -Destination $driversFolder -Force } Write-Host "Printer '$PrinterName' backed up successfully to $BackupFile" return $true } catch { Write-Error "Printer backup process failed: $_" return $false } } Export-ModuleMember -Function Backup-SinglePrinter Restore-SinglePrinter.psm1 function Restore-SinglePrinter { param ( [Parameter(Mandatory=$true)] [string]$BackupFile, [Parameter(Mandatory=$true)] [string]$NewPrinterName, [Parameter(Mandatory=$false)] [string]$NewPortName ) try { $backupObject = Import-Clixml -Path $BackupFile $printer = $backupObject.Printer $printerConfig = $backupObject.Configuration $printerProperties = $backupObject.Properties # Import printer properties module $propertiesModulePath = Join-Path $PSScriptRoot "Get-PrinterExtendedConfig.psm1" if (Test-Path $propertiesModulePath) { Import-Module $propertiesModulePath -Force } else { Write-Error "Get-PrinterExtendedConfig module not found at $propertiesModulePath" return $false } $printerExtendedConfig = Get-PrinterExtendedConfig # If NewPortName is not provided, use the original port if (-not $NewPortName) { $NewPortName = $printer.PortName } # Create or update the printer if (Get-Printer -Name $NewPrinterName -ErrorAction SilentlyContinue) { Set-Printer -Name $NewPrinterName -DriverName $printer.DriverName -PortName $NewPortName } else { Add-Printer -Name $NewPrinterName -DriverName $printer.DriverName -PortName $NewPortName } # Restore printer settings $validPrinterParams = $printerExtendedConfig.PrinterProperties $printerParams = @{} foreach ($param in $validPrinterParams) { if ($null -ne $printer.$param) { $printerParams[$param] = $printer.$param } } if ($printerParams.Count -gt 0) { Set-Printer -Name $NewPrinterName @printerParams } # Restore configuration $validConfigParams = $printerExtendedConfig.PrinterConfiguration $configParams = @{} foreach ($param in $validConfigParams) { if ($null -ne $printerConfig.$param -and $printerConfig.$param -isnot [System.Management.Automation.PSMethod]) { $configParams[$param] = $printerConfig.$param } } if ($configParams.Count -gt 0) { Set-PrintConfiguration -PrinterName $NewPrinterName @configParams } # Restore properties foreach ($prop in $printerProperties) { if (-not [string]::IsNullOrWhiteSpace($prop.Name) -and $null -ne $prop.Value) { try { Set-PrinterProperty -PrinterName $NewPrinterName -PropertyName $prop.Name -Value $prop.Value -ErrorAction Stop } catch { Write-Warning "Unable to set printer property $($prop.Name): $_" } } } # Restore sharing settings if ($printer.Shared) { Set-Printer -Name $NewPrinterName -Shared $true -ShareName $NewPrinterName } Write-Host "Printer '$NewPrinterName' restored successfully from $BackupFile" return $true } catch { Write-Error "Printer restoration process failed: $_" return $false } } Export-ModuleMember -Function Restore-SinglePrinter Settings.ps1 # settings.ps1 $BaseFolder = "\\testserver\developer\printerBackup" $BackupsFolder = Join-Path $BaseFolder "Backups" Get-PrinterExtendedConfig.psm1 I hoped would be a single place to list all settings to capture. Maybe that is not needed. function Get-PrinterExtendedConfig { return @{ PrinterProperties = @( 'Comment', 'Location', 'Shared', 'Published' ) PrinterConfiguration = @( 'Collate', 'Color', 'DuplexingMode', 'PaperSize', 'Orientation' ) } } Export-ModuleMember -Function Get-PrinterExtendedConfig Find-AvailablePort.psm1 # Find-AvailableIPPort.psm1 function Find-AvailableIPPort { param ( [string]$BaseIP ) $existingPorts = Get-PrinterPort | Where-Object { $_.Name -like "$BaseIP*" } | Select-Object -ExpandProperty Name # If the base IP is not in use, return it if ($BaseIP -notin $existingPorts) { return $BaseIP } # Check for available ports with suffixes for ($i = 1; $i -lt 100; $i++) { $newIP = "${BaseIP}_$i" if ($newIP -notin $existingPorts) { return $newIP } } # If no available port found, create a new one with the next available suffix $maxSuffix = $existingPorts | Where-Object { $_ -match "${BaseIP}_(\d+)" } | ForEach-Object { [int]($Matches[1]) } | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum return "${BaseIP}_$($maxSuffix + 1)" } Export-ModuleMember -Function Find-AvailableIPPort974Views0likes2CommentsNeed help changing Printer Port Name in Bulk
Hello all, I am in now way a powershell person, I have used other peoples scripts and manipulated to do what I needed but I am stuck on this one and running out of time. I just need to change the portname of roughly 300 printers from "Printer-Name" to "Papercut_Printer-Name" as shown below. i have a .csv file created based off the link below but I feel that I may not need that whole script to do what I am doing (and it errors out anyway), and the technet link below that I am unsure of how to point at a .csv. If anyone could help me that would be great. Thank you very much! https://community.spiceworks.com/topic/1964582-need-script-to-bulk-change-printer-port-ip-addresses-on-2012-r2-print-server https://techcommunity.microsoft.com/t5/windows-powershell/unable-to-change-printer-port/m-p/14434851.9KViews0likes1Comment