On my print server, the printer GUI contains the List in the Directory check box, which configures whether or not each printer is published in Active Directory (AD). Is it possible to read and change the value of this check box with a script?
The resource kits for Windows 2000 and later provide a DLL named PrnAdmin.dll that provides a set of printer administration objects. You can use these objects to change the value of the List in the Directory check box, but you first have to install the DLL on the computer running the script.
To get PrnAdmin.dll, download the Windows Server 2003 Resource Kit Tools package (rktools.exe), which is freely available on the Microsoft Web site at http://www.microsoft.com/windowsserver2003/techinfo/reskit/tools/default.mspx. After installing the package, open a command-shell window and register the PrnAdmin.dll file using the regsvr32 command
where path is the path to the Windows Server 2003 Resource Kit Tools installation folder.
After you register the DLL, you can use its objects in a script. According to the documentation in PrnAdmin.doc, the Printer object has a Published property, which corresponds to the List in the Directory check box in the GUI. You can select or clear the List in the Directory check box by setting the Published property to True or False, respectively.
Unfortunately, the Published property is write-only, so you can't read it to determine its current value. However, the Attributes property of the Printer object contains a numeric value called a bit map.
A bit map is an array of bits in which each bit represents an individual binary value. You can determine the value of a bit in the array by performing a bitwise AND operation using the bitmap array's value and a mask value representing the bit of interest. The Published value is the 14th bit in the array (i.e., the decimal value 8192). When the bit is 0, the Published property isn't set (i.e., isn't published). When the bit is 1, the Published property is set (i.e., is published).
The CheckPrinterValue.vbs script, which Listing 3 shows, uses the Attributes property to enumerate the shared printers on a computer and reports whether each printer is published. As callout A in Listing 3 shows, the script creates the PrintMaster object, which provides the Printers method. This method returns a collection of Printer objects that you can enumerate with a For Each...Next loop. Inside this loop, the script uses the IsBitSet function to determine whether each printer is shared. (The Shared property is the fourth bit in the array, which corresponds to the decimal value 8.)
The IsBitSet function, which callout B in Listing 3 shows, determines the state of a particular bit in a bit array. It performs a bitwise AND operation using the bit array and the mask value. (In the two examples here, the mask value is ATTR_SHARED, or 8, and ATTR_PUBLISHED, or 8192.) As I just mentioned, the script first uses IsBitSet to determine whether the Shared bit is set (i.e., the value is nonzero). When the Shared bit is set, the script uses the IsBitSet function again to determine whether the Published bit is set.
After you use CheckPrinterValue.vbs to determine which printers are published, you can use the ChangePrinterValue.vbs script, which Listing 4 shows, to change a printer's published status. As callout A in Listing 4 shows, the script uses the PrintMaster object's PrinterGet method to retrieve the printer name specified on the command line. The script then sets the Published property to True and uses the PrintMaster object's PrinterSet method to save the change.
The Attributes property of the Printer object corresponds to the Attributes property in the WMI Win32_Printer class. Thus, you can adapt CheckPrinterValue.vbs and ChangePrinterValue.vbs to check and change other printer properties. To learn about the other bit mask values you can check and change, go to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/win32_printer.asp.