Kopieren Sie die Datei remote mit PowerShell

93

Ich schreibe ein PowerShell- Skript, das ich von Server A ausführen möchte. Ich möchte eine Verbindung zu Server B herstellen und eine Datei als Backup auf Server A kopieren.

Wenn dies nicht möglich ist, möchte ich von Server A aus eine Verbindung zu Server B herstellen und eine Datei in ein anderes Verzeichnis in Server B kopieren.

Ich sehe den Copy-ItemBefehl, aber ich sehe nicht, wie ich ihm einen Computernamen geben soll.

Ich hätte gedacht, ich könnte so etwas tun

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

Wie kann ich das machen?

chobo2
quelle
4
Um Copy-Item verwenden zu können, müssen Sie einen UNC-Pfad wie "\\ ServerB \ C $ \ Programme \ temp \ test.txt"

Antworten:

94

Verwenden Sie einfach die Administratorfreigaben, um Dateien zwischen Systemen zu kopieren. Auf diese Weise ist es viel einfacher.

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

Indem Sie UNC-Pfade anstelle lokaler Dateisystempfade verwenden, können Sie sicherstellen, dass Ihr Skript von jedem Client-System aus ausgeführt werden kann, das Zugriff auf diese UNC-Pfade hat. Wenn Sie lokale Dateisystempfade verwenden, müssen Sie das Skript auf einem bestimmten Computer ausführen.

Dies funktioniert nur, wenn eine PowerShell-Sitzung unter dem Benutzer ausgeführt wird, der über Rechte für beide Administratorfreigaben verfügt.

Ich schlage vor, die reguläre Netzwerkfreigabe auf Server B mit schreibgeschütztem Zugriff auf alle Benutzer zu verwenden und einfach anzurufen (von Server A):

Copy-Item -Path "\\\ServerB\SharedPathToSourceFile" -Destination "$Env:USERPROFILE" -Force -PassThru -Verbose
Trevor Sullivan
quelle
9
Ein mögliches Problem bei diesem Ansatz ist, dass Copy-Item keine alternativen Anmeldeinformationen unterstützt (wenn Sie den Befehl mit einem anderen Benutzer ausführen müssen). In diesem Fall ist der New-PSDrive-Ansatz erforderlich.
Jordanien
1
Diese Lösung funktioniert nur, wenn zwischen den Hosts keine Firewall vorhanden ist, die UNC-Freigaben blockiert. In diesem Fall ist die richtige Lösung unten ( Copy-Item -FromSession).
Marc
83

Ab PowerShell Version 5 (in Windows Server 2016 enthalten, als Teil von WMF 5 für frühere Versionen herunterladbar ) ist dies mit Remoting möglich. Dies hat den Vorteil, dass es auch dann funktioniert, wenn Sie aus irgendeinem Grund nicht auf Freigaben zugreifen können.

Damit dies funktioniert, muss in der lokalen Sitzung, in der das Kopieren gestartet wird, PowerShell 5 oder höher installiert sein. Die Remote - Sitzung ist nicht brauchen , um Powershell 5 installiert - es arbeitet mit Powershell - Versionen so niedrig wie 2 und Windows Server - Versionen so günstig wie 2008 R2. [1]

Erstellen Sie von Server A aus eine Sitzung zu Server B:

$b = New-PSSession B

Und dann noch von A:

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

Das Kopieren von Elementen nach B erfolgt mit -ToSession. Beachten Sie, dass in beiden Fällen lokale Pfade verwendet werden. Sie müssen verfolgen, auf welchem ​​Server Sie sich befinden.


[1]: Achten Sie beim Kopieren von oder auf einen Remote-Server, auf dem nur PowerShell 2 installiert ist, auf diesen Fehler in PowerShell 5.1. Dies bedeutet zum Zeitpunkt des Schreibens, dass das rekursive Kopieren von Dateien nicht funktioniert -ToSessionund das Kopieren anscheinend nicht funktioniert alle mit -FromSession.

Jeroen Mostert
quelle
3
Ich habe festgestellt, dass auf beiden Servern nicht PS 5 installiert sein muss. Ich habe gerade einen erfolgreichen Test durchgeführt, bei dem nur auf dem Quellserver (Windows 10) PS 5 installiert war. Das Ziel war Windows Server 2012 R2 mit installiertem Standard-PS ($ PSVersionTable.PSVersion-Berichte 4).
Taylor Buchanan
2
Wenn Sie -ToSession für die Quelle verwenden, muss nur auf der Quelle PS 5 installiert sein. Wenn Sie -FromSession auf dem Ziel verwenden, muss nur auf dem Ziel PS 5 installiert sein.
Taylor Buchanan
1
Dies funktioniert auch, wenn Sie Hypervisor nur installiert haben (ohne Server). Sie müssen keine Freigaben einrichten, sondern verwenden nur die Sitzungen!
Bindestrich
Danke dir! Schöner, elegante Lösung, ähnlich wie scpüber sshauf Linux ... keine Notwendigkeit , mit lästigen Aktien zu stören!
Tobias J
40

Verwenden Sie net useoder New-PSDrive, um ein neues Laufwerk zu erstellen:

New-PsDrive: Erstellen Sie ein neues PsDrive, das nur in der PowerShell-Umgebung sichtbar ist:

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

Nettonutzung: Erstellen Sie ein neues Laufwerk, das in allen Teilen des Betriebssystems sichtbar ist.

Net use y: \\ServerName\Share
Copy-Item BigFile Y:\BigFileCopy
JPBlanc
quelle
Wenn ich das zweimal ausführe, bekomme ich New-PSDrive : A specified logon session does not exist. It may already have been terminated-> Ich denke, eine vorherige Sitzung läuft noch -> Also habe ich versucht zu verwenden Remove-PSDrive-> es funktioniert immer noch nicht. Hat net use <driveLetter> /deleteauch nicht geholfen. Kann ich diesen Befehl auch in einer Software-Build-Konfiguration ausführen?
Bruno Bieri
Es hat keinen Sinn, New-PSDrivezweimal zu laufen, die Sie haben solltenA drive with the name 'Y' already exists.
JPBlanc
Ich bin damit einverstanden, dass es keinen Sinn macht, es zweimal auszuführen. Aber es ist in einen Build-Schritt integriert und der Build wird mehrmals am Tag ausgeführt. Mein Ansatz war es also, das Laufwerk zu entfernen, sobald ich die benötigte Arbeit erledigt hatte, und ich ging davon aus, dass es kein Problem sein würde, es neu zu erstellen, sobald eine neue Build-Ausführung erfolgt. Aber es scheint ein Problem zu sein. Irgendein anderer Hinweis?
Bruno Bieri
Was ist mit dem Testen, ob es montiert ist, bevor es montiert wird? oder Sie können Remove-PSDrive in Ihrem Skript verwenden, wenn Sie sicher sind, dass alle Handles, die diesen Pfad verwenden, geschlossen sind.
JPBlanc
16

Nur für den Fall, dass für den Zugriff auf die Remote-Datei Ihr Berechtigungsnachweis erforderlich ist, können Sie mit dem Cmdlet New-Object ein System.Net.WebClient- Objekt generieren, um die Datei remote zu kopieren

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

Wenn Sie eine Datei hochladen müssen, können Sie UploadFile verwenden:

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

$WebClient.UploadFile($Dest, $Source)
shyan1
quelle
1
@klm_ Kannst du bitte erklären was du meinst?
FastTrack
0

Keine der oben genannten Antworten hat bei mir funktioniert. Ich bekam immer wieder diesen Fehler:

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

Also das hat es für mich:

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

Dann habe ich von meinem Host auf meinem Computer in der Run-Box Folgendes getan:

\\{IP address of nanoserver}\C$
RogerW
quelle
1
Möglicherweise sind Sie auf Probleme mit den Berechtigungen für Share + Dateisystem gestoßen. Denken Sie daran, dass die restriktivsten Berechtigungen gewinnen. Selbst wenn Sie Zugriff auf die Ebene des NTFS-Dateisystems haben und die Freigabeberechtigungen Sie einschränken, können Sie nicht schreiben. :)
Trevor Sullivan