Classes/printer.ps1
class Printer { <# .SYNOPSIS Represents a printer object, providing methods to manage printer drivers, ports, and printers. .DESCRIPTION The Printer class allows for the management of printer configurations, including checking for existing drivers, ports, and printers. It provides methods to add and remove printer drivers, ports, and printers. .PROPERTIES - Name: The name of the printer. - Driver: The name of the driver associated with the printer. - PortName: The name of the port associated with the printer. - PrinterHostAddress: The host address of the printer for port configuration. .METHODS - DriverExists Checks if the printer driver already exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $exists = $printer.DriverExists() Write-Host "Driver exists: $exists" - PortExists Checks if the specified printer port already exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $exists = $printer.PortExists() Write-Host "Port exists: $exists" - PrinterExists Checks if the printer already exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $exists = $printer.PrinterExists() Write-Host "Printer exists: $exists" - AddDriver Adds a printer driver if it does not already exist. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.AddDriver() - AddPort Adds a printer port if it does not already exist. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.AddPort() - AddPrinter Adds the printer if it does not already exist. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.AddPrinter() - RemovePrinter Removes the printer if it exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.RemovePrinter() - RemovePort Removes the printer port if it exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.RemovePort() - RemoveDriver Removes the printer driver if it exists. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.RemoveDriver() - InstallPrinterComponents Installs the printer, including the driver and port, if they do not already exist. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.InstallPrinterComponents() - RemovePrinterComponents Removes the printer, port, and driver. .EXAMPLE $printer = [Printer]::new('OfficePrinter', 'HP LaserJet', 'OfficePort', '192.168.1.10') $printer.RemovePrinterComponents() - FindUnassignedTCPIPPorts Find all TCP/IP ports that are unassigned i.e not in use .EXAMPLE # Create a Printer object $printer = [Printer]::new('null', 'null', 'null', 'null') # Find unassigned TCP/IP ports #$unassignedPorts = $printer.FindUnassignedTCPIPPorts() - RemoveUnassignedTCPIPPorts Remove any unassigned TCP/IP ports i.e delete any TCP/IP ports not in use .EXAMPLE # Create a Printer object $printer = [Printer]::new('null', 'null', 'null', 'null') # Remove unassigned TCP/IP ports $printer.RemoveUnassignedTCPIPPorts() .EXAMPLE Setting printer permissions (Assign directly to the method, not via a instantiated object parameter) $newSDDL = "O:SYG:SYD:(A;;FA;;;BA)(A;;FA;;;SY)(A;;0x1301ff;;;AU)" $printer.SetPrinterPermissions($newSDDL) .EXAMPLE Export Printer settings # Create a Printer object $printer = [Printer]::new("YourPrinterName") # Export settings to a valid file path $printer.ExportSettings("C:\ValidPath\printerConfig") # Export settings to an invalid file path (throws error) $printer.ExportSettings("C:\InvalidPath\printerConfig") .EXAMPLE Import Printer settings # Instantiate a printer object $printer = [Printer]::new("MyPrinterName") # Import settings from a .dat file $printer.ImportSettings("C:\Temp\printerConfig.dat") .NOTES Author : owen.heaume Version: 1.0 - Initial release 1.1 - Add methods: FindUnassignedTCPIPPorts and RemoveUnassignedTCPIPPorts #> [string]$Name [string]$Driver [string]$PortName [string]$PrinterHostAddress # Default constructor with all parameters Printer([string]$name, [string]$driver, [string]$portName, [string]$printerHostAddress) { $this.Name = $name $this.Driver = $driver $this.PortName = $portName $this.PrinterHostAddress = $printerHostAddress } # Overloaded constructor with default values for PortName and PrinterHostAddress Printer([string]$name, [string]$driver) { $this.Name = $name $this.Driver = $driver $this.PortName = 'DefaultPort' # Default value for PortName $this.PrinterHostAddress = '127.0.0.1' # Default value for PrinterHostAddress } # Overloaded constructor with default values for Driver, PortName, and PrinterHostAddress Printer([string]$name) { $this.Name = $name $this.Driver = 'DefaultDriver' # Default value for Driver $this.PortName = 'DefaultPort' # Default value for PortName $this.PrinterHostAddress = '127.0.0.1' # Default value for PrinterHostAddress } # ---- DRIVER MANAGEMENT ---- # Add a printer driver if it doesn't exist [void] AddDriver() { if (-not $this.DriverExists()) { try { #Write-Host "Adding driver: $($this.Driver) for printer: $($this.Name)" Add-PrinterDriver -Name $this.Driver -ea Stop } catch { #Write-Error "Failed to add driver $($this.Driver) for printer $($this.Name): $_" throw "Driver installation failed. $_" } } else { Write-Host "Driver $($this.Driver) already exists." } } # Remove the driver [void] RemoveDriver() { if ($this.DriverExists()) { try { # Write-Host "Removing driver: $($this.Driver)" Remove-PrinterDriver -Name $this.Driver -ErrorAction Stop } catch { #Write-Error "Failed to remove driver $($this.Driver): $_" throw "Driver removal failed. $_" } } else { Write-Host "Driver $($this.Driver) does not exist." } } # Check if a printer driver already exists [bool] DriverExists() { return Get-PrinterDriver -Name $this.Driver -ErrorAction SilentlyContinue } # ---- PORT MANAGEMENT ---- # Add a port if it doesn't exist [void] AddPort() { if (-not $this.PortExists()) { try { #Write-Host "Adding port: $($this.PortName) for printer: $($this.Name)" # Add the printer port using PrinterHostAddress Add-PrinterPort -Name $this.PortName -PrinterHostAddress $this.PrinterHostAddress -ea Stop } catch { #Write-Error "Failed to add port $($this.PortName) for printer $($this.Name): $_" throw "Port installation failed. $_ " } } else { Write-Host "Port $($this.PortName) already exists." } } # Remove the port [void] RemovePort() { if ($this.PortExists()) { try { # Write-Host "Removing port: $($this.PortName)" Remove-PrinterPort -Name $this.PortName -ErrorAction Stop } catch { # Write-Error "Failed to remove port $($this.PortName): $_" throw "Port removal failed. $_" } } else { Write-Host "Port $($this.PortName) does not exist." } } # Method to find unassigned TCP/IP ports with minimal output [System.Object[]] FindUnassignedTCPIPPorts() { try { # Get all TCP/IP printer ports $tcpPorts = Get-PrinterPort -ea stop | Where-Object { $_.PortMonitor -eq 'TCPMON.dll' } # Get ports that are currently assigned to printers $assignedPorts = Get-Printer -ea stop | Select-Object -ExpandProperty PortName # Find ports that are not assigned to any printer $unassignedPorts = $tcpPorts | Where-Object { $assignedPorts -notcontains $_.Name } # Count unassigned ports using a loop [int]$count = 0 $unassignedPorts | ForEach-Object { $count++ } # Output the count of unassigned ports if ($count -gt 0) { Write-Host "Found $count unassigned port(s):" -ForegroundColor DarkYellow foreach ($port in $unassignedPorts) { Write-Host "Unassigned Port: $($port.Name)" -ForegroundColor Yellow } } else { Write-Host 'No unassigned TCP/IP ports found.' -ForegroundColor DarkGray } return $unassignedPorts # Return the found unassigned ports } catch { throw "An error occurred while finding unassigned TCP/IP ports: $_" #return @() } } # Method to remove unassigned TCP/IP ports [void] RemoveUnassignedTCPIPPorts() { try { $unassignedPorts = $this.FindUnassignedTCPIPPorts() if ($unassignedPorts) { foreach ($port in $unassignedPorts) { try { Write-Host "Removing port: $($port.Name)..." -ForegroundColor DarkGray -NoNewline Remove-PrinterPort -Name $port.Name -ea Stop Write-Host 'Removed' -ForegroundColor DarkGreen } catch { Write-Error "An error occurred while removing the port: $_" } } } else { Write-Host 'No unassigned ports to remove.' -ForegroundColor DarkGray } } catch { #Write-Error "An error occurred while removing unassigned TCP/IP ports: $_" throw "Port removal process failed. $_" } } # Check if a port already exists [bool] PortExists() { return Get-PrinterPort -Name $this.PortName -ErrorAction SilentlyContinue } # Method to check if the printer's port is USB [bool] IsPortUSB() { <# We can check if the printer exists first if you like... if (!($this.PrinterExists())) { write-host "The printer '$($this.name)' does not exist on this system" return $false } #> try { # Define the registry path for USB printer ports $usbPortsRegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors\USB Monitor\Ports' # Get the USB printer ports from the registry $usbPorts = Get-ChildItem -Path $usbPortsRegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSChildName # Ensure both $usbPorts and $this.PortName are valid if ($usbPorts -and $this.PortName) { # Fetch the actual port name assigned to the printer $actualPortName = (Get-Printer -Name $this.Name -ErrorAction SilentlyContinue).PortName if ($actualPortName) { # Explicit string comparison to check if the printer's port is a USB port foreach ($usbPort in $usbPorts) { if ($usbPort -eq $actualPortName) { return $true } } } } # Default case: not a USB port return $false } catch { throw "An error occurred while checking if the port is USB: $_" } } # Method to check if the printer's port is TCP/IP [bool] IsPortTcp() { try { # Define the correct registry path for TCP/IP printer ports $tcpPortsRegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports' # Get the TCP/IP printer ports from the registry $tcpPorts = Get-ChildItem -Path $tcpPortsRegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSChildName # Ensure both $tcpPorts and $this.PortName are valid if ($tcpPorts -and $this.PortName) { # Fetch the actual port name assigned to the printer $actualPortName = (Get-Printer -Name $this.Name -ErrorAction SilentlyContinue).PortName if ($actualPortName) { # Explicit string comparison to check if the printer's port is a TCP/IP port foreach ($tcpPort in $tcpPorts) { if ($tcpPort -eq $actualPortName) { return $true } } } } # Default case: not a TCP/IP port return $false } catch { throw "An error occurred while checking if the port is TCP/IP: $_" } } # ---- PRINTER MANAGEMENT ---- # Add the printer if it doesn't exist [void] AddPrinter() { if (-not $this.PrinterExists()) { try { # Write-Host "Adding printer: $($this.Name) using driver: $($this.Driver) on port: $($this.PortName)" Add-Printer -Name $this.Name -DriverName $this.Driver -PortName $this.PortName -ea Stop } catch { #Write-Error "Failed to add printer $($this.Name): $_" throw "Printer installation failed. $_" } } else { Write-Host "Printer $($this.Name) already exists." } } # Remove the printer [void] RemovePrinter() { if ($this.PrinterExists()) { try { # Write-Host "Removing printer: $($this.Name)" Remove-Printer -Name $this.Name -ErrorAction Stop } catch { #Write-Error "Failed to remove printer $($this.Name): $_" throw "Printer removal failed. $_" } } else { Write-Host "Printer $($this.Name) does not exist." } } # Check if a printer already exists [bool] PrinterExists() { return Get-Printer -Name $this.Name -ErrorAction SilentlyContinue } # ---- PRINTER INSTALLATION AND REMOVAL ---- # Install all: driver, port, and printer [void] InstallPrinterComponents() { try { $this.AddDriver() $this.AddPort() $this.AddPrinter() } catch { #Write-Error "Failed to install the printer $($this.Name): $_" throw "Printer installation process failed. $_" } } # Remove all: printer, port, and driver [void] RemovePrinterComponents() { try { $this.RemovePrinter() $this.RemovePort() $this.RemoveDriver() } catch { #Write-Error "Failed to remove the printer $($this.Name): $_" throw "Printer removal process failed. $_" } } # ---- PRINTER PERMISSIONS MANAGEMENT ---- # Get the printer permissions [string] GetPrinterPermissions() { try { #Write-Host "Retrieving current printer SDDL permissions for $($this.Name)" $permissions = Get-Printer -Full -Name $this.Name -ea stop | Select-Object -ExpandProperty PermissionSDDL return $permissions } catch { throw "Unable to retrieve current printer SDDL permissions for $($this.Name) $_" } } # Set the printer permissions [void] SetPrinterPermissions([string]$newSDDL) { try { #Write-host "Setting printer permissions for $($this.Name) to $newSDDL" Set-Printer -Name $this.Name -PermissionSDDL $newSDDL -ea Stop } catch { #Write-Error "Failed to set printer permissions for $($this.Name): $_" throw "Permission setting failed. $_" } } # ---- PRINTER SETTINGS MANAGEMENT ---- [void]ExportSettings([string]$OutputFile) { # Ensure the output file has a .dat extension if (-not $OutputFile.EndsWith('.dat')) { $OutputFile += '.dat' } # Extract the directory path from the provided file path $directoryPath = [System.IO.Path]::GetDirectoryName($OutputFile) # Check if the directory exists if (-not (Test-Path -Path $directoryPath)) { throw [System.IO.DirectoryNotFoundException] "The directory '$directoryPath' does not exist. Please provide a valid path." } try { # Execute the printer settings export command & 'C:\Windows\System32\rundll32.exe' printui.dll, PrintUIEntry /Ss /n $this.Name /a $OutputFile Write-Host "Successfully exported printer settings for $($this.Name) to $OutputFile." -ForegroundColor DarkGray } catch { Write-Error "Failed to export printer settings for $($this.Name). $_" } } [void]ImportSettings([string]$InputFile) { # Ensure the input file has a .dat extension if (-not $InputFile.EndsWith('.dat')) { throw [System.ArgumentException] "The file '$InputFile' does not have a valid .dat extension." } # Check if the file exists if (-not (Test-Path -Path $InputFile)) { throw [System.IO.FileNotFoundException] "The file '$InputFile' does not exist. Please provide a valid file path." } try { # Execute the printer settings import command & 'C:\Windows\System32\rundll32.exe' printui.dll, PrintUIEntry /Sr /n $this.Name /a $InputFile Write-Host "Successfully imported printer settings for $($this.Name) from $InputFile." -ForegroundColor DarkGray } catch { Write-Error "Failed to import printer settings for $($this.Name). $_" } } } |