printer-powershell

Automated Printer Installation Script Documentation (Run Locally)

📄 Overview

This document provides a guide for the installing printer through PowerShell script, which automates the installation of a specific printer model. The script is designed for idempotency, meaning it can be run multiple times without causing errors, as it checks if components (drivers, ports, printer object) already exist before attempting to create them.

Script for RMM/Intune : https://website-c62a0363.feg.pqz.temporary.site/automated-printer-deployment-script-guide-powershell/

1. Prerequisites and Configuration

Before running the script, ensure the following conditions are met:

RequirementDetails
PermissionsThe script must be run with Administrator privileges.
Driver FileThe initial driver file (in my case CNP60MA64.INF) must be present at the expected staging location: C:\Temp\Driver\CNP60MA64.INF. (This filename is confirmed for the current installation case).
PowerShell VersionPowerShell 5.1 or newer (Standard on Windows 10/11) is recommended.
VariablesReview the variables at the top of the script and adjust them if the printer’s configuration changes.

Script Variables

The following variables are defined at the start of the script:

VariableValuePurpose
$PrinterIP"192.168.15.25"The target IP address of the network printer.
$PortName"IP_192.168.15.25"The name the TCP/IP port will be assigned.
$DriverName"HP Generic Plus PCL6"The exact name of the printer driver to be used. (Must match the INF file)
$InfFileName"CNP60MA64.INF"The name of the driver installation file.
$InitialInf"C:\Temp\Driver\CNP60MA64.INF"The temporary path where the driver is staged for Pnputil.
$PrinterName"HR PRINTER"The visible name the printer will have in Windows.

Determining the Exact Driver Name

The $DriverName variable (currently set to "HP Generic Plus PCL6") is case-sensitive and must exactly match the descriptive name defined inside the driver’s .INF file. If you are using a different driver, you must verify this value.

To find the correct name:

  1. Open the .INF file: Use a standard text editor (like Notepad or VS Code) to open the CNP60MA64.INF file.
  2. Locate the Strings Section: Scroll to the bottom of the file and locate the [Strings] section, or search for the [Manufacturer] section.
  3. Find the Display Name: Look for a line that contains the human-readable, quoted name of the driver. This is typically the name that appears in the “Add Printer” wizard.

For example, you might see an entry that looks like this:

PowerShell Script
DriverDesc = "HP Generic Plus PCL6"

The exact quoted text (e.g., "HP Generic Plus PCL6") is the value required for the $DriverName variable.

2. Script Logic and Flow

The script follows a sequential, error-checked workflow to ensure reliable installation.

Step 1: Install Driver to Driver Store (Pnputil)

  • Command: Pnputil /add-driver $InitialInf /install
  • Purpose: This command stages and installs the driver files into the Windows Driver Store.
  • Robustness: The script checks the $LASTEXITCODE for success or failure, providing a warning but continuing execution, as the driver might already be installed.

Step 2: Dynamically Find Driver Path

  • Command: Get-ChildItem -Path C:\Windows\System32\DriverStore\FileRepository -Filter "*$InfFileName" -Recurse
  • Purpose: The path created by Windows in the FileRepository is unique and contains an appended hash. This step dynamically searches for the subfolder containing $InfFileName and retrieves its full path.
  • Importance: This dynamic search ensures the script works correctly across different Windows machines, as it bypasses the need for a hardcoded, unique path.

Step 3: Add Printer Driver (Add-PrinterDriver)

  • Command: Add-PrinterDriver -Name $DriverName -InfPath $InfPath
  • Purpose: Registers the installed driver with the Windows Print Spooler service, making it available to the Add-Printer cmdlet.
  • Robustness: Uses a try/catch block to check if the driver already exists. If it does, a success message is displayed, and the script continues.

Step 4: Check and Create Printer Port

  • Port Check: Get-PrinterPort -Name $PortName -ErrorAction SilentlyContinue
  • Port Creation: Add-PrinterPort -Name $PortName -PrinterHostAddress $PrinterIP
  • Purpose: The script first checks if a TCP/IP port with the specified $PortName (e.g., IP_192.168.15.25) exists.
  • Robustness: If the port is found, port creation is skipped. If not found, a new port is created. This prevents an error message when re-running the script.

Step 5: Install the Printer Object

  • Command: Add-Printer -DriverName $DriverName -Name $PrinterName -PortName $PortName
  • Purpose: Creates the final printer object visible in Windows, linking the driver and the port.
  • Robustness: Uses a try/catch block to handle the scenario where the printer object (HR PRINTER) already exists, preventing a failure and allowing the script to complete gracefully.

Step 6: Verification

  • Command: Get-Printer | Select-Object Name, DriverName, PortName | Format-Table -AutoSize
  • Purpose: Displays the name, driver, and port for all installed printers, allowing the user to quickly verify the successful installation of the target printer.

Full Script

Powershell: printer installation
# Define variables for printer installation
$PrinterIP    = "192.168.15.25"
$PortName     = "IP_$($PrinterIP)"
$DriverName   = "HP Generic PCL6"
$InfFileName  = "CNP60MA64.INF"
$InitialInf   = "C:\Temp\Driver\$InfFileName"
$PrinterName  = "HR PRINTER"

# --- Driver Installation ---

# Step 1: Add the driver to the Driver Store using Pnputil (pre-installs the driver)
Write-Host "--- Attempting to add driver to Driver Store from $InitialInf..."
Pnputil /add-driver $InitialInf /install
if ($LASTEXITCODE -ne 0) {
    Write-Warning "Pnputil returned an error code: $LASTEXITCODE. This may mean the driver is already present. Proceeding..."
}

# Step 2: Dynamically find the full path of the installed INF file
Write-Host "--- Searching for the installed driver path..."
$DriverStorePath = Get-ChildItem -Path C:\Windows\System32\DriverStore\FileRepository -Filter "*$InfFileName" -Recurse | Select-Object -First 1

if ($DriverStorePath -ne $null) {
    $InfPath = $DriverStorePath.FullName
    Write-Host " Found driver path: $InfPath"
} else {
    Write-Error " Failed to find the installed driver path in FileRepository for $InfFileName. Cannot proceed with Add-PrinterDriver."
    exit 1
}

# Step 3: Add the printer driver for use with the Add-Printer cmdlet
try {
    Write-Host "--- Attempting to add printer driver '$DriverName'..."
    Add-PrinterDriver -Name $DriverName -InfPath $InfPath -ErrorAction Stop
    Write-Host " Printer driver added successfully."
}
catch {
    if ($_.Exception.Message -match "already exists") {
        Write-Host " Printer driver '$DriverName' already installed. Continuing..."
    }
    else {
        Write-Error " Failed to add printer driver: $($_.Exception.Message)"
        # You might choose to exit the script here if the driver is critical
    }
}

# ----------------------------------------------------------------------

# --- Port Creation and Printer Installation ---

# Step 4: Check if the printer port already exists
Write-Host "--- Checking for existing port '$PortName'..."
$ExistingPort = Get-PrinterPort -Name $PortName -ErrorAction SilentlyContinue

if (-not $ExistingPort) {
    # Port does not exist, create it
    Write-Host " Printer port '$PortName' not found. Creating new TCP/IP port..."
    try {
        Add-PrinterPort -Name $PortName -PrinterHostAddress $PrinterIP -ErrorAction Stop
        Write-Host " Printer port created successfully."
    }
    catch {
        Write-Error " Failed to create printer port: $($_.Exception.Message)"
        # Exiting because we can't install the printer without the port
        exit 1
    }
} else {
    Write-Host " Printer port '$PortName' already exists. Skipping port creation."
}

# Step 5: Install the printer
Write-Host "--- Attempting to install printer '$PrinterName'..."
try {
    # The command will fail if the printer name already exists, so we wrap it in a try/catch
    Add-Printer -DriverName $DriverName -Name $PrinterName -PortName $PortName -ErrorAction Stop
    Write-Host " Printer '$PrinterName' installed successfully."
}
catch {
    if ($_.Exception.Message -match "already exists") {
        Write-Host " Printer '$PrinterName' already exists. Skipping installation."
    }
    else {
        Write-Error " Failed to install printer: $($_.Exception.Message)"
    }
}

# ----------------------------------------------------------------------

# --- Verification ---

# Step 6: Display all installed printers for verification
Write-Host "--- Current installed printers:"
Get-Printer | Select-Object Name, DriverName, PortName | Format-Table -AutoSize