Copie o arquivo remotamente com PowerShell


94

Estou escrevendo um script do PowerShell que desejo executar do Servidor A. Desejo me conectar ao Servidor B e copiar um arquivo para o Servidor A como backup.

Se isso não puder ser feito, gostaria de me conectar ao Servidor B do Servidor A e copiar um arquivo para outro diretório no Servidor B.

Eu vejo o Copy-Itemcomando, mas não vejo como dar a ele um nome de computador.

Eu teria pensado que poderia fazer algo como

Copy-Item -ComputerName ServerB -Path C:\Programs\temp\test.txt -Destination (not sure how it would know to use ServerB or ServerA)

Como posso fazer isso?


4
Para usar Copy-Item, você terá que usar um caminho UNC como "\\ ServerB \ C $ \ Programs \ temp \ test.txt"

Respostas:


95

Basta usar os compartilhamentos administrativos para copiar arquivos entre sistemas. É muito mais fácil assim.

Copy-Item -Path \\serverb\c$\programs\temp\test.txt -Destination \\servera\c$\programs\temp\test.txt;

Usando caminhos UNC em vez de caminhos de sistema de arquivos locais, você ajuda a garantir que seu script seja executável de qualquer sistema cliente com acesso a esses caminhos UNC. Se você usar caminhos de sistema de arquivos locais, estará se preparando para executar o script em um computador específico.

Isso só funciona quando uma sessão do PowerShell é executada sob o usuário que tem direitos para ambos os compartilhamentos administrativos.

Eu sugiro usar compartilhamento de rede regular no servidor B com acesso somente leitura para todos e simplesmente chamar (do Servidor A):

Copy-Item -Path "\\\ServerB\SharedPathToSourceFile" -Destination "$Env:USERPROFILE" -Force -PassThru -Verbose

9
Um possível problema com essa abordagem é que Copy-Item não oferece suporte a credenciais alternativas (se você tiver que executar o comando com um usuário diferente). Nesse caso, a abordagem New-PSDrive é necessária.
Jordan

1
Esta solução só funciona se não houver firewall entre os hosts bloqueando compartilhamentos UNC. Nesse caso, a solução correta está abaixo ( Copy-Item -FromSession).
Marc

85

Do PowerShell versão 5 em diante (incluído no Windows Server 2016, para download como parte do WMF 5 para versões anteriores ), isso é possível com remoting. A vantagem disso é que funciona mesmo se, por qualquer motivo, você não puder acessar os compartilhamentos.

Para que isso funcione, a sessão local onde a cópia é iniciada deve ter o PowerShell 5 ou superior instalado. A sessão remota não precisa ter o PowerShell 5 instalado - funciona com versões do PowerShell tão baixas quanto 2 e versões do Windows Server tão baixas quanto 2008 R2. [1]

No servidor A, crie uma sessão para o servidor B:

$b = New-PSSession B

E então, ainda de A:

Copy-Item -FromSession $b C:\Programs\temp\test.txt -Destination C:\Programs\temp\test.txt

A cópia de itens para B é feita com -ToSession. Observe que os caminhos locais são usados ​​em ambos os casos; você tem que controlar em qual servidor você está.


[1]: ao copiar de ou para um servidor remoto que tem apenas PowerShell 2, cuidado com este bug no PowerShell 5.1 , que no momento da escrita significa que a cópia recursiva de arquivo não funciona com -ToSession, uma cópia aparentemente não funciona em todos com -FromSession.


3
Descobri que não é necessário que ambos os servidores tenham o PS 5 instalado. Acabei de realizar um teste bem-sucedido onde apenas o servidor de origem (Windows 10) tinha o PS 5 instalado. O destino era o Windows Server 2012 R2 com PS padrão instalado (relatórios $ PSVersionTable.PSVersion 4).
Taylor Buchanan,

2
Se você usar -ToSession na fonte, apenas a fonte precisa do PS 5 instalado. Se você usar -FromSession no destino, apenas o destino precisa do PS 5 instalado.
Taylor Buchanan

1
Isso também funciona quando você tem apenas o Hypervisor instalado (sem servidor), não há necessidade de configurar compartilhamentos, apenas use as sessões!
precipitado

Obrigado! Bom, solução elegante, semelhante a scpmais sshno Linux ... não há necessidade de se preocupar com ações traquinas!
Tobias J

40

Use net useou New-PSDrivepara criar uma nova unidade:

New-PsDrive: crie um novo PsDrive visível apenas no ambiente PowerShell:

New-PSDrive -Name Y -PSProvider filesystem -Root \\ServerName\Share
Copy-Item BigFile Y:\BigFileCopy

Uso líquido: crie uma nova unidade visível em todas as partes do sistema operacional.

Net use y: \\ServerName\Share
Copy-Item BigFile Y:\BigFileCopy

Se eu executar isso duas vezes, recebo New-PSDrive : A specified logon session does not exist. It may already have been terminated-> Acho que uma sessão anterior ainda está em andamento -> Então tentei usar Remove-PSDrive-> ainda não funciona. Também net use <driveLetter> /deletenão ajudou. Posso fazer mais alguma coisa para executar este comando em uma configuração de compilação de software?
Bruno Bieri

Não faz sentido correr New-PSDriveduas vezes que deveriaA drive with the name 'Y' already exists.
JPBlanc

Concordo que não faz sentido executá-lo duas vezes. Mas é incorporado a uma etapa de construção e a construção é executada várias vezes ao dia. Portanto, minha abordagem foi remover a unidade assim que fizesse o trabalho de que precisava e presumia que não haveria problema em recriá-la quando uma nova execução de compilação acontecesse. Mas parece um problema. Alguma outra dica?
Bruno Bieri

Que tal testar se ele está montado antes de montá-lo? ou você pode usar Remove-PSDrive em seu script quando tiver certeza de que todos os identificadores que usam esse caminho estão fechados.
JPBlanc

16

Apenas no caso de o arquivo remoto precisar de sua credencial para ser acessado, você pode gerar um objeto System.Net.WebClient usando o cmdlet New-Object para "Copiar arquivo remotamente", assim

$Source = "\\192.168.x.x\somefile.txt"
$Dest   = "C:\Users\user\somefile.txt"
$Username = "username"
$Password = "password"

$WebClient = New-Object System.Net.WebClient
$WebClient.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)

$WebClient.DownloadFile($Source, $Dest)

Ou se precisar fazer upload de um arquivo, você pode usar UploadFile:

$Dest = "\\192.168.x.x\somefile.txt"
$Source   = "C:\Users\user\somefile.txt"

$WebClient.UploadFile($Dest, $Source)

1
@klm_ Você pode explicar o que quer dizer?
FastTrack de

0

Nenhuma das respostas acima funcionou para mim. Continuei recebendo este erro:

Copy-Item : Access is denied
+ CategoryInfo          : PermissionDenied: (\\192.168.1.100\Shared\test.txt:String) [Copy-Item], UnauthorizedAccessException>   
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.CopyItemCommand

Então isso fez por mim:

netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=yes

Então, de meu host, minha máquina na caixa Executar, acabei de fazer isso:

\\{IP address of nanoserver}\C$

1
Provavelmente, você teve problemas com as permissões de compartilhamento + sistema de arquivos. Lembre-se de que as permissões mais restritivas vencem, portanto, mesmo que você tenha acesso na camada do sistema de arquivos NTFS, se as permissões de compartilhamento o restringirem, você não poderá escrever. :)
Trevor Sullivan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.