Downloads
97090.zip

Executive Summary:

The SubInACL utility, which you can find in the Microsoft Windows Server 2003 Resource Kit, is a versatile tool that lets you view, edit, remove, add, and migrate access control entries (ACEs) for files, directories, file shares, printer shares, and more. Because SubInACL is a command-line tool, you can script its use. Here's an example of how you can write a script that uses SubInACL to change permissions in a print cluster.

Q: I need to change the permissions for the printers in my company's print cluster. Our print cluster consists of two Window Server 2003 servers connected to a NAS device that provides shared storage to both servers. In the cluster, there are 10 logical resource groups, with 30 to 40 printers in each logical resource group. I'd like to replace the built-in Power Users group that Windows 2003 assigns by default to each printer's ACL with a group that has Manage Printer and Manage Document rights. (Some users who shouldn't have permission to manage the printers are embedded into the Power Users group by Group Policy Objects—GPOs—applied to the server, but we'd rather remove Power Users from the printers than tweak the GPOs at this time.) With 300 to 400 printers, changing the permissions manually on each printer would be too cumbersome. Do you have any idea on how this can be scripted?

—Scott

A: The easiest way to script the permission changes is to use the Microsoft Windows Server 2003 Resource Kit's SubInACL (subinacl.exe) utility. This command-line tool lets you view, edit, remove, add, and migrate access control entries (ACEs) for files, directories, file shares, printer shares, and more . As PrinterPerms.cmd in Listing 1 shows, you can use SubInACL to remove the ACEs for the Power Users group and add the ACEs for the group that contains the desired Manage Printer and Manage Document permissions.

The command syntax to run PrinterPerms.cmd is

printerperms.cmd
 servername
 group_to_remove
 group_to_add

where servername is the name of the target cluster server, group_to_remove is the name of the group for which you want to remove the ACEs, and group_to_add is the name of the group for which you want to add the ACEs. For example, if you want to remove the ACEs for the Power Users group and add the ACEs for MYDOMAIN\Printer Admins group to the printers in the logical resource group on a server named ClusterA, you'd run the command

printerperms.cmd
 ClusterA
 "Power Users"
 "MYDOMAIN\Printer Admins"

As this example shows, you must enclose in quotes any group names that contain embedded spaces. In addition, although the command wraps here, you would enter it all on one line in the command-shell window.

PrinterPerms.cmd starts by retrieving the parameters you entered on the command line. If the script finds fewer than three parameters or more than three parameters, it displays the syntax of the launch command, then exits. When the script finds exactly three parameters, it assigns the first parameter to the servername variable, the second parameter to the revokegroup variable, and the third parameter to the addgroup variable. Later in the script, you might notice that these variable names are enclosed in percent signs (e.g., %servername%). In .cmd and .bat scripts, you must enclose variable names in percent signs when you want to retrieve or use the variables' values.

Next, PrinterPerms.cmd uses the Net View command to retrieve the shared resources on the server specified in the %servername% variable, as callout A in Listing 1 shows. Because a server often hosts different types of shared resources, the script redirects, or pipes, the list that Net View returns to the Find command, which searches the list for lines that contain the string "Print". Note that when you use the pipe symbol (|) inside a For command, you must use the caret (^) to flag (i.e., escape) the pipe symbol.

For each instance of "Print" found, the script assigns the name of the printer in that line to the %%i iterator variable and runs the Call command. Unlike regular variables, you don't need to enclose iterator variables in percent signs. An iterator variable is a special type of variable that serves as a temporary container for data captured in a For command. To learn more about iterator variables, see "Shell Scripting 101, Lesson 8" (http://www.windowsitpro.com/Article/ArticleID/21984/21984.html).

The Call command is quite useful in Windows shell scripting. It lets you run another script or executable in separate command-shell window. In this case, the command

Call :updateperms
 \\%servername%\%%i

calls the code in callout B, which will run SubInACL, into action. Because SubInACL needs the pathname to the printer to modify, the Call command also passes in the \\%servername%\%%i parameter to the code in callout B.

After assigning the \\%servername%\%%i parameter to the printer variable, PrinterPerms.cmd launches SubInACL with the command

Subinacl /printer %printer%
 /revoke=%revokegroup%

The /revoke option tells SubInACL to remove the ACEs for the group specified in the % revokegroup% variable from the shared printer (/printer) specified in the %printer% variable. To add the new permissions, the script runs the command

Subinacl /printer %printer%
 /grant=%addgroup%=F

The /grant==%addgroup%=F option tells SubInACL to create new ACEs for the group specified in the %addgroup% variable. The last character specifies the permission to grant, which in this case is full control (F).

SubInACL is a versatile tool that you can use in scripts to view and change permissions. For more information about this tool, check out the Windows IT Pro article "Edit Permissions with Subinacl" (http://www.windowsitpro.com/Article/ArticleID/26362/26362.html). We've opened up this article for public viewing, so you don't need to be a Windows IT Pro subscriber to read it.