У меня возникают проблемы с выполнением удаленного сценария PowerShell, который должен обновлять установку приложения для автоматического тестирования в задаче диспетчера задач, выполняемой один раз в день.
Довольно простой скрипт (подробности ниже) успешно работал около года. Внезапно он начал давать сбой, потому что удаленный сценарий PowerShell не мог быть выполнен. Я понятия не имею, в чем основная причина этого. Местные ИТ-службы следят за тем, чтобы они ничего не меняли.
(Должен отметить, что я, вероятно, могу заменить сценарий PowerShell чем-то другим, но я не собираюсь отказываться от этого легко. Кроме того, я хотел бы понять, что здесь не так)
Вот общая настройка:
Виртуальная машина Windows Server 2008 R2, не подключенная к домену, называется целевой. Локальный пользователь u_target
назначен группе администраторов на цели.
Виртуальная машина Windows Server 2008 R2 в домене (назовем домен D), называемая источником. Пользователь домена D u_source
назначен группе администраторов источника.
Powershell имеет версию 2.0 на обеих виртуальных машинах.
Все команды на цели выполняются u_target
с правами администратора, все команды в источнике выполняются u_source
с правами администратора. Я трижды проверил, что PowerShell запускается от имени администратора во всех случаях.
Около года назад я включил psremoting на обеих виртуальных машинах следующим образом:
На цели u_target выполняется в административной оболочке. enable-psremoting -force
и set-item wsman:\local\client\TrustedHosts -value 'source'
После этого машина была перезагружена.
Обе команды были выполнены без ошибок. Позже, когда я столкнулся с проблемой, я заменил «источник» на *, чтобы убедиться, что проблема не связана с опечаткой.
По источнику, u_source
выполняется в административной оболочке PowerShell enable-psremoting -force
. Эта машина тоже была перезагружена.
Позже, когда что-то не удалось, цель была добавлена и в TrustedHosts здесь.
Скрипт, который предполагается выполнить, в принципе выглядит следующим образом:
$server = 'target' #(using the FQHN)
$username = 'u_target'
$password = 'u_targetpwd' #(the correct one, of course)
$pass = ConvertTo-SecureString -AsPlainText $password -Force
$Cred = New-Object System.Management.Automation.PSCredential -Argumentlist $username,$pass
$scbScriptBlock = {
# a valid script. For simplicity assume it's
Get-ChildItem C:\
}
Invoke-Command -ComputerName $server -Credential $Cred -ScriptBlock $scbScriptBlock
Это приводит к тому, что примерно через неделю появляется следующее сообщение об ошибке:
[target] Connecting to remote server failed with following error messages :
The connection to the specified remote host was refused. Verify that the
WS-Management service is running on the remote host and configured to
listen for requests on the correct port and HTTP URL. For more information,
see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo : OpenError: (:) [], PSRemotingTransportException
+ FullyQualifiedErrorID : PSSessionStateBroken
Что я пытался исправить или разобраться в чем дело:
Итак, вот мои вопросы:
конечно, этот ;-): вы хоть представляете, что могло вызвать внезапный сбой скрипта ???
В чем я не уверен, так это в том, что WS-Management прослушивает порт и URL-адрес HTTP. Как мне это проверить? Я выполнил команду «winrm enumerate winrm / config / listener», потому что мне было сказано сделать это в каком-то старом сообщении в событии, и я заметил, что имя хоста кажется неопределенным. Кажется, что для CertificateThumbprint тоже нет значения, но Transport - это HTTP.
Еще несколько абсурдных идей, которые мне пришли в голову, может быть, не слишком абсурдные (?):
В моем случае проблема была вызвана тем, что прокси-сервер winhttp, установленный на клиенте PS-Remoting, получал ошибку «соединение отклонено»:
netsh winhttp show proxy
Все, что мне нужно было сделать, это удалить его:
netsh winhttp reset proxy
Вы можете подтвердить порт, который он настроен для прослушивания, с помощью команды: winrm get winrm/config
. Это будет включать в себя такую информацию, как доверенные адреса / хосты, если источником является ручная конфигурация или GPO (который переопределит вашу конфигурацию), и включена ли проверка подлинности сертификата.
Проверьте журнал событий удаленного управления / операций Windows на исходном и целевом серверах. Ведение журнала слабое, но если есть ошибка, она может быть записана туда.
Netstat должен подтвердить порт прослушивания (5985 в приведенном ниже примере):
netstat -ano | findstr /i ":598"
TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING 4
TCP 192.168.1.132:49223 192.168.1.131:5985 ESTABLISHED 972
TCP [::]:5985 [::]:0 LISTENING 4
Также было бы полезно, если бы вы выполнили захват пакета netmon как на источнике, так и на цели, чтобы подтвердить, какая сетевая активность происходит.
Вы можете получить больше информации об этом виде проблемы, если включите опцию трассировки для поставщика WSMan (по крайней мере, на исходном сервере, возможно, также на удаленном). Без этого не очень много логируется. Чтобы включить ведение журнала трассировки:
Import-Module PSDiagnostics
Enable-PsWsmanCombinedTrace
<run your script>
Disable-PsWsmanCombinedTrace
Просмотрите журнал событий PowerShell (Журналы приложений и служб / Microsoft / Windows / PowerShell / Operational)
Если WinRM использовал SSL, сертификат должен быть в личной учетной записи компьютера.