- Connect to Exchange Online with PowerShell - Wed, Jun 7 2023
- SCP from remote to local - Wed, May 31 2023
- Understanding Kubernetes Persistent Volumes - Mon, May 29 2023
Many aspects of infrastructure must be managed by the IT admin. Printers are one of the devices in today’s networks that are simple in function but often complicated to manage and maintain. However, with PowerShell, many of the more complicated tasks that have been performed manually by admins can be automated.
One aspect of configuring and maintaining printers is security. Printer security must be configured so that only authorized users can print, manage, or administer printers on the network. Setting up permissions can be very tedious to configure manually. However, by using PowerShell to alter the Windows permissions assigned to printers, securing printer permissions can easily be automated. Let’s look at how to manage printer security with PowerShell.
Methodology for assigning printer permissions
Like folders, files, and other shared objects on the network, printers have both Access Control Lists (ACLs) and Access Control Entries (ACEs). The Access Control List houses the Access Control Entries. In the world of Microsoft Windows server groups and best practices, Microsoft recommends placing users in groups and nesting these groups in a certain manner. A familiar acronym describing this method of assigning permissions in the very common Windows Server domain is AGDLP, which helps you to remember that objects are nested in the following order:
- Accounts
- Global Groups
- Domain Local Groups
- Permissions
This same methodology applies to assigning permissions to printers. Users and computer accounts are placed inside Global Groups, and Global Groups are then placed inside of the Domain Local Groups that are assigned permissions.
Using this methodology, you can easily implement effective (RBAC) for your organization. Based on a certain role, a user, group, or other object gets a certain set of permissions. Much like files and folders, printers are a resource on the network that are assigned permissions. Users and groups often get printer permissions based on their roles in the organization.
By default, when you create a printer, Windows—as it does in the case of all objects—assigns a certain set of default permissions that allow users to connect to the printer and perform the basic functions. The default permissions assigned include adding the Everyone group to the ACEs of the printer so that all users can print to the printer.
However, for many different reasons, certain printers may need to be restricted from allowing anyone who has a network login to print to a specific printer; for example, in order to restrict who can print to certain department printers. In many environments, printers are often located in specific locations for the use of certain departments. For purposes of billing individual departments for printer resources such as the cost of consumables, it may be necessary to restrict printing permissions to only those departments for which the printer is configured.
Let’s see how we can use PowerShell to control permissions for printers in order to both add and remove permissions as needed in a Windows environment.
Manage printer security with PowerShell
It seems as if there are PowerShell modules and cmdlets to control, manage, or configure just about any aspect of the Windows Server infrastructure. Printers are no exception. There is an official PowerShell module for interacting with Windows printers.
The PrintManagement module allows interacting with printers and the performance of many handy tasks when it comes to managing printers. The PrintManagement module includes the
Cmdlet | Description |
Add-Printer | Adds a printer to the specified computer. |
Add-PrinterDriver | Installs a printer driver on the specified computer. |
Add-PrinterPort | Installs a printer port on the specified computer. |
Get-PrintConfiguration | Gets the configuration information of a printer. |
Get-PrintJob | Retrieves a list of print jobs in the specified printer. |
Get-Printer | Retrieves a list of printers installed on a computer. |
Get-PrinterDriver | Retrieves the list of printer drivers installed on the specified computer. |
Get-PrinterPort | Retrieves a list of printer ports installed on the specified computer. |
Get-PrinterProperty | Retrieves printer properties for the specified printer. |
Read-PrinterNfcTag | Reads information about printers from an NFC tag. |
Remove-PrintJob | Removes a print job on the specified printer. |
Remove-Printer | Removes a printer from the specified computer. |
Remove-PrinterDriver | Deletes printer driver from the specified computer. |
Remove-PrinterPort | Removes the specified printer port from the specified computer. |
Rename-Printer | Renames the specified printer. |
Restart-PrintJob | Restarts a print job on the specified printer. |
Resume-PrintJob | Resumes a suspended print job. |
Set-PrintConfiguration | Sets the configuration information for the specified printer. |
Set-Printer | Updates the configuration of an existing printer. |
Set-PrinterProperty | Modifies the printer properties for the specified printer. |
Suspend-PrintJob | Suspends a print job on the specified printer. |
Write-PrinterNfcTag | Writes printer connection data to an NFC tag. |
One capability glaringly missing from the PrintManagement module is the ability to control printer permissions. However, TechNet script center comes to the rescue. A script found on the TechNet Script Center, Set-PrinterPermissions.ps1, fills the gap in the natively included PrintManagement PowerShell module.
Using the Set-PrinterPermissions PowerShell script, you can modify the ACE entries of your printers that are installed, either locally or on a print server. The parameters that can be passed to the script include the following:
- ServerName - Specify the SamAccountName of a server on which to modify printer permissions.
- AccountName - Specify the SamAccountName or userPrincipalName of a User or Group on which to modify or create permissions.
- SinglePrinterName - Specify an individual printer to modify permissions on. If no printer is specified, all printers on the target server will be updated.
- AccessMask - The permission Access Mask to be applied. Only relevant printer bit masks are represented: "ManagePrinters," "ManageDocuments," "Print," "TakeOwnership," "ReadPermissions," or "ChangePermissions." The default value is "Print."
- Deny - AccessMask AccessType will be set to "Deny." Default is to "Allow."
- Remove - Removes all Access Control Entries associated with the specified Account Name.
- AceFlag - A bit flag that indicates permission propagation:
- 0x0001 - OBJECT_INHERIT_ACE
- 0x0002 - CONTAINER_INHERIT_ACE
- 0x0004 - NO_PROPAGATE_INHERIT_ACE
- 0x0008 - INHERIT_ONLY_ACE
- 0x0010 - INHERITED_ACE
- IntAccessMask - uint32 representation of an access mask. If used, it overrides the AccessMask parameter.
- NoLog - Specify not to create a log file.
- LogFile - The path and file name of the desired log file. "C:\Logfile.txt"
Let’s look at an example of adding permissions to print to a locally attached printer to a domain group.
- ps1 -SinglePrinterName “<your printer name>” -AccountName “<Your user/domain group>” -AccessMask “Print”
After running the script, you can verify that permissions have been added to the printer on the Security tab. Note that we now have an entry for the TestGroup domain group.
What about removing permissions from a printer? Let’s take a look at the use case we mentioned earlier. You may need to remove the Everyone group from the permissions on a printer.
Using the Set-PrinterPermissions script, we can easily remove the ACE entry for Everyone with the following:
- Set-PrinterPermissions.ps1 -SinglePrinterName <your printer name> -AccountName “Everyone” -Remove
After running the script, we can verify that the Everyone group has been removed from the Printer permissions.
Subscribe to 4sysops newsletter!
Wrapping up
PowerShell provides the ability to manage, configure, and administer printers, including permissions. Although the native PrintManagement PowerShell module is deficient in its ability to provide permissions management, the Set-PrinterPermissions script is a great way to manage permissions on both locally attached printers and printers found on a print server. This provides a powerful way to automate permissions management of printers as well as to remediate any configuration drift that may happen in an environment over time.
Very cool! Can't wait to put this into action!!
doesn't work on windows 10 though. or might be me.
.\Set-PrinterPermissions.ps1 -SinglePrinterName "Canon IR-ADV C7260 #14-03"-AccountName "Everyone" -AccessMask "ManagePrinters"
a log file is created which says
Started: 08/29/2019 15:17:00
ERROR: New-Win32_Trustee()
Type: System.Management.Automation.MethodInvocationException
Message: Exception calling "GetBinaryForm" with "2" argument(s): "Destination array was not long enough. Check destIndex and length, and the array's lower bounds."
1 Printer(s) to be updated.
Account: Everyone
Mask: 983052 ManagePrinters
Type: 0
Flag: 4
ERROR: Set-PrinterPermissions()
Type: System.Management.Automation.RuntimeException
Message: Cannot convert value "2147749896" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
Finished: 08/29/2019 15:17:08
I have this same error when trying to use "Authenticated Users" on Server 2016. But adding normal domain accounts works perfect
Same here. The value in the "cannot convert" error is the same as above with a different print mask, so apparently not derived from mask.
Started: 03/05/2020 14:39:31
ERROR: New-Win32_Trustee()
Type: System.Management.Automation.MethodInvocationException
Message: Exception calling "GetBinaryForm" with "2" argument(s): "Destination array was not long enough. Check destIndex and length, and the array's lower bounds."
137 Printer(s) to be updated.
Account: NT AUTHORITY\Authenticated Users
Mask: 131080 Print
Type: 0
Flag: 4
ERROR: Set-PrinterPermissions()
Type: System.Management.Automation.RuntimeException
Message: Cannot convert value "2147749896" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
Finished: 03/05/2020 14:39:36
how can we use it to run on multiple server at once, can we use a list of servers
What exactly would you like to do? Remove Everyone from all printers on multiple servers?
I have a list of servers in txt file, i want to run this script on all those servers and provide printer security permission to required AD group as below:
-SinglePrinterName "myprintername" -AccountName "Domain\ADGroupName" -AccessMask "Print"
I want to run this script remotely on a list of servers and provide permission to the printer.
Without messing with the script I guess the easiest way would be to do:
Please try. I havent tested 🙂
Thanks a lot Leos, it worked like a charm, i just have to modify the script location.
Cheers!!
Stay Home Stay Safe
removing doesnt work at all in my case.
WOuld like to find a wzay to set permissions "manage printers" on the system, not on a printer.
Then the users could add printers, drivers, etc.
is there a way, programatically ?
Hello,
Could someone tell me where to find the script Set-PrinterPermissions.ps1?
Thanks
Hello,
Could someone tell me where to find the script Set-PrinterPermissions.ps1?
Thanks
i can't find the script either!
If someone still has a copy of this script, please post it somewhere and link from here.
Hello,
Could someone tell me where to find the script Set-PrinterPermissions.ps1?
It might be on github
https://github.com/myusefulrepo/powershell-functions/commit/962fa19b0d74f1bebfca8d4918e033782952a232
or
https://github.com/myusefulrepo/powershell-functions/blob/79381cbc9d0827a0dbe81040f0d1269284537a3c/Printer/Set-PrinterPermission.ps1
The code is executing without errors. But the process is not working.
What would be the reason?
https://prnt.sc/1x8hltt
Here is the script from the original page using the way back machine.
https://web.archive.org/web/20200318043335/https://gallery.technet.microsoft.com/scriptcenter/Modify-Printer-Permissions-149ae172/file/116651/1/Set-PrinterPermissions.ps1