PowerShell – How to copy a local file to remote machines


During a training, a student asked me how to copy a local file to remote machines without using fileshare. It was a great question, so I decided to share here in this post.
As I need a file to be used as example, I can create a new one using the following command:
New Item -Path C:\temp\localfile.txt -Value $ env: ComputerName
The command to copy a file locally is:
Copy-Item -Path c:\processos.txt -Destionation c:\temp\localfile.txt
Now, imagine that I want to copy this file to other servers. If you are using the PowerShell 5.0, now the Copy-Item command supports copying files from one machine to another through -ToSession and -FromSession parameters. As the name suggests, the -ToSession parameter expects a session with the destination computer where the file will be copied.To create the session, I used the following command:
$ Session = new-PSSession -ComputerName PowerShellAzureMachine -Credential $ cred
Now we have the session, the second step is to perform the file copy via -ToSession parameter:
Copy-Item -Path C:\temp\localfile.txt -Destination C:\localfile.txt -ToSession $ session

For earlier versions of PowerShell, one way of doing this is through the Invoke-Command command.

The first step is to perform the reading of the local file to a local variable:

$ File = [System.IO.File] :: ReadAllBytes ( “C:\temp\localfile.txt”)
Now I use the Invoke-Command to run the copy:
Invoke-Command -session $ session -ArgumentList $ file -ScriptBlock {[System.IO.File] :: WriteAllBytes ( “C:\localfile2.txt”, $ args)}
copyitem
I hope you have enjoyed.
Comments (14)

  1. Jonathan Burbano says:

    Where can this be used in lieu of using Copy-Item and setting the to to an admin share? The only time I can think of is if the profile you are currently in the shell with, may not have access to an admin share, but Copy-Item does have a Credential option.

    1. Great question Jonathan. In the customer case, he’d like to use that within a script. As I can remember, he was facing a case where his user wasn’t admin and the destination folder wasn’t shared. 🙂

  2. Hi Luis, Just i started Power shell and you article is very help full for me. I am very thankful for you.
    Please keep me update, when you are posting any Power shell document or Scripts. Keep me in post on harvanshsinghwipro@hotdmail.com mail id.

    1. Thank you for this great feedback!!!

  3. Luca says:

    i want to copy txt file in windows 10 client from windows server client. I think to use ps session command to enter in client and use copy-item to copy the txt file but powershell responds acces denied.How can i use my domain credential to do this operation?

    1. Hi Luca,

      No configuration is required to enable a computer (client) to send remote commands. However, to receive remote commands, Windows PowerShell remoting must be enabled on the computer. Enabling includes starting the WinRM service, setting the startup type for the WinRM service to Automatic, creating listeners for HTTP and HTTPS connections, and creating default session configurations.

      Windows PowerShell remoting is enabled on Windows Server 2012 and newer releases of Windows Server by default.

      To configure a computer to receive remote commands, use the Enable-PSRemoting cmdlet. The following command enables all required remote settings, enables the session configurations, and restarts the WinRM service to make the changes effective.

      Enable-PSRemoting

      To suppress all user prompts, type:

      Enable-PSRemoting -Force

      On client versions of Windows, Enable-PSRemoting succeeds on private and domain networks. By default, it fails on public networks, but if you use the SkipNetworkProfileCheck parameter, Enable-PSRemoting succeeds and creates a firewall rule that allows traffic from the same local subnet.

      NOTE: The WinRM client cannot process the request. If the
      authentication scheme is different from Kerberos, or if the client
      computer is not joined to a domain, then HTTPS transport must be used
      or the destination machine must be added to the TrustedHosts
      configuration setting.

      When the local computer is not in a domain, the following procedure is required
      for remoting.

      Configure the computer for HTTPS transport or add the names of the remote computers to the TrustedHosts list on the local computer.

      HOW TO ADD A COMPUTER TO THE TRUSTED HOSTS LIST
      ———————————————–

      The TrustedHosts item can contain a comma-separated list of computer
      names, IP addresses, and fully-qualified domain names. Wildcards
      are permitted.

      To view or change the trusted host list, use the WSMan: drive. The
      TrustedHost item is in the WSMan:\localhost\Client node.

      Only members of the Administrators group on the computer have permission
      to change the list of trusted hosts on the computer.

      Caution: The value that you set for the TrustedHosts item affects all
      users of the computer.

      To view the list of trusted hosts, use the following command:

      Get-Item wsman:\localhost\Client\TrustedHosts

      To add all computers to the list of trusted hosts, use the following
      command, which places a value of * (all) in the ComputerName

      Set-Item wsman:localhost\client\trustedhosts -Value *

      You can also use a wildcard character (*) to add all computers in a
      particular domain to the list of trusted hosts. For example, the following
      command adds all of the computers in the Fabrikam domain to the list of
      trusted hosts.

      Set-Item wsman:localhost\client\trustedhosts *.fabrikam.com


      In the client computer, you need to change a configuration to trust on the remote computer. You

      Take a look at this article to more details:
      https://technet.microsoft.com/en-us/library/hh847850.aspx?f=255&MSPPError=-2147217396

  4. Matt says:

    Hi Luis, I am a rookie at powershell. Could you example to me what I am suppose to fill in for the parameter ‘-Credential $ cred ‘ ? Thanks!

    1. Hi Matt!
      The parameter -Credential is used to run a cmdlet with other credentials.
      For example, imagine you want to run a new instance of PowerShell with other credential, you can run:
      $cred = Get-Credential #that cmdlet you ask you the credentials (username and password) and stores it in a variable
      start-process powershell.exe -credential $cred

      To more details, run the following cmdlet: get-help get-credential

      Did I answer your question?
      Regards

  5. John Grissom says:

    This is terrible in comparison to Linux’s ‘scp’ command. What were they thinking?

    1. Hi John,
      This is only one example about how to use the -Credentials option. If you already have permission, you don’t need to inform the -credential parameter.
      Regards,

  6. Juan Luis says:

    Hi Luis!! I am newer at PowerShell, I have a remote server in which I need to copy some local files. Is needed for the remote server to have shared folders?
    Best regards.

    1. Hi Juan,

      If you have an administrative account you can do that using administrative shares:

      Copy-Item -Path C:\temp\test.txt -Destination \\server1\c$\Shared

      But let suppose that the administrative share option is disabled. In this case, you can read the file content to a variable and create a new remote file using that content. I now, is not the best option. Anyway, here is the command:


      $fileContent = Get-Content C:\temp\local.txt -Raw
      Invoke-Command -ComputerName server1 -ScriptBlock {Set-Content -Path c:\temp\remote.txt -value $using:fileContent}

  7. Rob says:

    Does the -tosession option no longer exist? I don’t have that option for copy-item

    1. Hi Rob,
      The -ToSession parameter is available after the version 5.0 of Powershell.

      You can versify what is the PowerShell version that you are using through the following property:

      $host.Version


      Major Minor Build Revision
      ----- ----- ----- --------
      5 1 14393 693

      Please, run the follow command to get the syntax of copy-item cmdlet:
      get-command copy-item -syntax


      Copy-Item [-Path] [[-Destination] ] [-Container] [-Force] [-Filter ] [-Include ]
      -Exclude ] [-Recurse] [-PassThru] [-Credential ] [-WhatIf] [-Confirm] [-UseTransaction] [-FroSession ] [-ToSession ] []

      Copy-Item [[-Destination] ] -LiteralPath [-Container] [-Force] [-Filter ] [-Include ] [-Exclude ] [-Recurse] [-PassThru] [-Credential ] [-WhatIf] [-Confirm] [-UseTransaction]
      -FromSession ] [-ToSession ] []

Skip to main content