Partager via


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

copyitem

I hope you have enjoyed.

Comments

  • Anonymous
    August 31, 2016
    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.
    • Anonymous
      August 31, 2016
      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. :)
  • Anonymous
    September 02, 2016
    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.
    • Anonymous
      September 03, 2016
      Thank you for this great feedback!!!
  • Anonymous
    October 20, 2016
    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?
    • Anonymous
      October 20, 2016
      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-PSRemotingTo suppress all user prompts, type: Enable-PSRemoting -ForceOn 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\TrustedHostsTo 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.comIn the client computer, you need to change a configuration to trust on the remote computer. YouTake a look at this article to more details:https://technet.microsoft.com/en-us/library/hh847850.aspx?f=255&MSPPError=-2147217396
  • Anonymous
    January 12, 2017
    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!
    • Anonymous
      January 12, 2017
      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 variablestart-process powershell.exe -credential $cred To more details, run the following cmdlet: get-help get-credentialDid I answer your question?Regards
  • Anonymous
    February 06, 2017
    This is terrible in comparison to Linux's 'scp' command. What were they thinking?
    • Anonymous
      February 06, 2017
      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,
  • Anonymous
    March 15, 2017
    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.
    • Anonymous
      March 16, 2017
      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 -RawInvoke-Command -ComputerName server1 -ScriptBlock {Set-Content -Path c:\temp\remote.txt -value $using:fileContent}
  • Anonymous
    March 16, 2017
    Does the -tosession option no longer exist? I don't have that option for copy-item
    • Anonymous
      March 16, 2017
      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.VersionMajor Minor Build Revision----- ----- ----- --------5 1 14393 693Please, run the follow command to get the syntax of copy-item cmdlet:get-command copy-item -syntaxCopy-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 ] []
  • Anonymous
    July 25, 2017
    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?
    • Anonymous
      July 26, 2017
      Hi Lars, thanks for your great feedback.In this case, you can use the recursive parameter -recurse.Example:PS C:> $Session = New-PSSession -ComputerName "Server04" -Credential "Contoso\PattiFul"PS C:> Copy-Item "D:\Folder003" -Destination "C:\Folder003_Copy" -ToSession $Session -RecurseI hope it helps.Regards,
  • Anonymous
    October 18, 2017
    i've one question
    • Anonymous
      August 22, 2018
      how to copy file from one windows machine to another using powershell
  • Anonymous
    November 04, 2018
    Article if very helpful. But you say nothing about the code necessary to create a directory on the target if it doesn't exist.
    • Anonymous
      November 14, 2018
      Thank you Lauren for the feedback.I will work on it.
  • Anonymous
    December 11, 2018
    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 -RecurseIs it 100% necessary for the credentials to be set to administration mode?
    • Anonymous
      December 11, 2018
      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.
      • Anonymous
        December 11, 2018
        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.
  • Anonymous
    January 11, 2019
    found errors in your second command, please updateCopy-Item -Path c:\processos.txt -Destionation c:\temp\localfile.txtDestionation : 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
    • Anonymous
      January 11, 2019
      Thank you for letting me know. I will fix it.