Tag Archives: Printers

Scripting printer permissions

I will probably need to refer to this myself, but maybe someone else will find this useful.

Still working through some print queue management tasks, I needed to change permissions on a collection of printers. Yesterday, I broke down and did a bunch of repetitive work in the GUI, and noticed there were some inconsistencies in the permissions applied to a clients print queues. Today, I decided that I would fix them, but I didn’t want to use the GUI.

Although the Server 2012 Printer Management Set-Printer cmdlet can change the permissions through its -PermissionSDDL parameter, I haven’t found a workable (even if you call SDDL workable) way to do so on a Server 2008 system.

So I fell back to using PowerShell with Helge Klein’s SetACL command-line tool. I could also have used his COM version if I wanted to be really efficient. I use an array of arguments to the external command. See this Scripting Guy post for more info on calling external commands.

Here’s what I did:

# Retrieve a list of target printers
PS C:> $rlprinters = gwmi Win32_Printer -filter "Name like 'RL -%' OR Name like 'RL-%' "

# Construct a list of printer names in \\[hostname]\[sharename] format
PS C:> $printers = $rlprinters | % { '\\' + $_.SystemName + '\' + $_.ShareName }

# Create some variables to make the command construction simpler
PS C:> $setacl = 'C:\local\bin\SetACL.exe'
PS C:> $group = 'DOMAIN\RL-PrinterGroup'

# Iterate through the list of printers, calling SetACL for each
PS C:> foreach ( $p in $printers ) {
>> & $setacl '-on', $p , '-ot', 'prn', '-actn', 'ace','-ace',"n:$group;p:full"
}

It worked like a champ.

Note that I needed to run an elevated PowerShell session (run as Administrator) to be able to make the changes. Also, I tested this on a single printer before attempting to make bulk changes. I also have a nightly dump of my printer configuration. You get the idea.

You can include multiple actions for each invocation of SetACL, and there are a number of ways to collect output in case you need to follow-up on problems when applying changes to large collections of printers. Hopefully, this is enough to get you started,

Printer management with PowerShell

I find the printer management scripts included with Server 2008 bothersome. However, until we get to Server 2012, with its shiny new printer management cmdlets, I’ll keep trying to make do with what we have.

I was pleased to find an old post on the Printing Team’s blog about using the .Net System.Printing namespace with PowerShell to automate things. Some brief experimenting looks promising.

For the moment, in order to switch the printer driver version on about fifteen printers (all the same model), I used PowerShell and WMI, like this:

PS C:\> $printers = Get-WmiObject Win32_Printer -filter "Name like 'RL -%'"
PS C:\> $printers | sort Name | ft Name, DriverName -a
PS C:\> $printers | Where DriverName -eq 'HP Universal Printing PCL 6 (v5.3)' | % {
>> $_.DriverName = 'HP Universal Printing PCL 6 (v5.6.1)'
>> $_.Put()
>> }

This took quite a while to execute, but did work. What I need to do now is modify the permissions on each printQueue. I doubt I can leverage Get-ACL and Set-ACL for this.

Printer drivers and architectures with PowerShell

We have a number of 32-bit Windows 2008 print servers that we want to migrate to Windows Server 2012, for the printer management PowerShell cmdlets, among other things. I found a helpful blog post about using the PRINTBRM utility to migrate print queues, which mentions that you need to have both 32-bit and 64-bit drivers versions of all the drivers in order to migrate from a 32-bit to a 64-bit OS instance.

I wrote a little script to quickly show me which print drivers need a 64-bit version installed. It can take a moment to run if you have many printers configured.

UPDATE: I made a couple changes, most notably that the count of printers using a driver is now optional (since it can take a while on a system with lots of printers).

<#
.SYNOPSIS
Lists printer drivers,  whether 32- and 64-bit versions are installed,
and how many printers are using each driver.


.PARAMETER Printers
Includes a counter of the printers using each printer driver. On a system
with many installed printers, this can take a a little time, so this 
functionality is optional.


.EXAMPLE
PS C:\local\scripts> .\Get-PrinterDriverArchitecture.ps1 | format-table -auto

Name                                       x86   x64
----                                       ---   ---
Brother HL-5250DN                         True False
Epson LQ-570+ ESC/P 2                     True False
HP Business Inkjet 2230/2280              True False
HP Business Inkjet 2250 (PCL5C)           True  True
HP Business Inkjet 2800 PCL 5             True False

This command lists the installed printer drivers, and whether 32-bit (x86)
or 64-bit (x64) drivers are available.


.EXAMPLE
PS C:\local\scripts> .\Get-PrinterDriverArchitecture.ps1 | where x64 -eq $false | ft -a

Name                                      x86   x64
----                                      ---   ---
Brother HL-5250DN                        True False
Epson LQ-570+ ESC/P 2                    True False
HP Business Inkjet 2230/2280             True False
HP Business Inkjet 2800 PCL 5            True False

This command uses the Where[-Object] cmdlet to filter out those drivers that
have a 64-bit driver installed.


.EXAMPLE
PS C:\local\scripts> .\Get-PrinterDriverArchitecture.ps1 -Printers | ft -a
Enumerating printers:
    WID - Kyocera TASKalfa 3050ci KX
    WC - Kyocera TASKalfa 300ci KX
    UFS - Canon iR-ADV C5035
    ...

Name                                       x86   x64 Printers
----                                       ---   --- --------
Brother HL-5250DN                         True False        5
Epson LQ-570+ ESC/P 2                     True False        0
HP Business Inkjet 2230/2280              True False        1
HP Business Inkjet 2250 (PCL5C)           True  True        0
HP Business Inkjet 2800 PCL 5             True False        1

This command includes the -Printers switch parameter to add a count of
the printers using each driver. Enumerating the printers can take a while
if there are lots of them installed, so this behavior is optional.


.NOTES
 - Author    : Geoffrey.Duke@uvm.edu
 - Mod. Date : May 28, 2013
#>

param( [switch] $printers )

$wmi_drivers = get-wmiobject Win32_PrinterDriver -Property Name
$drivers = @{}
foreach ($driver in $wmi_drivers) {
    # Isolate the driver name and platform
    $name,$null,$platform = $driver.Name -split ','

    if ( -not $drivers[$name] ) {
        switch ( $platform ) {
            'Windows NT x86' { $drivers[$name] = [ordered]@{ 
                                 'Name'=$name; 'x86'=$true; 'x64'=$false }; break }
            'Windows x64'    { $drivers[$name] = [ordered]@{ 
                                 'Name'=$name; 'x86'=$false; 'x64'=$true }; break }
             default         { write-warning "Unexpect platform $platform on driver $name"}
        }
    }
    else {
        switch ( $platform ) {
            'Windows x64'    { $drivers[$name]['x64'] = $true; break }
            'Windows NT x86' { $drivers[$name]['x86'] = $true; break }
             default         { write-warning "Unexpect platform $platform on driver $name"}
        }
    }
}

if ( $printers ) {
    # Initialize all printer counts
    $drivers.keys | foreach { $drivers[$_]['Printers'] = 0 }
    # Add a count of the number of printers using each driver
    # With some progress info
    write-host 'Enumerating printers:'
    $count = 0
    get-wmiobject Win32_Printer -Property Name,DriverName | foreach { 
        write-host "    $($_.Name)"  -foreground darkgray
        $drivers[$_.DriverName]['Printers']++ 
        $count++
    }

    write-host "Retrieved $count printers"
}

# Output collection of objects
$drivers.keys | sort | foreach { New-Object PSObject -Property $drivers[$_] } 
 

I hope this is useful to others.

Use it up – Brother HL-3070CW Toner

Use it up, Wear it out, Make it do, or Do without.

There are some things that we can’t really do without. But good old Yankee thrift pains me every time I have to replace printer consumables.

I have a Brother HL-3070CW color laser printer at home, which I really like. I selected it specifically because it has an optional straight-through printing path, to reduce curl on heavier stock.

I’ve also discovered that it reports being out of toner based on page count or something, rather than a measure of actual toner remaining. I found two ways to make sure I get the most from my toner cartridges.

First, I found that there’s a menu for resetting the state of toner in the printer.

  1. Open the top cover
  2. Press the Cancel and Secure Print buttons together to bring up the toner menu
  3. Use the + and – buttons to select the toner cartridge to reset, and press OK (twice). Each color (CMYK) has two options, one each for standard and high capacity cartridges.
  4. When finished, closed the top cover.

In addition, it’s very easy to reset the physical switch on the toner cartridge, as shown in this short video:

Very easy to do.

(Both procedures from http://www.fixyourownprinter.com/forums/laser/39806 )

I’ve used the menu reset option several times, and I haven’t seen any problems with toner coverage on my printed pages.

When I do need to replace the cartridge, I have found the best prices on Amazon and NewEgg.

Monday – 2009-09-28

Today’s issues:

  • Backup issues
  • Shared folder quotas
  • Printer configurations
  • Data execution protection

I created a Server 2008 x64 guest for managing 64-bit drivers on our shared printers. It works much better than trying to use Printer Management MMC in RSAT on Windows 7.

One hiccup I ran into while install the Ricoh PCL6 Driver for Universal Print was that it was missing a file. Fortunately, I had also download and extracted the non-universal PCL6 drivers and the file was present in the drivers for the corresponding platforms (x86, x64).

Looking at adding a –WhatIf switch parameter to my SharePoint Backup powershell script. Useful info at Negating PowerShell switch parameters.

Now wrestling with Task Scheduler and PowerShell invocation syntax.

backups – Bad and Good

We’ve been working with our backup vendor to address some shortcomings of their product as it relates to Windows 2008 system recover. This was precipitated by a failure of a portion of our virtual infrastructure, which lead to corruption of several hosts’ virtual disk files.

We managed to rebuild one failed host from bare (virtual) metal, because EMC Networker could not recover the system from backups. For Server 2008 systems, they require backups made with client 7.5.1 and restored with 7.5.1 and you have to enable/install any server role that was present on the original system before performing the restore.

We’ve been working on other ways to make sure we can recover from a system failure. Greg has successfully scripted using server 2008’s printer management scripts to dump printer info to files. I’ve been working on scripted backup of SharePoint Site collections. I got some help from Microsoft in determining the correct permissions needed for a service account to perform STSADM backup operations, which has been a thorny issue. ( see KB896148 )

Worklog – Town Meeting Day

Need to expand storage on WinDB; Kent is working on the FC storage.

Documentation regarding printer installation. Added a How-To wiki library to the AD Sharepoint Site, and added instruction for installing a printer by Finding a printer in the directory.

Disks on WinDB are successfully expanded.

Expanded the printer documentation.

Quite a bit of work confirming the functionality of NTFRS for SYSVOL: correlated GP GUIDs and Names; looked into a couple of orphaned policy folders; looked through deletedObjects container. Couldn’t find any policies pointing to those orphaned GUIDs.

Fixed Samsung printer duplex issue.

Registered for Mastering the Maze. I note that Greg is doing a couple of presentations, and Carol, Ben, and Henrietta are also covering technology topics.

Began review of Certificate Services migration process: