PowerShell
Рассеивание Powershell
Поиск…
замечания
Включение PowerShell Remoting
Перенаправление PowerShell необходимо сначала включить на сервере, к которому вы хотите удаленно подключиться.
Enable-PSRemoting -Force
Эта команда выполняет следующие действия:
- Выполняет командлет Set-WSManQuickConfig, который выполняет следующие задачи:
- Запуск службы WinRM.
- Устанавливает тип запуска в службе WinRM для Automatic.
- Создает прослушиватель для приема запросов на любой IP-адрес, если он еще не существует.
- Включает исключение брандмауэра для связи WS-Management.
- Регистрирует конфигурации сеанса Microsoft.PowerShell и Microsoft.PowerShell.Workflow, если они еще не зарегистрированы.
- Регистрирует конфигурацию сеанса Microsoft.PowerShell32 на 64-разрядных компьютерах, если она еще не зарегистрирована.
- Включает все конфигурации сеанса.
- Изменяет дескриптор безопасности всех конфигураций сеанса, чтобы разрешить удаленный доступ.
- Перезагружает службу WinRM, чтобы сделать предыдущие изменения эффективными.
Только для не-доменных сред
Для серверов в домене AD аутентификация удаленного доступа PS выполняется через Kerberos («Default») или NTLM («Negotiate»). Если вы хотите разрешить удаленный доступ к серверу, отличному от домена, у вас есть два варианта.
Либо настройте WSMan-связь через HTTPS (для чего требуется генерация сертификата), либо включите базовую аутентификацию, которая отправляет ваши учетные данные через проводную base64-кодировку (это в основном то же самое, что и обычный текст, поэтому будьте осторожны с этим).
В любом случае вам придется добавить удаленные системы в список надежных хостов WSM.
Включение базовой проверки подлинности
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
Затем на компьютере вы хотите подключиться, вы обязательно должны сказать ему доверять компьютеру вы подключая к.
Set-Item WSMan:\localhost\Client\TrustedHosts '192.168.1.1,192.168.1.2'
Set-Item WSMan:\localhost\Client\TrustedHosts *.contoso.com
Set-Item WSMan:\localhost\Client\TrustedHosts *
Важно : вы должны сообщить своему клиенту, чтобы он доверял компьютеру, адресованному так, как вы хотите подключиться (например, если вы подключаетесь через IP-адрес, он должен доверять IP-адресу, а не имени хоста)
Подключение к удаленному серверу через PowerShell
Использование учетных данных с вашего локального компьютера:
Enter-PSSession 192.168.1.1
Запрос учетных данных на удаленном компьютере
Enter-PSSession 192.168.1.1 -Credential $(Get-Credential)
Выполнять команды на удаленном компьютере
После включения удаленного доступа Powershell (Enable-PSRemoting) Вы можете запускать команды на удаленном компьютере следующим образом:
Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Вышеупомянутый метод создает временный сеанс и закрывает его сразу после завершения команды или скриптового блока.
Чтобы оставить сеанс открытым и запустить в нем другую команду позже, сначала необходимо создать удаленный сеанс:
$Session = New-PSSession -ComputerName "RemoteComputerName"
Затем вы можете использовать этот сеанс каждый раз, когда вы вызываете команды на удаленном компьютере:
Invoke-Command -Session $Session -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Invoke-Command -Session $Session -ScriptBlock {
Get-Date
}
Если вам нужно использовать разные учетные данные, вы можете добавить их с -Credential
параметра -Credential
Parameter:
$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}
Удаление предупреждения о сериализации
Замечания:
Важно знать, что удаленная передача сериализует объекты PowerShell в удаленной системе и десериализует их в конце сеанса удаленного доступа, то есть они преобразуются в XML во время транспортировки и теряют все их методы.
$output = Invoke-Command -Session $Session -ScriptBlock {
Get-WmiObject -Class win32_printer
}
$output | Get-Member -MemberType Method
TypeName: Deserialized.System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(string format, System.IFormatProvi...
Если у вас есть методы на обычном объекте PS:
Get-WmiObject -Class win32_printer | Get-Member -MemberType Method
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
CancelAllJobs Method System.Management.ManagementBaseObject CancelAllJobs()
GetSecurityDescriptor Method System.Management.ManagementBaseObject GetSecurityDescriptor()
Pause Method System.Management.ManagementBaseObject Pause()
PrintTestPage Method System.Management.ManagementBaseObject PrintTestPage()
RenamePrinter Method System.Management.ManagementBaseObject RenamePrinter(System.String NewPrinterName)
Reset Method System.Management.ManagementBaseObject Reset()
Resume Method System.Management.ManagementBaseObject Resume()
SetDefaultPrinter Method System.Management.ManagementBaseObject SetDefaultPrinter()
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time)
SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)
Использование аргумента
Чтобы использовать аргументы в качестве параметров для удаленного сценария, можно использовать параметр ArgumentList
для Invoke-Command
или использовать синтаксис $Using:
Использование ArgumentList
с неназванными параметрами (то есть в том порядке, в котором они передаются скриптблоку):
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $args[0]
Remove-Item -Path $args[1] -ErrorAction SilentlyContinue -Force
}
Использование ArgumentList
с именованными параметрами:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Param($serviceToShowInRemoteSession,$fileToDelete)
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $serviceToShowInRemoteSession
Remove-Item -Path $fileToDelete -ErrorAction SilentlyContinue -Force
}
Использование $Using:
syntax:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
Get-Service $Using:servicesToShow
Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}
Лучшая практика для автоматической очистки PSSessions
Когда удаленный сеанс создается с помощью командлета New-PSsession
, PSSession сохраняется до окончания текущего сеанса PowerShell. Это означает, что по умолчанию PSSession
и все связанные ресурсы будут по-прежнему использоваться до окончания текущего сеанса PowerShell.
Несколько активных PSSessions
могут стать нагрузкой на ресурсы, особенно для длинных или взаимосвязанных сценариев, которые создают сотни PSSessions
в одном сеансе PowerShell.
Лучше всего явно удалить каждую PSSession
после ее окончания. [1]
Следующий шаблон кода использует try-catch-finally
для достижения вышеуказанного, объединяя обработку ошибок с надежным способом, чтобы все созданные PSSessions
были удалены, когда они были использованы:
try
{
$session = New-PSsession -Computername "RemoteMachineName"
Invoke-Command -Session $session -ScriptBlock {write-host "This is running on $ENV:ComputerName"}
}
catch
{
Write-Output "ERROR: $_"
}
finally
{
if ($session)
{
Remove-PSSession $session
}
}
Ссылки: [1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession