Editor's note: This is the 13th column in a continuing series on scripting that appears monthly on SearchWinSystems.com. Feel free to send any scripting questions to the author, Christa Anderson, at email@example.com.
After taking a break last month to look at additional online sources of scripting information, it's back to the grind. This month's column will discuss how to read an external file and how to create folders programmatically from a list of names, as you might do when setting up a new terminal server and creating user home directories. We'll also see how to set permissions on those folders using an external command.
This script is designed for an administrator who's got a list of user names supplied by the HR department. We'll wait until next month to do the actual script; this month we'll examine what we're doing and how it works.
To fulfill its purpose, this script will need to do three things:
- Read names from a list.
- Create folders identified by those names.
- Apply permissions to those folders.
After this, you'll know how to create objects representing Microsoft Office applications, create folders and run external executables from within VBScript.
Creating new folders from a list of names
Our first task is to create the folders, naming them from a list of names stored in an Excel spreadsheet. We'll use a File System Object twice here: once to open and read the spreadsheet, and once to create the folders.
When reading the spreadsheet, the script will cycle through the column of user names, assigning them sequentially to the value sUser. (Note: This represents that this is a string value.) Obviously, the spreadsheet needs to be somewhere the script can get to it. The best bet is a network share, so you can run the script locally or remotely (as we've explored in a previous column).
In previous columns, we've used Select Case, for scripts that have multiple potential paths to follow, and If…Then statements for either-or options. But for the script to tell that it's reached the end of the list and stop and do something else will require the use of a conditional statement that I haven't discussed before, called Do…Until.
The statements Do…Until and Do…While check to see if a particular set of conditions is true. Do…Until loops execute until they start being true; Do…While loops execute so long as the set of conditions is true. In most cases, there's not much difference. It depends on whether it makes more sense to the logic of your script to see if a condition is still true or has become true.
But what if the folder already exists? This could easily happen if the spreadsheet you're working from is not a list of only new employees, but all employees. If you try to create a folder that already exists, you'll get an error. One option would be to hope that the HR department included hire dates, so you could sort out the most recent hires. But that's not practical. Instead, we'll make the script robust enough to only create folders if the folder doesn't already exist.
Assigning permissions to folders
If you've looked at the properties for the File System Object, you've probably noticed that it doesn't contain any properties controlling permissions. Are we going to have to manually set permissions on folders we created programmatically? Nope—this is a perfect opportunity to show how VBScript can incorporate external applications.
In this case, we're going to use a venerable Windows command-line tool called CACLS that you can use to set permissions from the command line. Using this tool, we can make sure that the following conditions are true:
- The owner of the home directory can modify, list, write, and execute files in their home directory.
- The administrators have full permission.
- Other users who are not the owner have no permissions. CACLS is fairly self-explanatory. Its syntax looks like this: CACLS filename [/T] [/E] [/C] [/G user:perm] [/R user [...]] [/P user:perm [...]] [/D user [...]]
There are only parts that might get you into trouble. The first is forgetting /t to set the permissions you apply for the entire tree (otherwise, you could end up with someone who's got permission to the top level of their home directory, but not the rest of it). The second one is that user names with two words in them need to be encased in quotation marks so that CACLS sees the name as one string.
Here is a list of arguments and their meanings.
- filename displays the ACLs for that path.
- /t changes the ACLs for that folder and all its subfolders. Think of T standing for "tree" and it makes more sense.
- /e can be used to edit the ACLs instead of replacing them. (Replacing them is the default.)
- /c continue is you get "access denied" errors.
- /g user permission grants the specified user(s) rights the specified path. Valid permissions are w (write), c (change), r (read), and f (full control).
- /r user revokes a specified usesr's access rights (valid only with /e).
- /p user permission replace the specified user(s) current rights with new rights. . Valid permissions are n (none) w (write), c (change), r (read) and f (full control).
- /d user denies the specified user access to the named path. This is not the same thing as no permissions.
CACLS is not part of VBScript. To use it from within the script, you'll need to create a WshShell object and use its Run Method. Run can run any external command to which the person running the script has permissions.
We'll do more with Run later. As you can combine it with methods to write input to a program, it's quite powerful. It's also very simple. In this example, you're going to use CACLS exactly as you would if running it from the command line, except that you're going to preface it with oShell.Run.
In this column, we've looked at what's required to create new folders from a list of user names and set the appropriate permissions on them. Since VBScript doesn't supply any way to set permissions programmatically on folders created with the File System Object, we've also examined how to run an external tool from within VBScript using WshShell's Run method.
As we discussed early in this column, there are times to script our new tools and there are times to rely on the work that someone else has already done. In this case, we've already got a file permissions tool so there's no reason to worry about how to set permissions outside it.
In next month's column, we'll look at how our script will work.
Read all of Christa's scripting columns:
April 2005: Beginner's guide to scripting
May 2005: It's time to increase your scripting expertise
June 2005: Connect users to network resources
July 2005: More on connecting to network resources
August 2005: Find objects with Windows Scripting Host
September 2005: Windows Script Host arguments
October 2005: Scripting School: Turning the environment with WshShell
November 2005: Scripting School: Connect scripts to remote computers
December 2005: Scripting School: Writing output to a text file
January 2006: Scripting School: Taking inventory of drives
February 2006: Scripting School: Enhancing scripts that require user input
March 2006: Scripting School: Nine links for online scripting resources
ABOUT THE AUTHOR:
A Terminal Services MVP, Christa Anderson is the strategic technology manager for visionapp She formerly was program manager for the Microsoft Terminal Services team. She is an internationally known authority on scripting, the author of Windows Terminal Services, The Definitive Guide to MetaFrame XP, and co-author of the book Mastering Windows 2003 Server. If you have a scripting question for Christa, please e-mail her at editor@SearchWincomputing.com. She often uses these emails as fodder for her scripting columns.