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:\temp\localfile.txt -Destination c:\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)}
I hope you have enjoyed.
Comments (25)
  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.


      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.


      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:

  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?

  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.

  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:


      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 ] []

  8. Lars Panzerbjørn says:

    Thanks for a good write-up 🙂
    One thing I have had a hard time figuring out, is how to copy a directory, and all sub-dirs + content…
    Could there be a simple solution I have just overlooked?

    1. Hi Lars, thanks for your great feedback.
      In this case, you can use the recursive parameter -recurse.

      PS C:\> $Session = New-PSSession -ComputerName “Server04” -Credential “Contoso\PattiFul”
      PS C:\> Copy-Item “D:\Folder003\” -Destination “C:\Folder003_Copy\” -ToSession $Session -Recurse

      I hope it helps.


  9. masa says:

    i’ve one question

    1. karthik says:

      how to copy file from one windows machine to another using powershell

  10. Lauren says:

    Article if very helpful. But you say nothing about the code necessary to create a directory on the target if it doesn’t exist.

    1. Thank you Lauren for the feedback.
      I will work on it.

  11. freimanmarc says:

    Hello Luis Henrique!
    First of all thank you very much for this quick tutorial,
    I have a question for you. What happens when I’m trying to connect to a remote server and transfer files over to my local machine/network. Do I have to run the script from the local machine or from the remote server?
    Would I use this as well?:
    PS C:\> $Session = New-PSSession -ComputerName “Server04” -Credential “Contoso\PattiFul”
    PS C:\> Copy-Item “D:\Folder003\” -Destination “C:\Folder003_Copy\” -ToSession $Session -Recurse

    Is it 100% necessary for the credentials to be set to administration mode?

    1. Thank you for the feedback.

      You can run the script on the client side and open a session to the destination computer using New-PSSession command.

      It is not necessary to inform the credentials, in case you are in the same domain and the credential that you are using has admin access.

      Let me know it helped you.

      1. freimanmarc says:

        Hello Luis Henrique,

        Thank you for the reply, I don’t think I’m going to be able to get administrator access to the server where the files live since it’s the database server.
        What I want is to use a -FromSession since it will be easier to be granted administrator access from the local machine.
        Also, I want to use a -Recurse for it to override everytime it runs as data will keep being added to the db.

  12. santosh0047 says:

    found errors in your second command, please update

    Copy-Item -Path c:\processos.txt -Destionation c:\temp\localfile.txt

    Destionation : has a typo, should be Destination

    you are copying c:\processos.txt to “c:\temp\localfile.txt”, i believe you want to do opposite as c:\processos.txt does not exists at this moment.

    correct command:

    Copy-Item -Path c:\temp\localfile.txt -Destination c:\processos.txt

    1. Thank you for letting me know. I will fix it.

Comments are closed.

Skip to main content