I'm trying to use Windows Management Instrumentation's (WMI's) Win32_ Directory TakeOwnerShip class method in a logon script so that users can take ownership of a specific folder when they log on. However, the code in Listing 5 fails to select the particular folder for ownership. Am I on the right track, or should I take a different approach?
You're on the right track. You can select the target folder in several ways:
- Using the WMI SWbemServices object's ExecQuery method, you can select the target folder with a WMI Query Language (WQL) Select statement in combination with a Where clause.
- Using the WMI SWbemServices object's InstancesOf method, you can enumerate all folders and use a decision statement in the body of the enumeration to test and subsequently select the target folder.
- You can use a WMI object path to select the target folder.
Let's examine each approach more closely.
The ExecQuery method. ExecQuery provides an efficient mechanism to select the target folder, provided you know that folder's path beforehand. To successfully use this method, you need a well-formed WQL Select statement. The Select statement in Listing 5 contains two minor syntax errors. The first error is that you didn't delimit the key value C:\temp. To delimit this value, you can use either single (') or double quotes ("). If you want to delimit the key value with single quotes, you use the query
& "Win32_Directory where" _
If you want to use double quotes, the query is
& "Win32_Directory where" _
Many systems administrators prefer using single quotes over double quotes because of VBScript's somewhat confusing syntax associated with embedding literal double quotes inside a string. As you can see in the double-quoted query, you must escape (i.e., flag) the literal double quotes to prevent the VBScript engine from interpreting the end of the string too early. To escape a literal double quote in VBScript, you preface the double quote with a second double quote. The VBScript engine interprets two adjacent double quotes as one literal double quote embedded in a string.
The second error is the use of a single backslash (\). Like double quotes, backslashes must be escaped, but the reason isn't related to VBScript. Escaping backslashes is a WMI requirement. To escape a backslash in WMI, you preface the backslash with another backslash, as the two sample queries show.
Providing that you make these two corrections to your script, ExecQuery should return an SWbemObjectSet collection with exactly one instance that represents the target folder identified in the Where clause. As Listing 6 shows, you can then enumerate the collection to access the instance and call the Win32_Directory TakeOwnerShip method.
The InstancesOf method. Instances-Of returns all instances of the target class. Listing 7 shows how to use this method. In the case of the Win32_ Directory class, the method will return instances of not only all the folders on all the target computer's local drives but also all the folders on all the target computer's mapped network drives. To put this in perspective, InstancesOf returned 14,023 Win32_Directory objects across three local drives and two mapped network drives on one of my workstations. Thus, unless you have no other option, I would discourage you from using the InstancesOf method because it will be terribly inefficient and significantly reduce the performance of the target computer, network drives, and network. InstancesOf is better suited for classes without hundreds or thousands of instances, such as the Win32_Process, Win32_Processor, or Win32_Service class.
WMI object path. Using the WMI object path is the most direct approach to selecting a target folder. The WMI object path lets you identify the complete path to the target class instance as part of the moniker string passed to VBScript's GetObject function. WMI object paths are much like fully qualified file system paths, but WMI object paths conform to the object path syntax defined by WMI. WMI object paths have the added benefit of returning a single SWbemObject object rather than an SWbemObjectSet collection, which means you don't need to unravel a collection to access one instance, as you have to do with ExecQuery. You access the instance directly, as Listing 8 shows.
Those are your options. As I mentioned earlier, using the InstancesOf method wouldn't be advantageous. Whether you want to use the ExecQuery method or the WMI object path is a matter of personal preference.