Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- PrinterUtils.ps1
- Version 0.1.0.0
- Functions for advanced printer management
- Vadims Podans (c) 2008
- http://www.sysadmins.lv/
- Updated 23/02/2012
- Translated from Russian by #######, ####### into French
- Translated from French by YellowOnline, ####### into English
- Reformatted by YellowOnline, #######
- Referred from the following blogpost:
- http://yellowonline.tweakblogs.net/blog/7617/administration-of-print-servers-through-powershell.html
- #>
- # The internal function that converts the number code of the ACL into text.
- Function _PrinterUtils_Get-Code ($Write)
- {
- Switch ($Write.ReturnValue)
- {
- "0" {"Success"}
- "2" {"Access Denied"}
- "8" {"Unknown Error"}
- "9" {"The user does not have adequate privileges to execute the method"}
- "21" {"A parameter specified in the method call is invalid"}
- Default {"Unknown error $($Write.ReturnValue)"}
- }
- }
- # The internal function that forms the user object with the collection of permissions
- # and returns the object in the called function for later changes.
- Function _Create-SDObject ( $User, $AceType, $AccessMask)
- {
- # Transformation of access from numbers to text
- $Masks = @{ManagePrinters = 983052; ManageDocuments = 983088; Print = 131080; TakeOwnership = 524288; ReadPermissions = 131072; ChangePermissions = 262144}
- $Types = @{Allow = 0; Deny = 1}
- # Creation of the necessary object properties. For remote support the Computer-property
- # has been added, who'll get from Get-Printer the value. Thus printer names are passed
- # sequentially through the pipeline to where they are connected.
- $AddInfo = New-Object System.Management.Automation.PSObject
- $AddInfo | Add-Member NoteProperty Computer ([PSObject]$null)
- $AddInfo | Add-Member NoteProperty Name ([PSObject]$null)
- $AddInfo | Add-Member NoteProperty AccessMask ([uint32]$null)
- $AddInfo | Add-Member NoteProperty AceFlags ([uint32]$null)
- $AddInfo | Add-Member NoteProperty AceType ([uint32]$null)
- $AddInfo | Add-Member NoteProperty User ([PSObject]$null)
- $AddInfo | Add-Member NoteProperty Domain ([PSObject]$null)
- $AddInfo | Add-Member NoteProperty SID ([PSObject]$null)
- # The object is filled with the data that was gotten through calling functions and their return values.
- $AddInfo.Name = $Name
- $AddInfo.User = $User
- $AddInfo.SID = (New-Object Security.Principal.NTAccount $User).Translate([Security.Principal.SecurityIdentifier])
- $AddInfo.AccessMask = $Masks.$AccessMask
- $AddInfo.AceType = $Types.$AceType
- If ($Masks.$AccessMask -EQ 983088)
- {
- $AddInfo.AceFlags = 9
- }
- $AddInfo
- }
- # The function to receive the list of ACLs of the printer(s).
- Function Get-Printer ($Computer = ".", $Name)
- {
- # If the variable $Name is empty, you'll receive a full list of local printers.
- If ($Name)
- {
- $Printers = gwmi Win32_Printer -ComputerName $Computer -Filter "name = '$name'"
- }
- Else
- {
- $Printers = gwmi Win32_Printer -ComputerName $Computer -Filter "local = '$True'"
- }
- # Output of a collection of ACL-listings.
- $PrinterInfo = @()
- # Extraction of the ACL list for every object.
- ForEach ($Printer in $Printers)
- {
- If ($Printer)
- {
- # We keep the security descriptor for every printer and every ACE (DACL) in the variable $SD.
- $SD = $Printer.GetSecurityDescriptor()
- $PrinterInfo += $SD.Descriptor.DACL | %{
- $_ | Select @{e = {$Printer.SystemName}; n = 'Computer'},
- @{e = {$Printer.name}; n = 'Name'},
- AccessMask,
- AceFlags,
- AceType,
- @{e = {$_.Trustee.Name}; n = 'User'},
- @{e = {$_.Trustee.Domain}; n = 'Domain'},
- @{e = {$_.Trustee.SIDString}; n = 'SID'}
- }
- }
- Else
- {
- Write-Warning "Specified printer not found!"
- }
- }
- # Output of the ACL information to the pipeline when quitting the function.
- $PrinterInfo
- }
- # The function for registering the printer ACL only accepts the information from the pipeline.
- Function Set-Printer()
- {
- # We get the ACE collection from an external source.
- $PrinterInfo = @($Input)
- # Get more data based on the printer name and, later, cycle through it to treat ACLs of individual printers.
- $PrinterInfo | Select-Object -Unique Computer, Name | % {
- $Computer = $_.Computer
- $Name = $_.name
- # Creating new objects of necessary classes.
- $SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
- $Ace = ([WMIClass] "Win32_Ace").CreateInstance()
- $Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
- # Now we share every ACE of the filtered ACL list of PrinterInfo and fill the SecurityDescriptor.
- $PrinterInfo | ? {$_.Computer -EQ $Computer -And $_.Name -EQ $Name} | % {
- $SID = New-Object Security.Principal.Securityidentifier($_.SID)
- [byte[]] $SIDArray = ,0 * $SID.BinaryLength
- $SID.GetBinaryForm($SIDArray,0)
- $Trustee.Name = $_.User
- $Trustee.SID = $SIDArray
- $Ace.AccessMask = $_.AccessMask
- $Ace.AceType = $_.AceType
- $Ace.AceFlags = $_.AceFlags
- $Ace.Trustee = $Trustee
- # Step by step ACE assembly in the security descriptor DACL.
- $SD.DACL += @($Ace.PSObject.BaseObject)
- # We flag SE_DACL_PRESENT, to precise that we only changed the ACL and nothing else.
- $SD.ControlFlags = 0x0004
- }
- # When the ACL for the current printer is complete, we pick the name of the current printer.
- $Printer = Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name = '$Name'"
- # We check if the proper printer for registering the ACL is found and the save is applied.
- # If the registering does not succeed, the ACL is not saved.
- If ($Printer)
- {
- $Write = $Printer.SetSecurityDescriptor($SD)
- Write-Host "Processing current printer: $Name"
- _PrinterUtils_Get-Code $Write
- }
- Else
- {
- Write-Warning "Skipping non-present printer: $Name"
- }
- }
- }
- # The function that applies permissions to the printer. When using this function, the current
- # ACL is cleared and will only contain a user or group with the ManagePrinters permissions.
- Function Set-PrinterPermission ($User)
- {
- # Reception of the data from the pipeline.
- $PrinterInfo = @($Input)
- $AddInfo = _Create-SDObject $User Allow ManagePrinters
- # In this cycle every printer name passes and for each one of them, the user, who's in the
- # arguments, registers itself with the suppression of the current ACE in the ACL.
- # We can see this because no part of PrinterInfo is passed through the pipeline to the output.
- ForEach ($Printer in ($PrinterInfo | Select-Object -Unique Computer, Name))
- {
- $AddInfo.Computer = $Printer.Computer
- $AddInfo.Name = $Printer.Name
- $AddInfo | Set-Printer
- }
- }
- # The function that adds users or groups to the existing ACL of the printer.
- # The essential difference from the previous option is that ACE does not replace
- # permissions on printers but appends to it.
- Function Add-PrinterPermission ($User, $AceType, $AccessMask) {
- $PrinterInfo = @($Input)
- $AddInfo = _Create-SDObject $User $AceType $AccessMask
- ForEach ($Printer in ($PrinterInfo | select -Unique Computer, Name))
- {
- $AddInfo.Name = $Printer.name
- $AddInfo.Computer = $Printer.Computer
- # With this line we cycle every printer on the list.
- $PrinterInfoNew = $PrinterInfo | ?{$_.Name -EQ $Printer.Name}
- # The ACE is added to the end of the list.
- $PrinterInfoNew += $AddInfo
- # And we save.
- $PrinterInfoNew | Set-Printer
- }
- }
- # The function for ACE suppression of the user or group.
- Function Remove-PrinterPermission ($User)
- {
- $Printers = @($Input)
- # Simply take the ACL list that was sent through the pipeline and remove from there all ACE
- # in whose arguments the user or group is specified.
- $Printers | ? {$_.User -NE $User} | Set-Printer
- }
- Function New-NetworkPrinter ($Computer, $Name)
- {
- ([wmiclass]'Win32_Printer').AddPrinterConnection("\\$Computer\$name")
- }
- Function Remove-NetworkPrinter ($Name)
- {
- If ($Name)
- {
- (Get-WmiObject Win32_Printer -Filter "sharename='$name'").Delete()
- }
- Else
- {
- (Get-WmiObject Win32_Printer -Filter "local = '$False'").Delete()
- }
- }
- Function Set-DefaultPrinter ($Name)
- {
- If (!$Name)
- {
- Write-Warning "You must specify the printer name. Operation aborted!"
- }
- Else
- {
- If (Get-WmiObject Win32_Printer -Filter "name = '$Name'")
- {
- $SetDefault = (Get-WmiObject Win32_Printer -Filter "name = '$Name'").SetDefaultPrinter()
- Switch ($SetDefault.ReturnValue)
- {
- "0" {Write-Host "The current default printer is $Name"}
- Default {Write-Warning "An error has occured."}
- }
- }
- Else
- {
- Write-Warning "The specified printer does not exist!"
- }
- }
- }
- Function Get-PrinterInfo ($Computer = ".", $Name)
- {
- # Here I offer to receive the complete set of properties or rather simplified information.
- If ($Name)
- {
- Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name = '$Name'" | Select-Object *
- }
- Else
- {
- Get-WmiObject Win32_Printer -ComputerName $Computer
- }
- }
- Function New-PrinterShare ($Computer = ".", $Name, $ShareName)
- {
- $Printer = Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name='$Name'"
- If ($Printer)
- {
- $Printer.Shared = $True
- $Printer.ShareName = $ShareName
- $Printer.Put()
- }
- Else
- {
- Write-Warning "The specified printer does not exist!"
- }
- }
- Function Remove-PrinterShare ($Computer = ".", $Name)
- {
- If ($Name)
- {
- $Filter = "name = '$Name'"
- }
- Else
- {
- $Filter = "local = '$False'"
- }
- Get-WmiObject Win32_Printer -ComputerName $Computer -Filter $Filter | % {
- $_.Shared = $False
- $_.Put()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment