Главная

Sunday, 7 July 2024

Printer and PowerShell.

Hi all.

With PowerShell, you can easily install a printer driver, add a printer to the repository, and then add a local or shared network printer to your Windows installation. In this post, I will also explain how you can list printers, add a printer port, set the default printer, and remove a printer with PowerShell.

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 illustrate the process of installing a new print driver, let’s take a concrete example of setting up Samsung M337x 387x 407x Series. According to the documentation, the PowerShell command for adding a driver is:

Add-PrinterDriver -Name "Samsung M337x 387x 407x Series” -InfPath "C:\Temp\SamsungPrinter\Printer\SPL_PCL\ssn3m.inf”

However, when you try your best to install a driver this way, an error appears:

Add-PrinterDriver : One or more specified parameters for this operation has an invalid value.

At line:1 char:1

+ Add-PrinterDriver -Name "Samsung M337x 387x 407x Series” -InfPath “C:\Т …

+ ~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidArgument: (MSFT_PrinterDriver:ROOT/StandardCimv2/MSFT_PrinterDriver) [Add-PrinterDriver], CimException + FullyQualifiedErrorId : HRESULT 0×80070057,Add-PrinterDriver

It turns out the driver from the INF file can be added under one specific condition - only if the DriverStore driver storage contains it. Logically, using the Add-PrinterDriver command to install a driver not available in the system driver storage is impossible. 

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:

1. Make sure you replace the path where you extracted the drivers with the actual path (in my case, it's C:\Temp\SamsungPrinter).

2. 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).

3. Make sure that the driver name is what you're looking for. Normally, the description retrieved with Dism.exe is valid.

4. 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.

No comments:

Post a Comment

А что вы думаете по этому поводу?