Help with test-path

Welcome Forums General PowerShell Q&A Help with test-path

Viewing 10 reply threads
  • Author
    Posts
    • #186637
      Participant
      Topics: 1
      Replies: 5
      Points: 32
      Rank: Member

      Hi everyone!

      I'm new to Powershell, so hoping to gain to experience/knowledge to become better!

      I ran the below script to test if a file is on a remote computer, but the results returned as False even though I have verified the file is there through Windows Explorer. I tested the same script on my local computer and it returned as True (both files are on both remote and local computer).

      $cred = Get-Credential
      $Session = New-PSSession -ComputerName "Computer1" -Credential $cred
      (Test-Path "\\$Session\c$\temp\test.txt")

       

      below are the results of running the script:

      PS C:\WINDOWS\system32> $cred = Get-Credential
      $Session = New-PSSession -ComputerName "Computer1" -Credential $cred
      (Test-Path "\\$Session\c$\temp\test.txt")
      cmdlet Get-Credential at command pipeline position 1
      Supply values for the following parameters:
      False

       

      Additional Notes: I did get a prompt to enter my credentials and it was submitted successfully, which resulted in the False result. I confirmed this by entering bad credentials which resulted in 'password is incorrect'.

      Can you assist in trying to figure out why it is returning as false and how I can change it to it returns True correctly?

    • #186694
      Senior Moderator
      Topics: 8
      Replies: 1141
      Points: 3,928
      Helping Hand
      Rank: Community Hero

      New-PSSession creates a PowerShell session using winrm to execute commands on another computer. To test a file you just need Test-Path like below.

      Test-Path \\Computer1\C$\temp\test.txt
      

      If credentials is required to connect to that computer you would do it like below

      $cred = Get-Credential
      
      # When using Session, you can do multiple invoke commands using the same session (there are other benefits as well)
      $Session = New-PSSession -ComputerName "Computer1" -Credential $cred
      Invoke-Command -Session $Session -ScriptBlock {Test-Path C:\temp\test.txt}
      
      # Or
      
      # When session is not used, credentials has to be mentioned for each invokes
      Invoke-Command -ComputerName 'Computer1' -ScriptBlock {Test-Path C:\temp\test.txt} -Credential $Cred
      
    • #186850
      Participant
      Topics: 4
      Replies: 6
      Points: 79
      Rank: Member

      If you are running your PowerShell session under the same user account that you would use to connect to the remote server the -Credential parameter can be excluded, as it will use that instance's credentials.

      Invoke-Command -ComputerName 'Computer1' -ScriptBlock { Test-Path C:\temp\test.txt }
    • #187060
      Participant
      Topics: 1
      Replies: 5
      Points: 32
      Rank: Member

      Thanks so far. So now I'm trying to add in if statement. that is, if the file is there (True) then copy a file from my local computer to the network/destination computer (overwriting the destination folder). I have this so far, but it says network path was not found.

       

      $cred = Get-Credential
      $Session = New-PSSession -ComputerName "TXHOUAPP342D" -Credential $cred
      Invoke-Command -Session $Session -ScriptBlock {if (Test-Path C:\Temp\test.txt) {Copy-Item "C:\temp\test.txt" -Destination "\\$Session\C$\temp\"}}

       

      PS C:\WINDOWS\system32> $cred = Get-Credential
      $Session = New-PSSession -ComputerName "TXHOUAPP342D" -Credential $cred
      Invoke-Command -Session $Session -ScriptBlock {if (Test-Path C:\Temp\test.txt) {Copy-Item "C:\temp\test.txt" -Destination "\\$Session\C$\temp\"}}
      cmdlet Get-Credential at command pipeline position 1
      Supply values for the following parameters:
      The network path was not found.
      + CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
      + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
      + PSComputerName : TXHOUAPP342D

       

    • #187093
      Participant
      Topics: 10
      Replies: 1284
      Points: 1,084
      Helping Hand
      Rank: Community Hero

      You may run into issue with double-hop. Is there are reason you are not just using a UNC path?

      $servers = 'Server1', 'Server2', 'Server3'
      
      foreach ($server in $servers) {
          $path = '\\{0}\c$\test.txt' -f $server
      
          if (Test-Path $path) {
              Copy-Item -Path $path -Destination 'C:\Temp'
          }
          else {
              'File path {0} not found' -f $path
          }
      }
      
      • #187648
        Participant
        Topics: 1
        Replies: 5
        Points: 32
        Rank: Member

        Hi Rob,

        My remote server requires different credentials, so how would I either 1) pass alternate credentials, or 2) create a credential parameter into your script?

    • #187723
      Senior Moderator
      Topics: 8
      Replies: 1141
      Points: 3,928
      Helping Hand
      Rank: Community Hero

      of course, you can pass a credential via Invoke-Command, but cannot be used with Test-Path and Copy-Item as its not yet supported even though its available for those cmdlets.

      If you are in PS v 5.0 or later, you can use Copy-Item with -From/ToSession parameters. You can read more at below link.

      https://docs.microsoft.com/en-us/previous-versions/powershell/module/microsoft.powershell.management/copy-item?view=powershell-5.0

    • #187876
      Participant
      Topics: 10
      Replies: 1284
      Points: 1,084
      Helping Hand
      Rank: Community Hero

      You could also just open Powershell ISE or Powershell prompt as the elevated credentials. I test scripts that are going to be running as service accounts all the time by basically opening Powershell ISE and debugging using that account to ensure the account has the appropriate permissions.

    • #188383
      Participant
      Topics: 1
      Replies: 5
      Points: 32
      Rank: Member

      Rob,

      I took your advice, along with another script I found online (link below) and ran PS ISE with the remote user credentials and do not have worry about any authentication. With some tweaks to the script in the below article I was able to achieve the desired goal, which is to copy files from the source to multiple servers only if the file exists on the destination server.

      https://stackoverflow.com/questions/25916197/copy-items-from-source-to-destination-if-they-dont-already-exist

      `$Source = "C:\SourceFolder"
      $Destination = "C:\DestinationFolder"

      GetChildItem $Source Recurse | ForEach {
      $ModifiedDestination
      = $($_.FullName).Replace("$Source","$Destination")
      If ((TestPath $ModifiedDestination) eq $False) {
      CopyItem $_.FullName $ModifiedDestination
      }
      }`

      
      
      		
      	
    • #189805
      Participant
      Topics: 1
      Replies: 5
      Points: 32
      Rank: Member

      Hey All,

      I'm still at it. With some help from another online forum and colleagues of mine, I am now using a ForEach statement with Invoke-Command. Good news is the script doesn't error out, but the bad news is it does not do what I want it to do, which is to copy files from my local computer to a remote computer using alternative credentials. See script below. Can you help by telling me why the script might not be copy files to remote location as expected?

       

      $cred = Get-Credential
      $Session = New-PSSession -ComputerName "Computer1" -Credential $cred 
      $Source = "C:\temp\test"
      $APPServer = "\\Computer1\c$\temp\test"
      $SB = { Get-ChildItem $Source -Recurse | ForEach {
      $ModifiedAppServer = $($_.FullName).Replace("$Source","$APPServer")
      If ((Test-Path $ModifiedAPPServer ) -eq $True) {
      Copy-Item $_.FullName $ModifiedAPPserver 
      }
      }
      }
      Invoke-Command -Session $Session -ScriptBlock $SB
    • #189811
      Participant
      Topics: 2
      Replies: 511
      Points: 1,306
      Helping Hand
      Rank: Community Hero

      Local variables don't get passed through into a remote session; you need to explicitly specify the variables in the scriptblock which originate from the local session by prefixing them with $using: e.g., $using:Source or $using:APPServer when referencing them within the $SB scriptblock.

    • #189817
      Participant
      Topics: 1
      Replies: 5
      Points: 32
      Rank: Member

      Thanks, Joel. but I am not sure I understand how to do that...

      I think you are saying I have to (some how) use `$using` to reference the `$session`?

      So like this?

      $cred = Get-Credential
      $Session = New-PSSession -ComputerName "Computer1" -Credential $cred 
      $Source = "C:\temp\test"
      $APPServer = "\\Computer1\c$\temp\test"
      $SB = { Get-ChildItem $Source -Recurse | ForEach {
      $ModifiedAppServer = $($_.FullName).Replace("$Source","$APPServer")
      If ((Test-Path $ModifiedAPPServer $using:session) -eq $True) {
      Copy-Item $_.FullName $ModifiedAPPserver 
      }
      }
      }
      Invoke-Command -Session $Session -ScriptBlock $SB

      I put $using:session after Test-Path $ModifiedAPPserver

       

      btw: I tried the above and it did not work

Viewing 10 reply threads
  • You must be logged in to reply to this topic.