Disabling Zebra printer Bidi when PowerShell refuses to help
I write deployment scripts for Zebra ZQ521 mobile printers running CPCL. Two of the standard config knobs — disable bidirectional communication and disable advanced printing features — are both required for these printers to behave on Windows, and both refuse to set cleanly via the PowerShell cmdlets you'd expect.
What was happening
Both ends of the same problem:
Set-PrinterPort -Name USB001 -EnableBidi $false
# Set-PrinterPort: A parameter cannot be found that matches parameter name 'EnableBidi'.
Set-PrintConfiguration -PrinterName 'ZDesigner ZQ521' -AdvancedPrintingFeatures $false
# Set-PrintConfiguration: A parameter cannot be found that matches parameter name
# 'AdvancedPrintingFeatures'.
These parameter names appear in plenty of Microsoft documentation. They aren't actually exposed on every Windows build I have to support. The bootstrap script kept logging warnings for both and the printers kept showing up bidi-enabled with default features on.
What I found
Both flags live in the registry as bits inside a single Attributes DWORD under HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers\<name>. The relevant bits:
0x00000400 PRINTER_ATTRIBUTE_WORK_OFFLINE
0x00000800 PRINTER_ATTRIBUTE_ENABLE_BIDI
0x00001000 PRINTER_ATTRIBUTE_RAW_ONLY
To disable bidi and force raw-only (which is what CPCL wants), clear the WORK_OFFLINE and ENABLE_BIDI bits and set RAW_ONLY. Then restart the spooler so the change takes.
The fix
$path = "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Printers\ZDesigner ZQ521"
$attr = (Get-ItemProperty -Path $path -Name Attributes).Attributes
$attr = $attr -band (-bnot 0x400) # clear WORK_OFFLINE
$attr = $attr -band (-bnot 0x800) # clear ENABLE_BIDI
$attr = $attr -bor 0x1000 # set RAW_ONLY
Set-ItemProperty -Path $path -Name Attributes -Value $attr
Restart-Service Spooler
Verification was the other thing I wanted to nail down — I don't trust a printer config change without proof. Reading the same Attributes value back after the spooler restart and decoding the bits is enough.
What I'd do differently
Two notes for next time. First: pnputil /add-driver silently partially-installs when the INF file's referenced supporting files are scattered across subdirectories. Flatten the driver package into one folder before calling pnputil. This bit me in an earlier version of the same script. Second: Add-PrinterDriver -InfPath for multi-driver INF packages already in the driver store fails the first time with "invalid value" but registers the driver anyway. Catch and ignore that one specific error rather than retrying. Both are the kind of Windows printing landmines you can only really learn by stepping on them.