Check if a file/folder exists in remote system using powershell

jayaganthan picture jayaganthan · Oct 4, 2017 · Viewed 10.9k times · Source

I already searched for this and found lot of answers. But, none of them seems to work.

I am working a script, which will be used to copy some files from local machine to remote servers. Before copying the files, I need to check if the file/folder already exists. If the folder doesn't exists, then create a new folder and then copy the files. If the file already exists at the specified location, just overwrite the file.

I got the logic on how to do this. But, for some reason Test-Path doesn't seems to work.

$server = #list of servers
$username = #username
$password = #password
$files = #list of files path to be copied
foreach($server in $servers) {
    $pw   = ConvertTo-SecureString $password -AsPlainText -Force
    $cred = New-Object Management.Automation.PSCredential ($username, $pw)
    $s = New-PSSession -computerName $server -credential $cred
    foreach($item in $files){
        $regex = $item | Select-String -Pattern '(^.*)\\(.*)$'
        $destinationPath = $regex.matches.groups[1]
        $filename = $regex.matches.groups[2]        
        #check if the file exists on local system
        if(Test-Path $item){
            #check if the path/file already exists on remote machine
            #First convert the path to UNC format before checking it
            $regex = $item | Select-String -Pattern '(^.*)\\(.*)$'
            $filename = $regex.matches.groups[2]
            $fullPath = $regex.matches.groups[1]
            $fullPath = $fullPath -replace '(.):', '$1$'
            $unc = '\\' + $server + '\' + $fullPath
            Write-Host $unc
            Test-Path  $unc #This always returns false even if file/path exists
            if(#path exists){
                Write-Host "Copying $filename to server $server"
                Copy-Item -ToSession $s -Path $item -Destination $destinationPath
            }
            else{
                #create the directory and then copy the files
            }
        }
        else{
            Write-Host "$filename does not exists at the local machine. Skipping this file"
        }           
    }
    Remove-PSSession -Session $s
}

The condition to check if the file/path exists on remote machine always fails. Not sure why.

I tried the following commands manually on powershell and the command returns true on the remote machine and false on the local machine.

On local machine:

Test-Path '\\10.207.xxx.XXX\C$\TEST'
False

On Remote machine:

Test-Path '\\10.207.xxx.xxx\C$\TEST'
True
Test-Path '\\localhost\C$\TEST'
True

So, it is clear that the command fails even if I try manually or through script. But the command passes when I try to do it from remote system or server.

But I need to check if the file exists on remote machine from local system.

Am I missing something ? Can someone help me to understand what's going on here ?

Thanks!

Answer

Harald F. picture Harald F. · Oct 4, 2017

First of all, you're not using your PSSessions for anything. They look redundant.

If your local path is the same as the destination and you're using WMF/Powershell 4 or newer; I would suggest that you stop with your regex and UNC paths and do the following, which would simplify and drop most of your code:

 $existsOnRemote = Invoke-Command -Session $s {param($fullpath) Test-Path $fullPath } -argumentList $item.Fullname; 
 if(-not $existsOnRemote){
    Copy-Item -Path $item.FullName -ToSession $s -Destination $item.Fullname;
 }