Copia il file in remoto con PowerShell


94

Sto scrivendo uno script PowerShell che desidero eseguire dal server A. Desidero connettermi al server B e copiare un file sul server A come backup.

Se ciò non può essere fatto, vorrei connettermi al server B dal server A e copiare un file in un'altra directory nel server B.

Vedo il Copy-Itemcomando, ma non vedo come assegnargli un nome di computer.

Avrei pensato di poter fare qualcosa di simile

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

Come posso fare questo?


4
Per usare Copy-Item dovrai usare un percorso UNC come "\\ ServerB \ C $ \ Programs \ temp \ test.txt"

Risposte:


96

Usa semplicemente le condivisioni amministrative per copiare i file tra i sistemi. È molto più facile in questo modo.

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

Utilizzando i percorsi UNC invece dei percorsi del file system locale, si aiuta a garantire che lo script sia eseguibile da qualsiasi sistema client con accesso a tali percorsi UNC. Se usi i percorsi del filesystem locale, ti stai impegnando per eseguire lo script su un computer specifico.

Funziona solo quando una sessione di PowerShell viene eseguita con l'utente che dispone dei diritti per entrambe le condivisioni amministrative.

Suggerisco di utilizzare una normale condivisione di rete sul server B con accesso in sola lettura a tutti e chiamare semplicemente (dal server A):

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

9
Un possibile problema con questo approccio è che Copy-Item non supporta credenziali alternative (se devi eseguire il comando con un utente diverso). In tal caso, è richiesto l'approccio New-PSDrive.
Jordan

1
Questa soluzione funziona solo se non è presente un firewall tra gli host che bloccano le condivisioni UNC. In tal caso la soluzione corretta è sotto ( Copy-Item -FromSession).
Marc

85

A partire dal versione 5 di PowerShell (inclusa in Windows Server 2016, scaricabile come parte di WMF 5 per le versioni precedenti ), questo è possibile con il telecomando. Il vantaggio di questo è che funziona anche se, per qualsiasi motivo, non è possibile accedere alle condivisioni.

Affinché funzioni, nella sessione locale in cui viene avviata la copia deve essere installato PowerShell 5 o versione successiva. La sessione remota fa non richiede l'installazione di PowerShell 5: funziona con versioni di PowerShell a partire da 2 e versioni di Windows Server a partire da 2008 R2. [1]

Dal server A, crea una sessione sul server B:

$b = New-PSSession B

E poi, sempre da A:

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

La copia degli elementi in B è terminata -ToSession . Notare che i percorsi locali vengono utilizzati in entrambi i casi; devi tenere traccia di quale server ti trovi.


[1]: quando si copia da o su un server remoto che ha solo PowerShell 2, fare attenzione a questo bug in PowerShell 5.1 , che al momento della scrittura significa che la copia ricorsiva dei file non funziona -ToSession, una copia apparentemente non funziona a tutto con -FromSession.


3
Ho scoperto che non è necessario che entrambi i server abbiano PS 5 installato. Ho appena eseguito un test di successo in cui solo il server di origine (Windows 10) aveva installato PS 5. L'obiettivo era Windows Server 2012 R2 con PS predefinito installato ($ PSVersionTable.PSVersion report 4).
Taylor Buchanan

2
Se usi -ToSession sulla sorgente, solo la sorgente necessita dell'installazione di PS 5. Se si utilizza -FromSession sul target, solo il target necessita dell'installazione di PS 5.
Taylor Buchanan

1
Funziona anche quando è installato solo Hypervisor (senza server), non è necessario configurare condivisioni, basta usare le sessioni!
dashesy

Grazie! Soluzione bella ed elegante, simile a scpover sshsu Linux ... non c'è bisogno di preoccuparsi di fastidiose condivisioni!
Tobias J

40

Usa net useo New-PSDriveper creare una nuova unità:

New-PsDrive: crea un nuovo PsDrive visibile solo in ambiente PowerShell:

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

Net use: crea una nuova unità visibile in tutte le parti del sistema operativo.

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

Se lo eseguo due volte ottengo New-PSDrive : A specified logon session does not exist. It may already have been terminated-> Penso che una sessione precedente sia ancora in corso -> Quindi ho provato a usare Remove-PSDrive-> ancora non funziona. Inoltre net use <driveLetter> /deletenon ha aiutato. Qualche altra cosa che posso fare in modo da poter eseguire questo comando in una configurazione di build software?
Bruno Bieri

Non ha senso correre New-PSDrivedue volte che dovresti avereA drive with the name 'Y' already exists.
JPBlanc

Sono d'accordo che non ha senso eseguirlo due volte. Ma è incorporato in una fase di compilazione e la compilazione viene eseguita più volte al giorno. Quindi il mio approccio era quello di rimuovere l'unità una volta eseguito il lavoro di cui avevo bisogno e pensavo che non sarebbe stato un problema ricrearlo una volta eseguita una nuova build. Ma sembra comunque un problema. Qualche altro suggerimento?
Bruno Bieri

Che ne dici di testare se è montato prima di montarlo? oppure puoi usare Remove-PSDrive nel tuo script quando sei sicuro che tutti gli handle che utilizzano questo percorso siano chiusi.
JPBlanc

16

Nel caso in cui il file remoto richieda le tue credenziali per accedere, puoi generare un oggetto System.Net.WebClient utilizzando il cmdlet New-Object su "Copia file in remoto", in questo modo

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

Oppure, se devi caricare un file, puoi utilizzare UploadFile:

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

$WebClient.UploadFile($Dest, $Source)

1
@klm_ Puoi spiegare cosa intendi?
FastTrack

0

Nessuna delle risposte precedenti ha funzionato per me. Ho continuato a ricevere questo errore:

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

Quindi questo ha fatto per me:

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

Quindi dal mio host la mia macchina nella casella Esegui ho appena fatto questo:

\\{IP address of nanoserver}\C$

1
È probabile che tu abbia riscontrato problemi con la condivisione e le autorizzazioni del filesystem. Ricorda che le autorizzazioni più restrittive vincono, quindi anche se hai accesso al livello del file system NTFS, se le autorizzazioni di condivisione ti limitano, non sarai in grado di scrivere. :)
Trevor Sullivan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.