Guest User

Print Utils

a guest
Feb 23rd, 2012
629
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. PrinterUtils.ps1
  3. Version 0.1.0.0
  4. Functions for advanced printer management
  5.  
  6. Vadims Podans (c) 2008
  7. http://www.sysadmins.lv/
  8.  
  9. Updated 23/02/2012
  10. Translated from Russian by #######, ####### into French
  11. Translated from French by YellowOnline, ####### into English
  12. Reformatted by YellowOnline, #######
  13.  
  14. Referred from the following blogpost:
  15. http://yellowonline.tweakblogs.net/blog/7617/administration-of-print-servers-through-powershell.html
  16. #>
  17.  
  18. # The internal function that converts the number code of the  ACL into text.
  19. Function _PrinterUtils_Get-Code ($Write)
  20.     {
  21.     Switch ($Write.ReturnValue)
  22.         {
  23.         "0" {"Success"}
  24.         "2" {"Access Denied"}
  25.         "8" {"Unknown Error"}
  26.         "9" {"The user does not have adequate privileges to execute the method"}
  27.         "21" {"A parameter specified in the method call is invalid"}
  28.         Default {"Unknown error $($Write.ReturnValue)"}
  29.         }
  30.     }
  31.  
  32. # The internal function that forms the user object with the collection of permissions
  33. # and returns the object in the called function for later changes.
  34. Function _Create-SDObject ( $User, $AceType, $AccessMask)
  35.     {
  36.     # Transformation of access from numbers to text
  37.     $Masks = @{ManagePrinters = 983052; ManageDocuments = 983088; Print = 131080; TakeOwnership = 524288; ReadPermissions = 131072; ChangePermissions = 262144}
  38.     $Types = @{Allow = 0; Deny = 1}
  39.    
  40.     # Creation of the necessary object properties. For remote support the Computer-property
  41.     # has been added, who'll get from Get-Printer the value. Thus printer names are passed
  42.     # sequentially through the pipeline to where they are connected.
  43.     $AddInfo = New-Object System.Management.Automation.PSObject
  44.     $AddInfo | Add-Member NoteProperty Computer ([PSObject]$null)
  45.     $AddInfo | Add-Member NoteProperty Name ([PSObject]$null)
  46.     $AddInfo | Add-Member NoteProperty AccessMask ([uint32]$null)
  47.     $AddInfo | Add-Member NoteProperty AceFlags ([uint32]$null)
  48.     $AddInfo | Add-Member NoteProperty AceType ([uint32]$null)
  49.     $AddInfo | Add-Member NoteProperty User ([PSObject]$null)
  50.     $AddInfo | Add-Member NoteProperty Domain ([PSObject]$null)
  51.     $AddInfo | Add-Member NoteProperty SID ([PSObject]$null)
  52.    
  53.     # The object is filled with the data that was gotten through calling functions and their return values.
  54.     $AddInfo.Name = $Name
  55.     $AddInfo.User = $User
  56.     $AddInfo.SID = (New-Object Security.Principal.NTAccount $User).Translate([Security.Principal.SecurityIdentifier])
  57.     $AddInfo.AccessMask = $Masks.$AccessMask
  58.     $AddInfo.AceType = $Types.$AceType
  59.     If ($Masks.$AccessMask -EQ 983088)
  60.         {
  61.         $AddInfo.AceFlags = 9
  62.         }
  63.     $AddInfo
  64.     }
  65.  
  66. # The function to receive the list of ACLs of the printer(s).
  67. Function Get-Printer ($Computer = ".", $Name)
  68.     {
  69.     # If the variable $Name is empty, you'll receive a full list of local printers.
  70.     If ($Name)
  71.         {
  72.         $Printers = gwmi Win32_Printer -ComputerName $Computer -Filter "name = '$name'"
  73.         }
  74.     Else
  75.         {
  76.         $Printers = gwmi Win32_Printer -ComputerName $Computer -Filter "local = '$True'"
  77.         }
  78.    
  79.     # Output of a collection of ACL-listings.
  80.     $PrinterInfo = @()
  81.    
  82.     # Extraction of the ACL list for every object.
  83.     ForEach ($Printer in $Printers)
  84.         {
  85.         If ($Printer)
  86.             {
  87.             # We keep the security descriptor for every printer and every ACE (DACL) in the variable $SD.
  88.             $SD = $Printer.GetSecurityDescriptor()
  89.             $PrinterInfo += $SD.Descriptor.DACL | %{
  90.                                                     $_ | Select @{e = {$Printer.SystemName}; n = 'Computer'},
  91.                                                     @{e = {$Printer.name}; n = 'Name'},
  92.                                                     AccessMask,
  93.                                                     AceFlags,
  94.                                                     AceType,
  95.                                                     @{e = {$_.Trustee.Name}; n = 'User'},
  96.                                                     @{e = {$_.Trustee.Domain}; n = 'Domain'},
  97.                                                     @{e = {$_.Trustee.SIDString}; n = 'SID'}
  98.                                                     }
  99.             }
  100.         Else
  101.             {
  102.             Write-Warning "Specified printer not found!"
  103.             }
  104.     }
  105.    
  106.     # Output of the ACL information to the pipeline when quitting the function.
  107.     $PrinterInfo
  108. }
  109.  
  110. # The function for registering the printer ACL only accepts the information from the pipeline.
  111. Function Set-Printer()
  112.     {
  113.     # We get the ACE collection from an external source.
  114.     $PrinterInfo = @($Input)
  115.    
  116.     # Get more data based on the printer name and, later, cycle through it to treat ACLs of individual printers.
  117.     $PrinterInfo | Select-Object -Unique Computer, Name | %     {
  118.                                                                 $Computer = $_.Computer
  119.                                                                 $Name = $_.name
  120.                                                                 # Creating new objects of necessary classes.
  121.                                                                 $SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance()
  122.                                                                 $Ace = ([WMIClass] "Win32_Ace").CreateInstance()
  123.                                                                 $Trustee = ([WMIClass] "Win32_Trustee").CreateInstance()
  124.                                                                 # Now we share every ACE of the filtered ACL list of PrinterInfo and fill the SecurityDescriptor.
  125.                                                                 $PrinterInfo | ? {$_.Computer -EQ $Computer -And $_.Name -EQ $Name} | %  {
  126.                                                                                                                                             $SID = New-Object Security.Principal.Securityidentifier($_.SID)
  127.                                                                                                                                             [byte[]] $SIDArray = ,0 * $SID.BinaryLength
  128.                                                                                                                                             $SID.GetBinaryForm($SIDArray,0)
  129.                                                                                                                                             $Trustee.Name = $_.User
  130.                                                                                                                                             $Trustee.SID = $SIDArray
  131.                                                                                                                                             $Ace.AccessMask = $_.AccessMask
  132.                                                                                                                                             $Ace.AceType = $_.AceType
  133.                                                                                                                                             $Ace.AceFlags = $_.AceFlags
  134.                                                                                                                                             $Ace.Trustee = $Trustee
  135.                                                                                                                                             # Step by step ACE assembly in the security descriptor DACL.
  136.                                                                                                                                             $SD.DACL += @($Ace.PSObject.BaseObject)
  137.                                                                                                                                             # We flag SE_DACL_PRESENT, to precise that we only changed the ACL and nothing else.
  138.                                                                                                                                             $SD.ControlFlags = 0x0004
  139.                                                                                                                                             }
  140.        
  141.                                                                 # When the ACL for the current printer is complete, we pick the name of the current printer.
  142.                                                                 $Printer = Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name = '$Name'"
  143.                                                                
  144.                                                                 # We check if the proper printer for registering the ACL is found and the save is applied.
  145.                                                                 # If the registering does not succeed, the ACL is not saved.
  146.                                                                 If ($Printer)
  147.                                                                     {
  148.                                                                     $Write = $Printer.SetSecurityDescriptor($SD)
  149.                                                                     Write-Host "Processing current printer: $Name"
  150.                                                                     _PrinterUtils_Get-Code $Write
  151.                                                                     }
  152.                                                                 Else
  153.                                                                     {
  154.                                                                     Write-Warning "Skipping non-present printer: $Name"
  155.                                                                     }
  156.                                                                 }
  157.     }
  158.    
  159. # The function that applies permissions to the printer. When using this function, the current
  160. # ACL is cleared and will only contain a user or group with the ManagePrinters permissions.
  161. Function Set-PrinterPermission ($User)
  162.     {
  163.     # Reception of the data from the pipeline.
  164.     $PrinterInfo = @($Input)
  165.     $AddInfo = _Create-SDObject $User Allow ManagePrinters
  166.     # In this cycle every printer name passes and for each one of them, the user, who's in the
  167.     # arguments, registers itself with the suppression of the current ACE in the ACL.
  168.     # We can see this because no part of PrinterInfo is passed through the pipeline to the output.
  169.     ForEach ($Printer in ($PrinterInfo | Select-Object -Unique Computer, Name))
  170.         {
  171.         $AddInfo.Computer = $Printer.Computer
  172.         $AddInfo.Name = $Printer.Name
  173.         $AddInfo | Set-Printer
  174.         }
  175.     }
  176.  
  177. # The function that adds users or groups to the existing ACL of the printer.
  178. # The essential difference from the previous option is that ACE does not replace
  179. # permissions on printers but appends to it.
  180. Function Add-PrinterPermission ($User, $AceType, $AccessMask) {
  181.     $PrinterInfo = @($Input)
  182.     $AddInfo = _Create-SDObject $User $AceType $AccessMask
  183.     ForEach ($Printer in ($PrinterInfo | select -Unique Computer, Name))
  184.         {
  185.         $AddInfo.Name = $Printer.name
  186.         $AddInfo.Computer = $Printer.Computer
  187.         # With this line we cycle every printer on the list.
  188.         $PrinterInfoNew = $PrinterInfo | ?{$_.Name -EQ $Printer.Name}
  189.         # The ACE is added to the end of the list.
  190.         $PrinterInfoNew += $AddInfo
  191.         # And we save.
  192.         $PrinterInfoNew | Set-Printer
  193.         }
  194.     }
  195.  
  196. # The function for ACE suppression of the user or group.
  197. Function Remove-PrinterPermission ($User)
  198.     {
  199.     $Printers = @($Input)
  200.     # Simply take the ACL list that was sent through the pipeline and remove from there all ACE
  201.     # in whose arguments the user or group is specified.
  202.     $Printers | ? {$_.User -NE $User} | Set-Printer
  203. }
  204.  
  205. Function New-NetworkPrinter ($Computer, $Name)
  206.     {
  207.     ([wmiclass]'Win32_Printer').AddPrinterConnection("\\$Computer\$name")
  208.     }
  209.  
  210. Function Remove-NetworkPrinter ($Name)
  211.     {
  212.     If ($Name)
  213.         {
  214.         (Get-WmiObject Win32_Printer -Filter "sharename='$name'").Delete()
  215.         }
  216.     Else
  217.         {
  218.         (Get-WmiObject Win32_Printer -Filter "local = '$False'").Delete()
  219.         }
  220.     }
  221.  
  222. Function Set-DefaultPrinter ($Name)
  223.     {
  224.     If (!$Name)
  225.         {
  226.         Write-Warning "You must specify the printer name. Operation aborted!"
  227.         }
  228.     Else
  229.         {
  230.         If (Get-WmiObject Win32_Printer -Filter "name = '$Name'")
  231.             {
  232.             $SetDefault = (Get-WmiObject Win32_Printer -Filter "name = '$Name'").SetDefaultPrinter()
  233.             Switch ($SetDefault.ReturnValue)
  234.                 {
  235.                 "0" {Write-Host "The current default printer is $Name"}
  236.                 Default {Write-Warning "An error has occured."}
  237.                 }
  238.             }
  239.         Else
  240.             {
  241.             Write-Warning "The specified printer does not exist!"
  242.             }
  243.         }
  244.     }
  245.  
  246. Function Get-PrinterInfo ($Computer = ".", $Name)
  247.     {
  248.     # Here I offer to receive the complete set of properties or rather simplified information.
  249.     If ($Name)
  250.         {
  251.         Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name = '$Name'" | Select-Object *
  252.         }
  253.     Else
  254.         {
  255.         Get-WmiObject Win32_Printer -ComputerName $Computer
  256.         }
  257.     }
  258.  
  259. Function New-PrinterShare ($Computer = ".", $Name, $ShareName)
  260.     {
  261.     $Printer = Get-WmiObject Win32_Printer -ComputerName $Computer -Filter "name='$Name'"
  262.     If ($Printer)
  263.         {
  264.         $Printer.Shared = $True
  265.         $Printer.ShareName = $ShareName
  266.         $Printer.Put()
  267.         }
  268.     Else
  269.         {
  270.         Write-Warning "The specified printer does not exist!"
  271.         }
  272.     }
  273.  
  274. Function Remove-PrinterShare ($Computer = ".", $Name)
  275.     {
  276.     If ($Name)
  277.         {
  278.         $Filter = "name = '$Name'"
  279.         }
  280.     Else
  281.         {
  282.         $Filter = "local = '$False'"
  283.         }
  284.     Get-WmiObject Win32_Printer -ComputerName $Computer -Filter $Filter | %     {
  285.                                                                                 $_.Shared = $False
  286.                                                                                 $_.Put()
  287.                                                                                 }
  288.     }
Advertisement
Add Comment
Please, Sign In to add comment