Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I run a script to unhide all the files in a folder?

-- GA

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GA. You know, when one of the Scripting Guys was a bit younger he and the other kids in his neighborhood spent countless hours playing variations on hide-and-seek; in fact, this Scripting Guy still has vivid memories of lying in a shallow ditch and having members of the other team walk right over him, without even knowing that he was there. (That ploy worked so well that he’s seriously considering digging a shallow ditch in his office and hiding in there any time someone comes looking for him.)

Back in those days you wouldn’t have wanted a script that could automatically unhide everything; that might have been useful, but wouldn’t have been much fun. As a system administrator, however, you probably don’t find it all that enjoyable to play hide-and-seek with your files. You would probably welcome a script that could automatically unhide all the files in a folder, a script like, say, this one:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set FileList = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='c:\Scripts'} Where " _
        & "ResultClass = CIM_DataFile")

Set objFSO = CreateObject("Scripting.FileSystemObject")

For Each objFile In FileList
    Set objFile = objFSO.GetFile(objFile.Name)

    If objFile.Attributes AND 2 Then
        objFile.Attributes = objFile.Attributes XOR 2 
    End If
Next

This is kind of an unusual script in that we combine WMI and the FileSystemObject. (Sure, it sounds dangerous, but it’s OK: after all, we’re trained professionals.) We start off by connecting to the WMI service on the local computer (we’ll talk about that in a minute), and then use this query to retrieve a collection of all the files (that is, all the instances of the CIM_DataFile class) found in the folder C:\Scripts:

Set FileList = objWMIService.ExecQuery _
    ("ASSOCIATORS OF {Win32_Directory.Name='c:\Scripts'} Where " _
        & "ResultClass = CIM_DataFile")

We use WMI to retrieve the collection of files because we find it quick and easy and because - in most cases - we can use the same script to go out and retrieve a collection of files from a remote computer. Unfortunately, though, WMI can’t be used to unhide files; the CIM_DataFile class does include a property named Hidden, but that property is read-only. That’s why we have to use both WMI and the FileSystemObject: we use WMI to grab the collection of files, then we use the FileSystemObject to unhide those files.

Sadly, that also means that this script must run on the local computer; that’s because the FileSystemObject, unlike WMI, isn’t designed to work remotely. Bummer.

At any rate, after retrieving our collection we create an instance of the FileSystemObject and then set up a For Each loop to walk through the set of files. Inside that For Each loop we bind to each individual file using this line of code:

Set objFile = objFSO.GetFile(objFile.Name)

As you can see, we simply call the GetFile method, passing it the value of the Name property (which we retrieved using WMI). The Name property is equivalent to the file path; thus a file “name,” at least in WMI, will be something like C:\Scripts\My_file.txt.

After binding to a given file we then check to see whether the file is hidden or not; hidden or not hidden happens to be part of the file’s attributes. With this line of code we check to see if the “switch” for the hidden attribute is on or off. If the switch is on and the file is hidden, then this statement will be True. If the switch is off and the file is not hidden then this statement will be False:

If objFile.Attributes AND 2 Then

Note. File attributes are stored as a bitmask property. We can’t go through all the ins and outs of bitmask properties in this column, but you’ll find a reasonably good explanation of bitmasks and how to work with them in the Microsoft Windows 2000 Scripting Guide.

Why do we care whether the file is already hidden? Well, the easiest way to unhide a hidden file is to flip the switch from on to off; in fact, this line of code does that very thing:

objFile.Attributes = objFile.Attributes XOR 2

However, the XOR operator isn’t particularly intelligent: it just flips a switch from one state to another. If the switch is on, it turns it off; if the switch is off, it turns it on. That’s why we check the current state of the file. If the file is hidden then we want to use XOR to flip the switch from on to off. But what if the file isn’t hidden? In that case, we don’t want to flip the switch; that would result in us hiding the file. (Because XOR would flip the switch from off to on.) Thus we check the value of each file before we start flipping switches.

Run this script and - olly olly oxen-free! - all the files that were previously hidden will be visible once again. And then it will be your turn to hide and see if those files can find you.