// St Mary's Primary School Bairnsdale // Printer management script // // If printers are specified on the command line, just connect to them. // Otherwise disconnect existing remote and fax printers, connect to those // listed in printerN environment variables, and set the default printer // to the first reachable one specified by a printerN variable. // // Stephen Thomas // Last updated 1-Feb-2012 // // This is free software. Do whatever you like with it except // hold me accountable for any grief it causes you. Constructive // criticism always welcome. // Everybody should always have access to at least the following printers. extra = ['CutePDF Writer', '\\\\curricserver.curric.local\\Library copier']; // Get access to some useful Windows facilities. wmi = GetObject('winmgmts://./root/CIMV2'); wsh = new ActiveXObject('WScript.Shell'); fso = new ActiveXObject('Scripting.FileSystemObject'); // Issue diagnostic spew when run from cscript. cscript = fso.GetFile(WScript.Fullname).Name.toLowerCase() == "cscript.exe"; function Log(message) { if (cscript) WScript.Echo(message); } // Windows makes extensive use of collections, which the standard jscript "for" // statement won't enumerate. This helper function makes walking these much // less clumsy. function forEach(collection, func) { for (var e = new Enumerator(collection); !e.atEnd(); e.moveNext()) { var result = func(e.item()); if (result) return result; } } // Printer management functions based on those found in %windir%\system32\prnmngr.vbs function RemovePrinter(printer) { Log('Remove: ' + printer); try { printer = wmi.Get("Win32_Printer.DeviceID='" + printer + "'"); if (printer) printer.Delete_(); } catch (ex) { Log(ex.message); } } function ConnectPrinter(printer) { Log('Connect: ' + printer); try { printers = wmi.Get("Win32_Printer"); if (printers) printers.AddPrinterConnection(printer); } catch (ex) { Log(ex.message); } } function SetDefaultPrinter(printer) { Log('Choose: ' + printer); try { printer = wmi.Get("Win32_Printer.DeviceID='" + printer + "'"); if (printer) printer.SetDefaultPrinter(); } catch (ex) { Log(ex.message); } } function GetDefaultPrinter() { try { var defaultPrinters = wmi.ExecQuery('SELECT Name, Default FROM Win32_Printer WHERE default=true'); var result = forEach (defaultPrinters, function (printer) { return printer.Name; }); if (result) { Log('Chosen: ' + result); return result; } } catch (ex) { Log(ex.message); } return ""; } // Mainline starts here. have = {}; want = {}; prefer = []; // Make a list of the remote printers specified in the command line. hasArgs = false; forEach (WScript.Arguments, function (arg) { hasArgs = true; if (arg.match(/^\\\\/)) { want[arg.toLowerCase()] = arg; } }); // If none were specified on the command line, we want to make connections // conform to those specified in printerN environment variables. if (!hasArgs) { // Collect the printers we want from environment variables. // Remember wanted connections and order of preference. forEach (wsh.Environment('PROCESS'), function (envVar) { if (envVar.match(/^printer/i)) { printer = envVar.replace(/^[^=]+=/, '').replace(/"/g, ''); if (printer.match(/^\\\\/)) { want[printer.toLowerCase()] = printer; } prefer.push(printer); } }); // Add printers from extra[] to the list as well. for (i in extra) { printer = extra[i]; if (printer.match(/^\\\\/)) { want[printer.toLowerCase()] = printer; } prefer.push(printer); } // Make a list of existing printer connections. We don't want // fax printers on school workstations; lump them in with the // remote connections so they can get deleted as well. query = 'SELECT Name FROM Win32_Printer WHERE Local=false OR Name Like "%Fax%"' try { forEach (wmi.ExecQuery(query), function (printer) { have[printer.Name.toLowerCase()] = printer.Name; }); } catch (ex) { Log(ex.message); } Log('\r\nHave:'); for (printer in have) { Log(have[printer]); } } Log('\r\nWant:'); for (printer in want) { Log(want[printer]); } Log('\r\nPrefer:'); for (i in prefer) { Log(prefer[i]); } Log(); // Delete printers we have but no longer want. for (printer in have) { if (!want.hasOwnProperty(printer)) { RemovePrinter(have[printer]); } } // Establish connections we want but don't already have. for (printer in want) { if (!have.hasOwnProperty(printer)) { ConnectPrinter(want[printer]); } } // Set the default printer to the first one reachable. defaultPrinter = GetDefaultPrinter(); for (i in prefer) { printer = prefer[i]; if (defaultPrinter.toLowerCase() == printer.toLowerCase()) { break; } SetDefaultPrinter(printer); defaultPrinter = GetDefaultPrinter(); if (defaultPrinter.toLowerCase() == printer.toLowerCase()) { break; } }