Копіюйте файл віддалено за допомогою PowerShell


93

Я пишу сценарій PowerShell, який хочу запустити з сервера А. Я хочу підключитися до сервера B і скопіювати файл на сервер A як резервну копію.

Якщо цього зробити не вдається, я хотів би підключитися до сервера B із сервера A і скопіювати файл в інший каталог на сервері B.

Я бачу Copy-Itemкоманду, але не бачу, як дати їй назву комп'ютера.

Я міг би подумати, що можу зробити щось подібне

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

Як я можу це зробити?


4
Для використання елемента копіювання вам доведеться використовувати шлях UNC, такий як "\\ ServerB \ C $ \ Programs \ temp \ test.txt"

Відповіді:


94

Просто використовуйте адміністративні спільні ресурси для копіювання файлів між системами. Таким чином набагато простіше.

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

Використовуючи шляхи UNC замість локальних шляхів файлової системи, ви допомагаєте забезпечити виконання вашого сценарію з будь-якої клієнтської системи з доступом до цих шляхів UNC. Якщо ви використовуєте локальні шляхи до файлової системи, то ви хочете запустити сценарій на певному комп'ютері.

Це працює лише тоді, коли сеанс PowerShell працює під користувачем, який має права на обидва адміністративні спільні ресурси.

Я пропоную використовувати звичайний спільний доступ до мережі на сервері B з доступом лише для читання для всіх і просто зателефонувати (із сервера A):

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

9
Однією з можливих проблем цього підходу є те, що Copy-Item не підтримує альтернативні облікові дані (якщо вам потрібно запустити команду з іншим користувачем). У цьому випадку потрібен підхід New-PSDrive.
Йорданія

1
Це рішення працює, лише якщо між хостами немає брандмауера, який блокує спільні ресурси UNC. У цьому випадку правильне рішення знаходиться нижче ( Copy-Item -FromSession).
Марк

85

Починаючи з версії PowerShell 5 (включена в Windows Server 2016, яку можна завантажити як частину WMF 5 для попередніх версій ), це можливо за допомогою віддаленого керування. Перевага цього полягає в тому, що він працює, навіть якщо з якихось причин ви не можете отримати доступ до спільних ресурсів.

Щоб це працювало, у локальному сеансі, де розпочинається копіювання, повинен бути встановлений PowerShell 5 або новішої версії. Для віддаленого сеансу не потрібно встановлювати PowerShell 5 - він працює з версіями PowerShell до 2, а версії Windows Server до 2008 R2. [1]

З сервера A створіть сеанс на сервер B:

$b = New-PSSession B

А потім, ще від А:

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

Копіювання елементів у B виконується за допомогою -ToSession. Зверніть увагу, що в обох випадках використовуються локальні шляхи; ви повинні відстежувати, на якому сервері ви перебуваєте.


[1]: під час копіювання з або на віддалений сервер, який має лише PowerShell 2, остерігайтеся цієї помилки в PowerShell 5.1 , що на момент написання означає, що рекурсивне копіювання файлів не працює -ToSession, очевидно, що копіювання не працює на все з -FromSession.


3
Я виявив, що для обох серверів не потрібно встановлювати PS 5. Я щойно провів успішний тест, де лише на вихідному сервері (Windows 10) був встановлений PS 5. Ціль була Windows Server 2012 R2 із встановленим PS за замовчуванням ($ PSVersionTable.PSVersion звітів 4).
Тейлор Бьюкенен

2
Якщо ви використовуєте -ToSession на джерелі, лише джерело потребує встановлення PS 5. Якщо ви використовуєте -FromSession на цілі, лише ціль потребує встановлення PS 5.
Тейлор Бьюкенен

1
Це також працює, коли у вас встановлений лише Hypervisor (без сервера), не потрібно налаштовувати спільні ресурси, просто використовуйте сеанси!
dashesy

Дякую! Приємне, елегантне рішення, подібне до scpтого, як sshу Linux ... не потрібно докучати з надокучливими акціями!
Тобіас Дж.

40

Використовуйте net useабо New-PSDriveдля створення нового диска:

New-PsDrive: створити новий PsDrive, видимий лише в середовищі PowerShell:

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

Користування мережею: створіть новий диск, видимий у всіх частинах ОС.

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

Якщо я запустив це двічі, я отримую New-PSDrive : A specified logon session does not exist. It may already have been terminated-> я думаю, що попередній сеанс все ще триває -> Отже, я спробував використати Remove-PSDrive-> все одно це не працює. Також net use <driveLetter> /deleteне допомогло. Будь-що інше, що я можу зробити, щоб я міг запустити цю команду в конфігурації збірки програмного забезпечення?
Bruno Bieri

Немає сенсу бігати New-PSDriveдва рази, ніж ви мали бA drive with the name 'Y' already exists.
JPBlanc

Я згоден, що немає сенсу запускати його двічі. Але це включено в крок збірки, і збірка виконується кілька разів на день. Тож мій підхід полягав у тому, щоб видалити накопичувач, коли я зробив потрібну мені роботу, і я припускав, що не буде проблемою відтворити його, як тільки відбудеться нове виконання збірки. Але це, здається, проблема. Будь-який інший натяк?
Бруно Бієрі

А як щодо тестування, якщо воно встановлене перед монтажем? або ви можете використовувати Remove-PSDrive у своєму сценарії, коли впевнені, що всі дескриптори, що використовують цей шлях, закриті.
JPBlanc,

16

Про всяк випадок, якщо для доступу до віддаленого файлу потрібні ваші облікові дані, ви можете сформувати об’єкт System.Net.WebClient, використовуючи командлет New-Object для "Копіювання файлу віддалено", наприклад

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

Або якщо вам потрібно завантажити файл, ви можете використовувати UploadFile:

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

$WebClient.UploadFile($Dest, $Source)

1
@klm_ Чи можете ви пояснити, що ви маєте на увазі?
FastTrack

0

Жодна з наведених відповідей не спрацювала для мене. Я постійно отримував цю помилку:

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

Отже, це зробило це для мене:

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

Тоді від мого хоста, на моїй машині в полі запуску, я щойно зробив це:

\\{IP address of nanoserver}\C$

1
Швидше за все, у вас виникли проблеми з дозволами файлової системи спільного доступу +. Пам'ятайте, що виграють найбільш обмежувальні дозволи, тому навіть якщо у вас є доступ на рівні файлової системи NTFS, якщо дозволи на спільний доступ обмежують вас, ви не зможете писати. :)
Тревор Салліван
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.