A client recently asked me whether it was possible to identify the name of every file that a specific user had created in a directory structure containing more than 20,000 files. At first this request seemed absurdthe only way to find this information would be to check the ownership of each file individually and compose a list, a task that would take forever. Then, I remembered that a few years ago I'd used a resource kit utility called subinacl.exe to change the ownership of files. At the time, I'd discovered that among the tool's many features, it lets you view a file's properties, including the SID of the user who owns the file. Knowing that Subinacl could help me locate the information I needed, I created a script called ownedby.cmd, which Listing 1 shows, to audit file ownership.
Subinacl.exe
More than one version of Subinacl existsMicrosoft released the first version with the .Microsoft Windows NT Server 4.0 Resource Kit and a second, updated version with the .Microsoft Windows 2000 Resource Kit. The two versions vary slightly because Microsoft added some functionality in the Win2K version to accommodate some of the new features in the new OS. However, for the purposes of ownedby.cmd, both versions of Subinacl work the same. For a complete list of options for this tool, from the command prompt type
subinacl.exe /help /full
To use the Subinacl command to view details about a file's ACL, simply type
subinacl.exe /file filename
where filename is the file's name. Because you won't need all the information that this command provides, you can add the /noverbose switch to display only a summary of the file ACL information. Figure 1, page 6, shows sample output of the Subinacl command with all the switches specified. As you can see, one of the lines contains the string /owner = S-1-5-32-544, which signifies that the file owner's SID is S-1-5-32-544.
You might be wondering what good knowing the owner's SID will do you. After all, not too many administrators know their users' SIDs by heart. The approach that ownedby.cmd takes is to start with a known username, determine its SID, then find all files associated with that SID. So, for the next step in the process, you need a tool to convert usernames to SIDs. Fortunately, Microsoft includes just such a tool, called Getsid, in the Win2K and NT 4.0 resource kits.
Getsid.exe
Getsid.exe compares the user SIDs of two accounts. The command syntax is
getsid \\server1 account1 \\server2 account2
where server1 and server2 specify the servers that you want to query to get the SID information and account1 and account2 specify the user accounts you want to compare. Ownedby.cmd uses Getsid to obtain the SID for a specified user account, so in this case, server1 and server2 will be the same, as will account1 and account2. For example, to get the SID for user JDoe from domain controller (DC) mydc, I'd type
getsid \\mydc JDoe \\mydc JDoe
Running the Script
You now have the basic tools to make the script work. Subinacl provides a file owner's SID, and Getsid provides the SID for a specified username. With these tools, you can perform usernametofile-ownership comparisons. Ownedby.cmd's scope is to output the filename and path for every file owned by a specified user within a particular directory structure. The script requires one hard-coded parameter (the name of the DC) and three runtime parameters: the username (userid), the root of the directory structure (root_directory), and the output file's name (outputfile). The final syntax for the Ownedby command is
ownedby.cmd userid root_directory outputfile
For example, if I type
ownedby.cmd JDoe G:\users results.txt
the script outputs to results.txt all the files that user JDoe owns in the G:\users directory and its subdirectories.
When the script runs, it must determine the SID of the specified user ID, then store that SID in the sid variable for later use, as the code at callout A in Listing 1 shows. This code first clears the sid variable in case it was previously defined. The script then determines the user's SID by running Getsid in a For loop and filtering the output to display only entries that contain the string "S-", which is the prefix for a SID. The script retrieves the SID value from the seventh string ("tokens=7") of Getsid's output and stores this value in the sid variable. The %DC% value is the hard-coded name of the DC, which is defined earlier in the script. The %USERID% value contains the user ID that you specify in the command-line parameters when you run the script.
Next, as the code at callout B shows, the script runs the Dir command in a For loop to obtain a list of files that the script will compare against the user ID (%USERID%) value. Several switches tell the command to not include header or summary information for all subdirectories (/s), to output the results in bare format (/b), and, because you only care about files and not directories, to output only objects whose "attribute is not directory" (/a-d). The ROOTDIR variable contains the value of the directory that you want to search. Using the earlier example, the ROOTDIR variable would contain the string G:\users.
Prev. page  
[1]
2
next page