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