В Powershell реализована возможность подключать сетевые диски используя протоколы SMB/CIFS. Эта возможность использует разные команды работа с которыми может вызвать сложности. Рассмотрим применение команд на примерах.
Как работают в Powershell сетевые диски
В Powershell по умолчанию существует возможность обратиться по сетевому пути не используя сетевые диски. Например это можно сделать через команду 'Get-ChildItem':
Get-ChildItem -Path '\\localhost\c$'
Такой способ ограничен пользователем, который открыл консоль или запустил скрипт. Если вы запустите консоль от имени доменного администратора - то обращение к сетевому пути будет от его имени.
Возможность использовать другие учетные записи, а так же подключать сетевые диски, реализованы в 2 командах:
- New-SmbMapping - команда появилась в версии Powershell 5. Относится к модулю SmbShare, то есть создана специально для работы с SMB;
- New-PSDrive - работает с версии Powershell 3. Все командлеты типа 'PSDrive' относятся ко всем дискам.
Обе команды, аналогично Get-ChildItem, подключают диски под учетной записью, которая запустила консоль.
Хоть эти команды достаточно старые, в каждой из новых версий Powershell находятся ошибки и баги. На момент написания статьи баги были найдены в версиях 5.1 - 7.1 и все они касались процесса подключения.
Основной момент, который упростит работу с сетевыми папками в Powershell кроется в понимании понятии провайдеров. Создавая сетевой диск обычными средствами Windows вы сразу видите результат в проводнике. Делая то же самое в Powershell вы изначально обращаетесь к провайдеру услуг, а он обращается к Windows. В зависимости от указанных вами параметров и возможностью команды у вас может быть создан диск только в рамках этого провайдера либо в рамках провайдера и области Windows.
Если это сложно понять, то представьте, что среда Windows и Powershell это разные вещи и что бы скопировать файл с одного места на другое - нужно использовать дополнительный параметр, которого может и не быть.
Получение списка сетевых дисков и их удаление
Мы можем получить список сетевых дисков используя обе команды модуля:
Get-PSDrive
Get-SmbMapping
Отличия, которые видны на первый взгляд в том, что во втором случае мы возвращаем список дисков подключение к которым не восстановилось. Кроме этого 'Get-SmbMapping' хранит больше информации о дисках, если вывести их все:
Get-PSDrive -Name 'G' | select *
Get-SmbMapping -LocalPath 'G:' | select *
Мы можем вывести учетную запись, под которой подключена сетевая папка, следующим образом:
(Get-PSDrive -Name 'G').Credential
Команды удаления отличаются только наличием параметра 'UpdateProfile'. Если он присутствует в команде 'Remove-SMBMapping', то диск не будет восстанавливать соединение после перезагрузки компьютера. В случае с Remove-PSDrive это предусмотрено автоматически:
Remove-SmbMapping -LocalPath 'G:' -UpdateProfile -Force
Remove-PSDrive -Name 'J' -Force
Force удаляет подключение без подтверждения.
Подключение сетевых дисков
Проблемы с командами могут зависеть от версии вашего интерпретатора. Powershell 5-ой версии был предустановлен во всех версиях начиная с Windows 10 и Windows Server 2016. Если вы сомневаетесь в версии, то это можно проверить следующей командой:
$PSVersionTable
# или
host
New-SmbMapping
Самый простой способ подключить диски, используя команду New-SmbMapping, будет выглядеть следующим способом:
New-SmbMapping -LocalPath 'J:' -RemotePath '\\192.168.2.200\SharedFolder' -Persistent $true
В этой команде используются следующие ключи:
- LocalPath - локальный путь или буква, под которой будет подключен диск;
- RemotePath - путь к папке через IP или DNS. В случае выше подразумевается, что у пользователя, который открыл консоль Powershell, есть права для подключения к этому пути. Важно так же обратить внимание на кавычки, если ваш путь содержит специальные символы;
- Persistent - дословно переводится как 'постоянный', но в случае сетевых папок обозначает восстановление соединения после отключения сети/компьютера.
Пример выше специально демонстрирует проводник так как это одна из проблем этой команды в версии 5.1 - диск начнет отображаться в проводнике только после перезагрузки компьютера или перезапуске процесса 'explorer.exe'.
Мы можем перезапустить процесс средствами Powershell. Выполнение этой команды, как минимум, закроет все открытые окна:
Stop-Process -Name 'explorer' | Start-Process -FilePath 'C:\Windows\explorer.exe'
Так же у вас могут появиться другие ошибки, например следующие говорят об уже занятой букве:
- New-SmbMapping : Имя локального устройства уже используется.
- New-SmbMapping : The local device name is already in use.
Следующая ошибка произойдет, если вы указали слэш '\' в конце пути или к нему нет доступа на уровне сети (фаерволла, dns, политик и т.д.):
- New-SmbMapping : The network name cannot be found.
New-PSDrive
В отличие от предыдущего способа - у него нет проблем с проводником, но после перезагрузки компьютера подключение к диску пропадет. Как я прочитал в каких-то версиях Powershell это исправлено, в каких-то появились новые проблем. Один из способов сделать диск постоянным - будет рассмотрен ниже.
Подключить аналогичный диск можно следующим способом:
New-PSDrive -Name 'G' -PSProvider 'FileSystem' -Root '\\192.168.2.200\SharedFolder' -Persist -Scope 'Global'
Где:
- Name - путь, буква или любой другой идентификатор определяющий диск. Чаще всего это просто буква;
- PSProvider - поставщик услуг. Всех поставщиков услуг можно увидеть через 'Get-PSProvider'. В большинстве случаев поставщиком услуг для сетевых дисков будет 'FileSystem'. В теории вы можете использовать поставщика "Registry" что бы в рамках сессии Powershell легче обращаться к какому-то пути. Поставщик услуг или 'PSProvider' - это условная программа, которая будет обрабатывать вашу команду между Powershell и Windows;
- Root - путь до удаленной папки. Если бы в 'PSProvider' стоял 'Registry', то тут можно было указать путь следующего формата: 'HKLM:\Software\Microsoft';
- Persist - должно ли восстанавливаться подключение при потере связи;
- Scope - область действия диска. В этом случае не должно играть значение, но на форумах советуют использовать значение 'Global', если не получается подключать диск. Если бы вы использовали сетевой диск только для одно сессии Powershell - вы могли бы ограничить область видимости диска.
У вас могут появиться следующие ошибки:
- New-PSDrive : The network resource type is not correct;
- The specified network resource or device is no longer available.
Один из способов решения - убрать слэш в конце пути. Так же попробуйте открыть полный путь в проводнике так как ошибка может указывать на недоступность папки. Так же можете попробовать убрать параметр 'Persist', т.к. после этого ошибка может изменится и принять более понятный характер.
Рабочий способ сделать этот диск постоянным - отредактировать его через реестр. Ветка, под которой был подключен диск, будет иметь следующий путь ''HKCU:\Network\G". "G" в конце - это буква под который был подключен диск. Мы можем вернуть существующие значения следующей командой:
Get-ItemProperty -Path 'HKCU:\Network\G'
Вам нужно обратить внимание на выделенные фрагменты. 'DeferFlags', в значении 4, обозначает, что диск подключается под логином и паролем аутентифицированного пользователя. 1-ца говорит об обратном и, возможно, что пароль не указан. На одном из форумов писали, что это поле должно указывать на цифру 4 что бы команда успешно работала. Я наблюдал случаи с 1 и 4, но проблем не замечал.
Моя проблема была решена после указания 1 в поле 'ConnectionType'. Значение 1 говорит, что будет выполняться перенаправление дисков. Установить это значение через Powershell можно так:
Set-ItemProperty -Path 'HKCU:\Network\G' -Name 'ConnectionType' -Value 1
Подключение дисков под другим пользователем
Обе команды позволяют выполнять подключение используя других пользователей. Для каждой из команд этот подход отличается.
В случае команды 'New-PSDrive' вам нужно будет выполнить 'Get-Credential' и поместить в него учетные данные. Традиционный способ поместить эти данные в переменную:
$сred = Get-Credential
Эта переменная будет хранить ссылку на объект в памяти, который нельзя будет экспортировать на другой компьютер. Как упростить процесс, если вы планируете использовать учетные данные на разных компьютерах, рассмотрено в другой статье.
После этого мы передаем переменную в параметр '-Credential':
New-PSDrive -Credential $cred -Name 'G' -PSProvider 'FileSystem' -Root '\\192.168.2.200\SharedFolder' -Persist -Scope 'Global'
В случае с 'New-SMBMapping' эта операция выполняется проще. У вас есть 3 параметра, которые нужно заполнить:
- UserName - логин;
- Password - пароль;
- SaveCredential - нужно ли сохранять учетные данные.
Пример подключения с сохранением учетных данных:
$password = '123'
$username = 'admin@domain.local'
New-SmbMapping -Username $username -Password $password `
-LocalPath 'J:' -RemotePath '\\192.168.2.200\SharedFolder' `
-Persistent $true -SaveCredentials
Проблема, которую не получилось решить на разных версиях Powershell, связана с параметром '-SaveCredentials'. Его указание приводит к ошибке "New-SmbMapping : The parameter is incorrect.". Его отсутствие - не сохраняет введенные учетные данные и после перезагрузки связь с диском может пропасть если не добавить соответствующую запись в 'Credential Manager'.
Подключение дисков удаленно
Каждая из команд может выполняется удаленно. У команды 'New-SMBMapping' для этого есть встроенный параметр 'CimSession'. В случае обоих подходов можно использовать команды из модуля PSRemoting, например 'Invoke-Command'. Нужно отметить, что сетевые папки в Powershell всегда подключаются под тем пользователем, под которым была запущена консоль или скрипт. Если вы были аутентифицированы под пользователем 'alex' и открыли консоль Powershell, то диски будут подключены пользователю 'alex'. Кроме этого, для каждой команды у вас должен быть запущен WinRM и установлены настройки в TrustedHost.
Пример команды, которая подключит диск у пользователя:
# Вводим логин и пароль пользователя
# который имеет право подключаться к удаленному компьютеру
$cred = Get-Credential
# Устанавливаем сессию с удаленным компьютером
$session = New-CimSession -Credential $cred -ComputerName 192.168.2.111
# Через созданную сессию подключаем сетевой диск
New-SmbMapping -LocalPath S: -RemotePath "\\192.168.2.200\admin2" -CimSession $session
Для обеих команд подойдет следующий способ:
# Вводим логин и пароль пользователя
# который имеет право подключаться к удаленному компьютеру
$cred = Get-Credential
# Используем учетные данные для выполнения команды
Invoke-Command -ComputerName '192.168.2.111' -Credential $cred -ScriptBlock {
New-PSDrive -Name 'G' -PSProvider 'FileSystem' -Root '\\192.168.2.200\SharedFolder' -Persist -Scope 'Global'
}
...
Подписывайтесь на наш Telegram канал
Теги: #powershell