- If a Windows service hangs, restart the service with PowerShell - Mon, Dec 12 2022
- Install, remove, list, and set default printer with PowerShell - Mon, Nov 7 2022
- Format time and date output of PowerShell New-TimeSpan - Wed, Nov 2 2022
Prerequisites
A note before we start: there is not a one-size-fits-all solution for all printers, since manufacturers have different choices, options, and settings for almost every driver, model, set of printer features, and so on. Therefore, you won't be running the same command for setting duplex and color printing for your Samsung, HP, or Brother printers.
Any supported version of Windows that has Windows PowerShell (5.1) or PowerShell 7 will work. Both will cover the most common scenarios. At the time of writing (Nov. 2022), there are the same number of commands in both versions of PowerShell (15). This might change in the future, as there will be no further development for Windows PowerShell. All the resources and innovations will be in PS7.
Now, it's time to see some of these commands in action. I find it very easy to learn by example, so let's dig in. Of course, like for any PowerShell cmdlet, you can also run Get-Help to get more information about each command.
Before you can install a printer, you'll need the driver for it. While most common printers already have drivers in Windows, there may be a situation when you need to install one from the drivers provided by your vendor.
After the driver is installed, you have to add the printer to the repository and add a printer port. Only then will you be able to add a local printer or a shared network printer with PowerShell. We will do this step-by-step.
Install the printer driver
Once you download the ISO or ZIP archive, extract it to a temp folder, and you'll find a bunch of files. One or more of them will have an .inf extension. Those are the files that you'll reference in the installation commands.
Note that if the drivers come packaged in an ISO file, you will most likely find a file called Autorun.inf in the root folder, which is used to mount and launch the CD when you insert it into a drive. That's not the .inf file you're looking for.
Sometimes, the folder structure can be complicated, particularly for vendors that attempt to install a bunch of utilities and apps with the drivers. To find the right INF file, we can use PowerShell:
Get-ChildItem -Recurse -Filter "*.inf" | Select-Object FullName
In my case, I'll use the file ssn3m.inf to install the driver(s) for my Samsung printer.
Opening the INF file in Notepad shows the name of the printer, which is what you can use for installing the driver offline (using Dism.exe and Add-PrinterDriver, see below). In my case, the name is "Samsung M337x 387x 407x Series."
Another way to get the driver's name is to use Dism.exe and check the description. The description field will be displayed several times, but it's the same for all the Windows versions and architectures this driver supports.
Dism.exe /online /Get-DriverInfo /driver:"C:\Temp\SamsungPrinter\Printer\SPL_PCL\ssn3m.inf"
You might be tempted to use the Add-PrinterDriver cmdlet to install the driver. However, despite Microsoft stating on its help page that the Add-PrinterDriver cmdlet installs a printer driver on the specified computer, this only works for Windows images that are offline. For a live installation, you also cannot use the servicing tool dism.exe.
To install a printer driver on a live Windows computer, you need the good old driver installation utility pnputil.exe. You don't have to provide the driver name because PnPUtil automatically gets the name from the INF file. The tool can also install all the INF files in a folder.
PNPUtil.exe /add-driver "C:\Temp\SamsungPrinter\Printer\SPL_PCL\ssn3m.inf" /install
List installed printer drivers with PnPUtil
You can also use PnPUtil to review installed drivers. This can be a long list if you've installed many drivers.
pnputil.exe /enum-drivers
Add a printer driver to the repository
Once the driver is installed, use Add-PrinterDriver to make the driver available in the list of printers in the repository. This is needed for adding local and shared network printers with PowerShell (see sections below). Here is where the driver name comes in handy.
Add-PrinterDriver -Name "Samsung M337x 387x 407x Series" -Verbose
Add the printer port
The only thing we need to do before we can actually add the printer is create a port for our printer. Since this is a local printer, I will create a local port. In the example below, I include the syntax for creating a network port. More information is available on the Microsoft documentation page.
Just like above, I've included a "before" and an "after" list of ports using Get-PrinterPort.
# Add local printer port Add-PrinterPort -Name "LocalPort:" -ErrorAction -Verbose # Add a network printer port Add-PrinterPort -Name "TCPPort:" -PrinterHostAddress "10.1.2.3" -ErrorAction SilentlyContinue
Add a local printer
The prerequisites for installing our printer are met. We can now use the Add-Printer cmdlet with a set of parameters to add our local printer. I've included an example with a splat object because I think it looks more elegant (Method 1), but you can simply use parameters in the command (Method 2).
Method 1: Using splatting
$PrinterDetails = @{ DriverName = "Samsung M337x 387x 407x Series" Name = "Samsung M337x" PortName = (Get-PrinterPort -Name LocalPort*).Name Verbose = $true } Add-Printer @PrinterDetails
Method 2: Using parameters
Add-Printer -DriverName "Samsung M337x 387x 407x Series" -Name "Samsung M337x" -PortName (Get-PrinterPort -Name LocalPort*).Name -Verbose
Of course, you can get more information using various options. You can include a location, you can publish it in Active Directory, you can set a comment, you can share it, etc.
Add a shared network printer
Adding a shared printer is often easier than installing a local one, because someone else might have already gone to the trouble of installing and configuring the drivers and printers. Adding the shared printer is accomplished using Add-Printer, just as with a local printer. You only need to specify the name of the print server and printer:
Add-Printer -ConnectionName "\\PrintServer\Samsung 407x (Colour)"
Let's look at some common tasks you may want to configure once the printer has been installed and added to your printers.
Set a default printer
There is no specific PowerShell cmdlet to set a printer as the default; however, you can use Invoke-CimMethod.
$Printer = Get-CimInstance -Class Win32_Printer -Filter "Name='Samsung M337x'" Invoke-CimMethod -InputObject $Printer -MethodName SetDefaultPrinter
Share a printer
Sharing a printer with PowerShell is easy using Set-Printer. Of course, you can also share it when you add it (see above), but if you forget or change your mind later, you can use this command.
Set-Printer -Name "Samsung M337x" -Shared $True -ShareName "Samsung M337x (B/W)"
With Get-Printer, you can quickly confirm that the printer is shared.
Remove a printer
Once the printer has reached its end of life, you can easily remove it from Windows using Remove-Printer:
Remove-Printer -Name "Samsung M337x" -Verbose
If you don't plan to replace the printer, you can also remove the printer driver. You can do it directly with Remove-PrinterDriver and specify the full driver name, or you can use Get-Printer, specify a wildcard, and then pipe it to Remove-PrinterDriver. Just make sure the wildcard is not too generic, so you don't remove drivers than you still need.
# Remove-PrinterDriver -Name "Samsung M337x 387x 407x Series" Get-PrinterDriver -Name Samsung M337x* | Remove-PrinterDriver -Verbose
Install a printer with a PowerShell script
As you have noticed, many steps are needed to install a printer with PowerShell. To automate the process, you can use the little PowerShell that I wrote. Please consider these points before you use the script:
Subscribe to 4sysops newsletter!
- Make sure you replace the path where you extracted the drivers with the actual path (in my case, it's C:\Temp\SamsungPrinter).
- My command selects the first INF file that is not Autorun.inf (explained above). There may be more than one .inf file in your folder. Make sure you select the correct one. If you're not sure, just use the path to the file (something like $inf = C:\Temp \Extracted\Model600\Driver\MagicPrinter.inf).
- Make sure that the driver name is what you're looking for. Normally, the description retrieved with Dism.exe is valid.
- The script contains a line for adding a local and a network port. Remove the line that you don't need. Also, replace the IP address if you add a network printer port.
# Get the driver file. Select the first, in case there are more $inf = Get-ChildItem -Path "C:\Temp\SamsungPrinter" -Recurse -Filter "*.inf" | Where-Object Name -NotLike "Autorun.inf" | Select-Object -First 1 | Select-Object -ExpandProperty FullName # Check that the inf file is the one you're looking for Write-Host "The inf file is '$inf'" -ForegroundColor Cyan # Install the driver PNPUtil.exe /add-driver $inf /install # Retrieve driver info $DismInfo = Dism.exe /online /Get-DriverInfo /driver:$inf # Retrieve the printer driver name $DriverName = ( $DismInfo | Select-String -Pattern "Description" | Select-Object -Last 1 ) -split " : " | Select-Object -Last 1 # Add driver to the list of available printers Add-PrinterDriver -Name $DriverName -Verbose # Add local printer port (SilentlyContinue skips without errors in case the port name already exists) Add-PrinterPort -Name "LocalPort:" -ErrorAction SilentlyContinue -Verbose # Add a network printer port Add-PrinterPort -Name "TCPPort:" -PrinterHostAddress "10.1.2.3" -ErrorAction SilentlyContinue #Add the printer Add-Printer -DriverName $DriverName -Name $DriverName -PortName (Get-PrinterPort -Name LocalPort*).Name -Verbose
Conclusion
In this post, I covered only the core tasks required for managing printers with PowerShell. Many settings depend on the printer's and drivers' capabilities, and you need to consult your printer's documentation to learn more about these options.
Hi Emanuel,
cool post indeed!
Question – as you know the default printer is per-user setting. Is it possible to use the command remotely and set the default printer for a specific user? I guess that would require impersonating the command, right?
Cheers Leos
Hello, Leos.
I imagine you can, but it would invoke a bit more digging in the WMI. But it’s perfectly doable, Invoke-CimMethod has the switch -ComputerName which allows you to execute commands to remote computers.
If it’s for a lot of users, you can still use Group Policy Preferences. Mike Kanakos has an excellent article here: https://4sysops.com/archives/deploying-printers-using-group-policy/
Cheers! Emanuel
P.S. Many thanks for the appreciation.
Ye sure, I know about it, had read the post in the past already :). Now I was thinking more for an ad-hoc solution.
A bit afraid that remotely it would be a bit difficult for a specific user, as normally you execute the remote command under your admin account.
Maybe its easier to connect via remote support tool and do the clicking/pasting the command.
Hello again, Leos
The code in the article for setting a default printer (and also below) doesn’t need admin credentials.
$Printer = Get-CimInstance -Class Win32_Printer -Filter “Name=’Adobe PDF'”
Invoke-CimMethod -InputObject $Printer -MethodName SetDefaultPrinter
If you haven’t blocked PowerShell for regular users, you could include this code as part of their logon script.
Hello Emanuel,
there are printers that ask for an acceptance to continue adding the driver, is there a way for me to force this with the PS?
Hi, Gustavo. I hate to give you the consultant answer, but “it depends”. Since this is not related to the topic, you can ping me in private and continue the conversation there. If I can help, I’d be glad to.
Cheers! Emanuel