176

I have this script which compares files in two areas of the disk and copies the latest file over the one with the older modified date.

$filestowatch=get-content C:\H\files-to-watch.txt

$adminFiles=dir C:\H\admin\admin -recurse | ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

$userFiles=dir C:\H\user\user -recurse | ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

foreach($userfile in $userFiles)
{

      $exactadminfile= $adminfiles | ? {$_.Name -eq $userfile.Name} |Select -First 1
      $filetext1=[System.IO.File]::ReadAllText($exactadminfile.FullName)
      $filetext2=[System.IO.File]::ReadAllText($userfile.FullName)
      $equal = $filetext1 -ceq $filetext2 # case sensitive comparison

      if ($equal) { 
        Write-Host "Checking == : " $userfile.FullName 
        continue; 
      } 

      if($exactadminfile.LastWriteTime -gt $userfile.LastWriteTime)
      {
         Write-Host "Checking != : " $userfile.FullName " >> user"
         Copy-Item -Path $exactadminfile.FullName -Destination $userfile.FullName -Force
       }
       else
       {
          Write-Host "Checking != : " $userfile.FullName " >> admin"
          Copy-Item -Path $userfile.FullName -Destination $exactadminfile.FullName -Force
       }
}

Here is the format of files-to-watch.txt

content\less\_light.less
content\less\_mixins.less
content\less\_variables.less
content\font-awesome\variables.less
content\font-awesome\mixins.less
content\font-awesome\path.less
content\font-awesome\core.less

I would like to modify this so that it avoids doing this if the file does not exist in both areas and prints a warning message. Can someone tell me how I can check if a file exists using PowerShell?

wonea
  • 4,783
  • 17
  • 86
  • 139
Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427

7 Answers7

291

Just to offer the alternative to the Test-Path cmdlet (since nobody mentioned it):

[System.IO.File]::Exists($path)

Does (almost) the same thing as

Test-Path $path -PathType Leaf

except no support for wildcard characters

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • 1
    See also: [A better way to check if a file exists or not in PowerShell](http://stackoverflow.com/a/31888581/450913) – orad Aug 08 '15 at 17:37
  • 1
    @orad Yes, I saw it, posted an answer with a negated Exists() call, but was not met with the same positive response ;-) – Mathias R. Jessen Aug 08 '15 at 19:27
  • 5
    Using `[System.IO.File]::Exists` also [resolves relative paths differently](https://stackoverflow.com/q/11246068/1394393), and `Test-Path` can be used with non-filepaths (e.g., registry locations). Use `Test-Path`. – jpmc26 Jan 20 '18 at 00:26
  • The Exists() one didn't work for me with relative paths. Test-Path worked great. – Jamie Aug 18 '18 at 00:12
  • 2
    @Jamie Native .NET methods usually resolve paths relative to the working directory of the process, not necessarily the current FileSystem path in powershell. You could do `[System.IO.File]::($(Join-Path $PWD $path))` – Mathias R. Jessen Aug 18 '18 at 14:09
  • 1
    And in case you didn't guess it's `[System.IO.Directory]::Exists($path)` for folders. Both support UNC paths on my system, but to do hidden shares remember to escape the `$` in the path as "`$" – Chris Rudd May 14 '19 at 17:32
  • This will return `$False` if a file is hidden. At least for me anyway. – Ste Jul 24 '21 at 13:41
108

Use Test-Path:

if (!(Test-Path $exactadminfile) -and !(Test-Path $userfile)) {
  Write-Warning "$userFile absent from both locations"
}

Placing the above code in your ForEach loop should do what you want

arco444
  • 22,002
  • 12
  • 63
  • 67
38

You want to use Test-Path:

Test-Path <path to file> -PathType Leaf
SharpC
  • 6,974
  • 4
  • 45
  • 40
GodEater
  • 3,445
  • 2
  • 27
  • 30
12

The standard way to see if a file exists is with the Test-Path cmdlet.

Test-Path -path $filename
Mike Shepard
  • 17,466
  • 6
  • 51
  • 69
9

You can use the Test-Path cmd-let. So something like...

if(!(Test-Path [oldLocation]) -and !(Test-Path [newLocation]))
{
    Write-Host "$file doesn't exist in both locations."
}
Speerian
  • 1,138
  • 1
  • 12
  • 29
2
cls

$exactadminfile = "C:\temp\files\admin" #First folder to check the file

$userfile = "C:\temp\files\user" #Second folder to check the file

$filenames=Get-Content "C:\temp\files\files-to-watch.txt" #Reading the names of the files to test the existance in one of the above locations

foreach ($filename in $filenames) {
  if (!(Test-Path $exactadminfile\$filename) -and !(Test-Path $userfile\$filename)) { #if the file is not there in either of the folder
    Write-Warning "$filename absent from both locations"
  } else {
    Write-Host " $filename  File is there in one or both Locations" #if file exists there at both locations or at least in one location
  }
}
Cosmin Staicu
  • 1,809
  • 2
  • 20
  • 27
M-A Charlotte
  • 325
  • 1
  • 3
  • 10
-5

Test-Path may give odd answer. E.g. "Test-Path c:\temp\ -PathType leaf" gives false, but "Test-Path c:\temp* -PathType leaf" gives true. Sad :(

Zoltan Hernyak
  • 989
  • 1
  • 14
  • 35