Vérifier si un fichier existe ou non dans Windows PowerShell?

112

J'ai ce script qui compare les fichiers dans deux zones du disque et copie le dernier fichier sur celui avec la date de modification la plus ancienne.

$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
       }
}

Voici le format de 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

Je voudrais modifier ceci afin qu'il évite de faire cela si le fichier n'existe pas dans les deux zones et imprime un message d'avertissement. Quelqu'un peut-il me dire comment vérifier si un fichier existe à l'aide de PowerShell?

Samantha JT Star
la source

Réponses:

199

Juste pour proposer l'alternative à l' Test-Pathapplet de commande (puisque personne ne l'a mentionnée):

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

Fait (presque) la même chose que

Test-Path $path -PathType Leaf

sauf pas de prise en charge des caractères génériques

Mathias R. Jessen
la source
1
@orad Oui, je l'ai vu, j'ai posté une réponse avec un appel Exists () annulé, mais je n'ai pas reçu la même réponse positive ;-)
Mathias R. Jessen
5
L'utilisation résout[System.IO.File]::Exists également les chemins relatifs différemment et Test-Pathpeut être utilisée avec des chemins autres que des chemins de fichiers (par exemple, des emplacements de registre). Utilisez Test-Path.
jpmc26
2
Les méthodes @Jamie Native .NET résolvent généralement les chemins relatifs au répertoire de travail du processus, pas nécessairement le chemin FileSystem actuel dans PowerShell. Vous pourriez faire[System.IO.File]::($(Join-Path $PWD $path))
Mathias R. Jessen
1
Et au cas où vous ne l'auriez pas deviné, c'est [System.IO.Directory]::Exists($path)pour les dossiers. Les deux prennent en charge les chemins UNC sur mon système, mais pour faire des partages cachés, n'oubliez pas d'échapper $au chemin en tant que "` $ "
Chris Rudd
71

Utilisez Test-Path :

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

Placer le code ci-dessus dans votre ForEachboucle devrait faire ce que vous voulez

arco444
la source
22

Vous souhaitez utiliser Test-Path:

Test-Path <path to file> -PathType Leaf
GodEater
la source
7

La méthode standard pour voir si un fichier existe est avec l' Test-Pathapplet de commande.

Test-Path -path $filename
Mike Shepard
la source
6

Vous pouvez utiliser le Test-Pathcmd-let. Donc quelque chose comme ...

if(!(Test-Path [oldLocation]) -and !(Test-Path [newLocation]))
{
    Write-Host "$file doesn't exist in both locations."
}
Speerian
la source
0
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
  }
}
MA Charlotte
la source
-4

Test-Path peut donner une réponse étrange. Par exemple, "Test-Path c: \ temp \ -PathType leaf" donne false, mais "Test-Path c: \ temp * -PathType leaf" donne true. Triste :(

Zoltan Hernyak
la source