Set Permissions for a Print Server with Powershell

Set Permissions for a Print Server with Powershell

You cannot set permissions for a print server with Powershell alone. At least you can’t right now (4th of May 2017). There’s a way though 🙂

I spent a few hours researching this and I noticed I wasn’t the only one that wanted to set up a security group on a Print Server level in a scripted manner, however everybody was stuck with the same issue. Just to be clear, this is what I want to achieve:

print-management_print-server-security

My idea is to get a security group to be able to fully manage the print server, without being Server Admins. And I want to achieve this before adding any printer so that permissions will eventually get applied on new printers. In theory this step will help me with automating a print server installation/configuration.

SetPrinter

I was losing any hope until I came across a technet forum’s thread where there was a discussion over “setprinter.exe“, a tool contained in the Windows Server 2003 Resource Kit. However the one that comes with it, doesn’t really work. After some more time, I was able to obtain the updated MS version of the tool which you can download from here: SetPrinter.Zip.
Note that I only have the 64bit version of it, so this won’t work on a 32bit system.

I will try and explain how we’re going to use this application before showing you a basic powershell script that will assign the permissions. The cool thing of this tool is that it can work remotely as well.

First of all, we will work with the pSecurityDescriptor. This contains the access type and depending on how we use setprinter.exe, we can grab and/or set the pSecurityDescriptor for the Print Server itself or for one of its printers; the last option would be useless as Powershell nowadays allows you to change printer’s security settings easily.

So, let’s run the following to get the current pSecurityDescriptor:

setprinter.exe -show \\PRINTSERVERNAME\ 3

Note that right after the print server you need to add a backslash and you need a space and the number 3 right after.

This is what you’ll get (these are the default permissions):

setprinter_show_1

 pSecurityDescriptor="O:BAG:BAD:(A;;DCRC;;;WD)(A;CIIO;SWRC;;;WD)(A;OIIO;RPWPSDRCWDWO;;;AC)(A;;DCRC;;;AC)(A;CIIO;SWRC;;;AC)(A;OIIO;RPWPSDRCWDWO;;;CO)(A;;CCDCSDRCWDWO;;;BA)(A;OICIIO;LCSWRPWPSDRCWDWO;;;BA)"

During the process when I was trying to understand this, I added a security group to the permissions of the server (manually, through the GUI) and gave it Full Control (this is the level of permissions I need for the group). After doing that, I re-ran the command above and I got this:

pSecurityDescriptor="O:BAG:BAD:(A;CIIO;LCSWSDRCWDWO;;;S-1-5-21-1578242438-287667933-3204412446-30897)(A;OIIO;RPWPSDRCWDWO;;;S-1-5-21-1578242438-287667933-3204412446-30897)(A;;CCDCSDRCWDWO;;;S-1-5-21-1578242438-287667933-3204412446-30897)(A;CIIO;SWRC;;;WD)(A;;DCRC;;;WD)(A;CIIO;SWRC;;;AC)(A;;DCRC;;;AC)(A;OIIO;RPWPSDRCWDWO;;;AC)(A;OIIO;RPWPSDRCWDWO;;;CO)(A;OICIIO;LCSWRPWPSDRCWDWO;;;BA)(A;;CCDCSDRCWDWO;;;BA)"

This might seem confusing, but ultimately it’s simple: Anything within ( ) contains the permissions and the user/group identification and for the group I just added, that’s its SID!
When I was testing this, I ended up adding an extra group manually (again, Full permissions) and re-ran the setprinter.exe command so that I could compare the 3 outputs and have a better understanding of what was happening.

Eventually I figured out that in order to assign full permissions to a user or a group, I need to add the following to the pSecurityDescriptor:

(A;CIIO;LCSWSDRCWDWO;;;MYSIDHERE)(A;OIIO;RPWPSDRCWDWO;;;MYSIDHERE)(A;;CCDCSDRCWDWO;;;MYSIDHERE)

Obviously, replace MYSIDHERE with the SID of the User or Group. That wasn’t so bad after all 🙂

Powershell

Time to have powershell to do some work now! See the script below:

<#
	Give Full Print Server rights over a User or a Group at the Server Level
	v1.0	Simone Corbisiero
#>

$ADobject = "MyADgroup" #The user or group to give permissions to
$PrintServer = "printserver" #The remote (can be local if ran locally) print servewr
$SetPrinterExe = "C:\Users\itdroplets\setprinter.exe" #The full path to the SetPrinter.exe file
$CurrentSecurityBackup = "C:\Users\itdroplets\$($PrintServer)_security.txt" #To be safe, I'll save the current security to a file

#Get the SID of the AD User or Group
	$SID = (Get-ADUser $ADobject | select-object SID).SID.Value
#Get the current security of the remote print server (& needed to run the exe)
	$CurrentSecurity = & $SetPrinterExe -show "\\$($PrintServer)\" 3
	
	#Backup $CurrentSecurity to a file ($CurrentSecurityBackup)
		$CurrentSecurity | Out-File $CurrentSecurityBackup
		

#Set the new security variable by appending the extra bit to the Current Security
	
	$NewSecurity = $CurrentSecurity[1].Replace(" ","").Replace("pSecurityDescriptor=","").Replace('"','') + "(A;CIIO;LCSWSDRCWDWO;;;$($SID))(A;OIIO;RPWPSDRCWDWO;;;$($SID))(A;;CCDCSDRCWDWO;;;$($SID))"
		<#
			Here's what the above line does:
				- $CurrentSecurity is an array and the first (position 0) entry is empty, so the script grabs just $CurrentSecurity[1]
				- The script remove all of the unnecessary ouput so that we keep just the permissions (this is done on all .Replace)
				- Take the above 2 steps and append the Full Permission for $SID
		#>
	
#Finally, assign the new permissions
$SetPrinterResult = & $SetPrinterExe "\\$($PrintServer)\" 3 pSecurityDescriptor=$NewSecurity
$SetPrinterResult[1] #The array in position 1 will contain the result of the above command

I’ve added a lot of comments to make sure everything is explained. Remember that the AD Powershell module is required for getting the SID (you could use psgetsid if you don’t want to use the AD Module) and also that you can run this remotely from your own machine as setprinter.exe will be able to grab/apply permissions remotely.

Let’s go quickly through it:

  • The script requires 4 variables.
    • The AD Object (either a user or a group)
    • The print server hostname or IP address
    • The full path to setprinter.exe
    • The full path to a file where to store the current pSecurityDescriptor (without any alteration).
  • Now the script gets the SID of the user or group you have stated in the AD Object variable.
  • It grabs the current security and then backs them up to a file
  • It builds the new security by removing some unnecessary output from the current security and by appending the Full Permissions based for the AD Object’s SID.
    • $CurrentSecurity is an array and the position 0 is empty. That’s why I use $CurrentSecurity[1].
    • The unnecessary output consist of spaces (there shouldn’t be any), quotes and the string pSecurityDescriptor=.
    • The append is done by using the Full Permission format together with the $SID variable.

So this is how to set permissions for a print server with Powershell.

Final Remarks

You might not be interested in assigning the full permissions, but it doesn’t matter. You can just grab the current permissions, then add a group or a user through the Print Management GUI and assign the permissions you want. Then, you want to grab again the permissions and see what’s changed: you will basically need just what’s been added which will contain the SID of the user/group.

You can then apply the permission set to the script provided above.

I hope this helps until Microsoft sort this out for good!

 

IT Droplets

IT Droplets