Add printer from a print server in Intune using powershell for Azure AD joined computers

Strangely enough Intune still does not support adding printers that are published through a print server directly, even though it is just a one-liner PowerShell script to execute. Universal Print from our experience has been a little unstable and it’s rare that anyone needs to print outside of the network anyway.

Add-Printer -ConnectionName "\\company.local\printername"

The issue here is that this one-liner needs to be run under the user context and here is where it get’s tricky. There might be more than one way to achieve this, but the script following utilizes a workaround where we create a schedule task to be run under user context from the package deployed. This also helps with the issue that the server hosting the print queue might not be available at the time the script is intially run. The logic here can probably be improved, but it at least works, and uninstallation also work. A second thing that we have to “workaround” is that PowerShell scripts ran from Task Scheduler under user context will show for the end user, which is not desired. We circumvent that annoiance by creating a VBS script that runs from Task Scheduler that runs the actual PowerShell script.

We need two scripts in order for this whole solution to work as well as a custom detection script, unless you figure another way of detecting the printer afterwards easily.

Logging goes to the IntuneManagementExtension folder since we then can run a “Collect diagnostics” on a device directly from Endpoint Manager and fetch the log from folder 42. This so that we don’t need to involve the user if we need to troubleshoot.

The first one is for creating the scheduled task and also creates a VBS script to run.

The script has 2 arguments:

  • printerFQDN – Example \\mycompany.local\printqueue1
  • uninstall – Add -uninstall to remove the printer
param (
    [switch]$uninstall = $false,
    [Parameter(Mandatory = $true)]
    [string]$printerFQDN
)

$taskScheduleName = "PrintInstall-$($printerFQDN -replace '\W','')"
$logfileName = "$taskScheduleName-TaskSchedule.log"
$scriptDir = "$env:ProgramData\$taskScheduleName"
$scriptName = "InstallPrinter.ps1"

Start-Transcript -Path $(Join-Path -Path C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\ -ChildPath $logfileName) -Force
if (!(Test-Path $scriptDir)) {
    New-Item -Path $scriptDir -ItemType Directory
}
Copy-Item -Path .\$scriptName -Destination $scriptDir\$scriptName -Force

if ($uninstall) {
    # Make the task-scheduler silent
    $vbs = @"
command = "powershell.exe -nologo -executionpolicy Bypass -windowstyle hidden -file $scriptDir\$scriptName -printerFQDN $printerFQDN -uninstall"
set shell = CreateObject("WScript.Shell")
shell.Run command,0
"@

    $vbs | Out-File -FilePath "$scriptDir\$($scriptName.replace(".ps1","-uninstall.vbs"))" -Force

    Unregister-ScheduledTask -TaskName $taskScheduleName -Confirm:$false -ErrorAction SilentlyContinue
    $action = New-ScheduledTaskAction -Execute "$scriptDir\$($scriptName.replace(".ps1","-uninstall.vbs"))"
    $trigger = New-ScheduledTaskTrigger -AtLogOn
    $principal = New-ScheduledTaskPrincipal -UserId (whoami)
    $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
    $task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings
    Register-ScheduledTask RemoveThatPrinter -InputObject $task
    Start-ScheduledTask -TaskName RemoveThatPrinter
    Start-Sleep -Seconds 1
    Unregister-ScheduledTask -TaskName RemoveThatPrinter -Confirm:$false
    Remove-Item -Path $scriptDir -Recurse -Force
} 
else {
    # Make the task-scheduler silent
    $vbs = @"
command = "powershell.exe -nologo -executionpolicy Bypass -windowstyle hidden -file $scriptDir\$scriptName -printerFQDN $printerFQDN"
set shell = CreateObject("WScript.Shell")
shell.Run command,0
"@

    $vbs | Out-File -FilePath "$scriptDir\$($scriptName.replace("ps1","vbs"))" -Force
    Unregister-ScheduledTask -TaskName $taskScheduleName -Confirm:$false -ErrorAction SilentlyContinue
    $action = New-ScheduledTaskAction -Execute "$scriptDir\$($scriptName.replace("ps1","vbs"))"
    $trigger = @(
        $(New-ScheduledTaskTrigger -AtLogOn),
        $(New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 10))
    )
    $principal = New-ScheduledTaskPrincipal -UserId (whoami)
    $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -Hidden
    $task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings
    Register-ScheduledTask $taskScheduleName -InputObject $task
    Start-ScheduledTask -TaskName $taskScheduleName
}

Stop-Transcript
exit 0
param (
    [switch]$uninstall = $false,
    [Parameter(Mandatory = $true)]
    [string]$printerFQDN
)

# Starting our logging.
$taskScheduleName = "PrintInstall-$($printerFQDN -replace '\W','')"
$logfileName = "$taskScheduleName.log"
$scriptDir = "$env:ProgramData\$taskScheduleName"
$scriptName = "InstallPrinter.ps1"

Start-Transcript -Path $(Join-Path -Path C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\ -ChildPath $logfileName) -Force

if (!($uninstall)) {
    "Installing printer $printerFQDN"
    Add-Printer -ConnectionName $printerFQDN
}
else {
    "Uninstalling printer $printerFQDN"
    Remove-Printer -Name $printerFQDN
}

Stop-Transcript

# Let's tell IME that all is well :)
exit 0

Save both of these files into the same folder and package it as a Win32 file using IntuneWin. Once done you are ready to install printers.

Uppload the package with “Install Behaviour” set to User and assign.

The detectionscript needs to be created based on what the taskname ends up being named.

if(Get-ScheduledTask -TaskName PrintInstall-xxxxx -ErrorAction SilentlyContinue){"Detected"}

Two improvements that should be made to the scripts would be:

  • Check for domain line of sight before trying to add printer
  • Self remove the scheduled task once printer has been added
  • Possibility to add an array of printerFQDN’s for multiple printers

    Leave a Reply

    Your email address will not be published. Required fields are marked *