How Can I Determine Whether a File Exists on a Remote Computer?

How Can I Determine Whether a File Exists on a Remote Computer?

  • Comments 2
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I check to see if a file exists on a remote computer even if that file isn’t in a shared folder?

-- SP

SpacerHey, Scripting Guy! AnswerTechNet Script Center

Hey, SP. You know, the Scripting Guy who writes this column had minor periodontal surgery this morning. (Well, maybe his dentist thought it was minor. The Scripting Guy, who’s a bit of a baby when it comes to these sorts of things, begs to differ.) And, yes, our hero came to work anyway, meaning he’s either a real trouper or, well, an idiot. (Editor’s Note: I think we all know the answer to that one.) At any rate, even though he’s in no pain or discomfort (aside from the fact that he was only allowed to eat yogurt at lunch) he was definitely hoping to find an easy question to answer for today’s column. SP, this is just what the doctor ordered!

OK, technically the doctor ordered Vicodin and penicillin. But you know what we mean.

As you noted, you want to verify the existence of a file on a remote computer; however, that file might not be stored in a shared folder. Is that a problem? Well, it could be, if you were using the FileSystemObject. But if you’re using WMI, well, then it’s no problem at all: WMI can locate files in a regular old folder just as easily as it can locate files in a shared folder. Verify the existence of a file on a remote computer? It’s as easy as pulling teeth.

So to speak.

For example, here’s a script that will check to see if the file C:\Scripts\Test.vbs can be found on the remote computer atl-fs-01:

strComputer = "atl-fs-01"

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

Set colFiles = objWMIService. _
    ExecQuery("Select * From CIM_DataFile Where Name = 'C:\\Scripts\\Test.vbs'")

If colFiles.Count = 0 Then
    Wscript.Echo "The file does not exist on the remote computer."
Else
    Wscript.Echo "The file exists on the remote computer."
End If

We told you this Scripting Guy was looking for an easy question to answer; as you can see, there’s not much to this script at all. We begin by assigning the name of the remote computer to a variable named strComputer:

strComputer = "atl-fs-01"

In an unusual plot twist (at least for this column), that brings up an interesting question: could we run this same script on the local computer? You bet; all we have to do is assign a dot (.) to the variable strComputer:

strComputer = "."

Note. Why a dot? That’s easy: when constructing a WMI path the dot provides a way to indicate the local computer, even if you don’t know the name of the local computer.

After assigning the computer name to strComputer we connect to the WMI service on atl-fs-01. That brings us to this line of code:

Set colFiles = objWMIService.ExecQuery _
    ("Select * From CIM_DataFile Where Name = 'C:\\Scripts\\Test.vbs'")

Here we’re retrieving a collection of all the files on atl-fs-01 that have a name equal to C:\Scripts\Test.vbs. (In WMI, the Name property is equivalent to the file path.) And no, you’re not seeing double: we really did write out the path as C:\\Scripts\\Test.vbs. That’s not due to us taking one-too-many painkillers (we’re too tough to take any painkillers!). Instead, that’s due to the fact that the \ is a reserved character in WMI; because of that any time you use the \ in a query you must “escape” the character by prefacing it with another \. It’s a bit goofy-looking, but it works.

Now, where were we? (On painkillers, tough guy.) Oh, right: as we noted, our query returns a collection of all the files with the Name C:\Scripts\Test.vbs. To determine whether or not the file exists all we have to do is check the Count of the collection; as the name implies, the Count tells you the number of items in the collection. Suppose Count is equal to 0. That means there are no items in the collection; in turn, that means that there are no files named C:\Scripts\test.vbs located on atl-fs-01. Therefore, we echo back the fact that the file does not exist. If Count is not equal to 0 (and, because file paths must be unique, the only other possibility is a Count equal to 1) we echo back the fact that the file does exist on atl-fs-01.

Pretty simple, right? All that takes place inside this block of code:

strComputer = "atl-fs-01"

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

Set colFiles = objWMIService. _
    ExecQuery("Select * From CIM_DataFile Where Name = 'C:\\Scripts\\Test.vbs'")

If colFiles.Count = 0 Then
    Wscript.Echo "The file does not exist on the remote computer."
Else
    Wscript.Echo "The file exists on the remote computer."
End If

And there you have it. Because WMI works by connecting to the remote machine itself, it doesn’t matter whether the file is in a shared folder or not; WMI will track it down for you.

Ah, good question: suppose you’re looking for the file Test.vbs but you aren’t sure what folder that file might be stored in. Can WMI located a file even when you don’t know the folder name? You bet it can. We won’t discuss this script in any detail today, but it searches atl-fs-01 for any file named Test.vbs, regardless of the folder that file might be stored in:

strComputer = "atl-fs-01"

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

Set colFiles = objWMIService. _
    ExecQuery("Select * From CIM_DataFile Where FileName = 'Test' and Extension = 'vbs'")

If colFiles.Count = 0 Then
    Wscript.Echo "The file does not exist on the remote computer."
Else
    Wscript.Echo "The file exists on the remote computer."
End If

Note. For more information on using scripts to manage files and folders - including an explanation of what properties such as FileName and Extension represent - see the Microsoft Windows 2000 Scripting Guide.

We hope that helps, SP. We’d be happy to stay and chat about this, except it’s time to go home and eat dinner. And, trust us, after being limited to yogurt for lunch we are starved. Fortunately, for dinner the dentist has said we can have … um, yogurt …. Oh: and maybe a banana. How … nice ….

Come to think of it, SP, if you’d like to chat more about this script, well, maybe we can stay a bit longer after all ….


Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi...

    Great article and comments...

    I was wondering how exactly I can search same in list of computers and have output in logfile?

    Thanks,

  • Dear VB newbie,

    Step 1: Change your name to PoSh Newbie and forget you ever heard of VB.

    Step 2: Run something like this in a PowerShell window:

    $list = Get-Content -Path List-O-Computers.txt # You can figure out many different ways to get your list of computers

    $found = @()

    foreach($computer in $list) {

     # Slow way

     #$file = Get-WMiObject -ComputerName $computer -Class CIM_DataFile -Filter "FileName = 'Test' AND Extension = 'ps1'"

     # Faster way, if you know the expected path

     $file = Get-WMiObject -ComputerName $computer -Class CIM_DataFile -Filter "Name = 'C:\\Path\\ToThe\\File\\test.ps1'" | Select-Object Name

     $file | Add-Member -MemberType NoteProperty -Name ComputerName -Value $computer

     $found += $file

     }

    $found | Export-Csv -Path "$env:UserProfile\desktop\List-O-Files.csv" -NoTypeInformation

    Jeremy