Adding printer drivers and printers using Microsoft Intune and PowerShell

This year I wrote two separate blog posts about adding printer drivers and printers to Intune clients. Recently I repackaged these two into one package with some improvements. In this blog post, I will show how it looks now 🙂

How the script works

The script will take the following steps:

  • Import a printers.csv file containing all printers. This file looks like this: (The DriverName is present in the .inf files, make sure it matches)
"Name","DriverName","PortName","Comment","Location"
"Contoso-General","TOSHIBA Universal Printer 2","192.1.2.3","Contoso","Hallway"
"Contoso-HP","HP Universal Printing PCL 6 (v7.0.0)","192.4.5.6","HR","HR Office"
"Contoso-MFP","Canon Generic Plus PCL6","192.7.8.9","MFP","Finance Office"
  • Create a list of .inf files in the package directory, and you can add the driver directories in separate folders like this:
Canon
HP
Toshiba
  • Install all the drivers from within those folders using the .inf files
  • Add all the installed drivers to Windows using the Add-PrinterDriver cmdlet
  • Add the printers using the fields from the CSV file to Windows using the Add-PrinterPort, Add-Printer, and Set-PrintConfiguration cmdlets. If it finds printer ports that were already present, it will remove the attached printer first and recreate it (Easy if you have an updated name or IP address for that port). You can edit the script to set the default Printer configuration. This example doesn’t print in color by default and prints on both sides of the paper.

The detection script for Intune will count the number of printers and check if they are all installed. If not, it will exit with code 1, which tells Intune to start the install.cmd.

Running the installation script

When running the Add_Printers.ps1 script, the output looks like this (It also logs all output to c:\windows\temp\printers.log using Start-Transcript)

Transcript started, output file is c:\windows\temp\printers.log
[Install printer driver(s)]

[1/3] Adding inf file C:\Users\WDAGUtilityAccount\Desktop\Adding Printer Drivers and Printers with Intune\Canon\CNP60MA64.INF
[2/3] Adding inf file C:\Users\WDAGUtilityAccount\Desktop\Adding Printer Drivers and Printers with Intune\HP\hpcu250u.inf
[3/3] Adding inf file C:\Users\WDAGUtilityAccount\Desktop\Adding Printer Drivers and Printers with Intune\TOSHIBA\esf6u.inf

[Add printerdriver(s) to Windows]
[1/3] Adding printerdriver TOSHIBA Universal Printer 2
[2/3] Adding printerdriver HP Universal Printing PCL 6 (v7.0.0)
[3/3] Adding printerdriver Canon Generic Plus PCL6

[Add printer(s) to Windows]
[1/3] Adding printer Contoso-General
[2/3] Adding printer Contoso-HP
[3/3] Adding printer Contoso-MFP
Transcript stopped, output file is C:\windows\temp\printers.log

Running the detection script

Intune will run the detection script to see if all printers are installed. You can see the output in the AgentExector.log file in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs :

Name                           ComputerName    Type         DriverName                PortName        Shared   Published
----                           ------------    ----         ----------                --------        ------   --------
Contoso-General                   		Local        TOSHIBA Universal Pri... Contoso-Gene... False    False
Contoso-HP                        		Local        HP Universal Printing... Contoso-HP      False    False   
Contoso-MFP                       		Local        Canon Generic Plus PC... Contoso-MFP     False    False   
(3) printers were found

If it can’t find all printers, it will remove/add everything with the values from the printers.csv list. By doing so, any change in the detection.ps1 script will start the installation so that changes in the printers.csv will be processed, making updating existing printers easier. Always update the detection.ps1 with the correct printer names!

The scripts

Below are all the files needed for installation. Combine these with the printer folders into one folder and create a .intunewin file. Add the package to intune and use the detection.ps1 for the detection rule and the install.cmd and uninstall.cmd for install/uninstall and set it as System.

Add_Printers.ps1

Start-Transcript -Path c:\windows\temp\printers.log
#Read printers.csv as input
$Printers = Import-Csv .\printers.csv

#Add all printer drivers by scanning for the .inf files and installing them using pnputil.exe
$infs = get-childitem -Path . -Filter "*.inf" -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Fullname

$totalnumberofinfs = $infs.Count
$currentnumber = 1
Write-Host ("[Install printer driver(s)]n") -ForegroundColor Green
Foreach ($inf in $infs) {
    Write-Host ("[{0}/{1}] Adding inf file {2}" -f $currentnumber, $totalnumberofinfs, $inf) -ForegroundColor Green
    try {
        c:\windows\sysnative\Pnputil.exe /a $inf | Out-Null
    }
    catch {
        try {
            c:\windows\system32\Pnputil.exe /a $inf | Out-Null
        }
        catch {
            C:\Windows\SysWOW64\pnputil.exe /a $inf | Out-Null
        }
    }
    $currentnumber++
}

#Add all installed drivers to Windows using the CSV list for the correct names
$totalnumberofdrivers = ($printers.drivername | Select-Object -Unique).count
$currentnumber = 1
Write-Host ("[Add printerdriver(s) to Windows]") -ForegroundColor Green
foreach ($driver in $printers.drivername | Select-Object -Unique) {
    Write-Host ("[{0}/{1}] Adding printerdriver {2}" -f $currentnumber, $totalnumberofdrivers, $driver) -ForegroundColor Green
    Add-PrinterDriver -Name $driver
    $currentnumber++
}

#Loop through all printers in the csv-file and add the Printer port, the printer and associate it with the port and set the color options to 0 which is black and white (1 = automatic and 2 = color)
$totalnumberofprinters = $Printers.Count
$currentnumber = 1
Write-Host ("`n[Add printer(s) to Windows]") -ForegroundColor Green
foreach ($printer in $printers) {
    Write-Host ("[{0}/{1}] Adding printer {2}" -f $currentnumber, $totalnumberofprinters, $printer.Name) -ForegroundColor Green
    #Set options for adding printers and their ports
    $PrinterAddOptions = @{
        ComputerName = $env:COMPUTERNAME
        Comment      = $Printer.Comment
        DriverName   = $Printer.DriverName
        Location     = $Printer.Location
        Name         = $Printer.Name
        PortName     = $Printer.Name
    }

    $PrinterConfigOptions = @{
        Color         = 0
        DuplexingMode = 'TwoSidedLongEdge'
        PrinterName   = $Printer.Name
    }

    $PrinterPortOptions = @{
        ComputerName       = $env:COMPUTERNAME
        Name               = $Printer.Name
        PrinterHostAddress = $Printer.PortName
        PortNumber         = '9100'

    }

    #Add Printerport, remove existing one and the corresponding printer if it already exists 
    if (Get-PrinterPort -ComputerName $env:COMPUTERNAME | Where-Object Name -EQ $printer.Name) {  
        Write-Warning ("Port for Printer {0} already exists, removing existing port and printer first" -f $printer.Name)
        Remove-Printer -Name $printer.Name -ComputerName $env:COMPUTERNAME -Confirm:$false -ErrorAction SilentlyContinue
        Start-Sleep -Seconds 10
        Remove-PrinterPort -Name $printer.Name -ComputerName $env:COMPUTERNAME -Confirm:$false
    }

    #Add printer and configure it with the required options
    Add-PrinterPort @PrinterPortOptions
    Add-Printer @PrinterAddOptions -ErrorAction SilentlyContinue
    Set-PrintConfiguration @PrinterConfigOptions
    $currentnumber++
}
Stop-Transcript

Detection.ps1

$printers = @(
    'Contoso-General'
    'Contoso-HP'
    'Contoso-MFP'
)

#Check every printer if it's installed
$numberofprintersfound = 0
foreach ($printer in $printers) {
    try {
        Get-Printer -Name $printer -ErrorAction Stop
        $numberofprintersfound++
    }
    catch {
        "Printer $($printer) not found"
    }
}

#If all printers are installed, exit 0
if ($numberofprintersfound -eq $printers.count) {
    write-host "($numberofprintersfound) printers were found"
    exit 0
}
else {
    write-host "Not all $($printers.count) printers were found"
    exit 1
}

Install.cmd

The 32Bit version of PowerShell is used here because of issues calling the correct pnputil.exe

C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -file .\add_printers.ps1

Printers.csv

"Name","DriverName","PortName","Comment","Location"
"Contoso-General","TOSHIBA Universal Printer 2","192.1.2.3","Contoso","Hallway"
"Contoso-HP","HP Universal Printing PCL 6 (v7.0.0)","192.4.5.6","HR","HR Office"
"Contoso-MFP","Canon Generic Plus PCL6","192.7.8.9","MFP","Finance Office"

Remove_Printers.ps1

#Read printers.csv as input
$Printers = Import-Csv .\printers.csv

#Loop through all printers in the csv-file and remove the printers listed
foreach ($printer in $printers) {
    #Set options
    $PrinterRemoveOptions = @{
        Confirm = $false
        Name    = $Printer.Name
    }

    $PrinterPortRemoveOptions = @{
        Confirm      = $false
        Computername = $env:COMPUTERNAME
        Name         = $Printer.Name
    }

    #Remove printers and their ports
    Remove-Printer @PrinterRemoveOptions
    Start-Sleep -Seconds 10
    Remove-PrinterPort @PrinterPortRemoveOptions
}

#Remove drivers from the system
foreach ($driver in $printers.drivername | Select-Object -Unique) {
    $PrinterDriverRemoveOptions = @{
        Confirm               = $false
        Computername          = $env:COMPUTERNAME
        Name                  = $driver
        RemoveFromDriverStore = $true
    }
    Remove-PrinterDriver @PrinterDriverRemoveOptions
}

Uninstall.cmd

powershell.exe -executionpolicy bypass -file .\remove_printers.ps1

Download the script(s) from GitHub here

2 thoughts on “Adding printer drivers and printers using Microsoft Intune and PowerShell

  1. Pingback: Blog post – Adding printer drivers and printers using Intune – 247 TECH

  2. Pingback: Intune Newsletter - 9th December 2022 - Andrew Taylor

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.