Problem: given a Windows server with a number of installed printers, publish them to DNS so that they can be used from macos/iOS (et al).
No free software exists AFAIK to automate this trivial but annoying task.
An AWK script can of course process a list of printers into a batch of dnscmd commands.
Usual disclaimers apply: done in 30 minutes, trivial, works with en_us versions only, and so on. I’m not liable for anything, from the script no working to destroying your AD. UAYOR, YMMV, etc.
In short: for a mac/iOS to list printer as Bonjour printers you need broadcast, mDNS or DNS-SD. Which means:
- five PTR records that “enable” the zone for DNS-SD
- for every printer, three records in the _printer._tcp.zone.tld subzone:
- a PTR for the zone that says “there’s a printer with this name”
- a SRV for the printer’s name that says “and this is its hostname”
- a TXT for the printer’s name that explains the printer’s capabilities, queue name, and so on.
The printer can be shared as IPP, IPPS, IPP-TLS and, most important, LPD. Windows has had LPD service available since Windows 2000, on server and workstation, and thus that’s simpler than using IPP. My script, having been conceived with Windows in mind, uses LPD. Of course you need to install LPD service and the printers must have been shared. I won’t show you how to do that – it’s trivial and if you need to know how to do it you can google it – or change job altogether.
The script won’t “just work” I guess: the tricky part is the “ty” line in the TXT record, which tells the mac which driver to use. I’m just using the Windows driver’s name, YMMV but I’m positive you’ll have to edit the TXT records if you want the mac to install the printer automatically (and not asking you for the driver to use).
Full specifications on how to fill the TXT record with significant data can be found on Apple’s website. Google for “bonjour priniting specification” site:developer.apple.com
NOTE NOTE NOTE NOTE
I might have once again reinvented the wheel. Square. And lost my ability to properly google for stuff. So if you know of a better way to do this, free (no pesky unmantained $29 software to install on a little innocent MS DC) please come forward and tell your story.
Let’s get it on:
- Get the list of printers from the server:
cscript prnmngr.vbs -l -s FQDN.domain.tld > %temp%\prtlist.txt
(must be run from the folder where the VBS is; in 2008R2 %windir%\system32\printing_admin_scripts\xx-XX – like en-US)
- Process the list with AWK. IMPORTANT: if you’re not using AWK on Windows but are moving the list and the script back and forth from/to a *nix machine, you MUST take care of CR/LF conversion.
./prnmngr2dnscmd.awk prtlist.txt > dnssd.cmd
- Run the script and hope for the best.
The script itself. You need to CHANGE domain.tld with your zone FQDN. Again, I assume you’re not a dummy but a decently experienced sysadmin.
split("b db dr lb t", sr);
for (rr in sr) printf "dnscmd . /RecordAdd %s %s._dns-sd._udp PTR %s\n", dom, sr[rr], dom;
getline name; gsub("Printer name ", "", name);
n=name; gsub(" ", "_", n);
getline rp; gsub("Share name ", "", rp);
getline ty; gsub("Driver name ", "", ty);
getline note; gsub("Location ", "", note);
product="(" ty ")";
printf "dnscmd . /RecordAdd %s _printer._tcp PTR %s._printer._tcp.%s\n", dom, n, dom;
printf "dnscmd . /RecordAdd %s %s._printer._tcp SRV 0 0 515 %s.%s\n", dom, n, srv, dom;
printf "dnscmd . /RecordAdd %s %s._printer._tcp TXT \"txtvers=1\" \"qtotal=1\" \"rp=%s\" \"ty=%s\" \"note=%s\" \"priority=0\" \"product=%s\" \"printer-state=3\" \"printer-type=0x809056\" \"pdl=application/octet-stream,application/pdf,application/postscript,image/jpeg,image/png\"\n", dom, n, rp, ty, note, product;