我在执行远程PowerShell脚本时遇到问题,该脚本应该在每天运行一次的任务pipe理器任务中更新应用程序的安装以进行自动化testing。
相当简单的脚本(下面的细节)用于成功运行约一年。 突然间,它开始失败,因为远程PowerShell脚本不能执行。 我不知道这是什么根源。 本地IT确保他们没有改变任何东西。
(我应该注意,我可以用别的东西来代替powershell脚本,但是我不打算轻易放弃,除此之外,我想知道这里有什么问题)
以下是一般设置:
未连接到域的Windows Server 2008 R2虚拟机称为目标。 在目标上分配给pipe理员组的本地用户u_target 。
域(称为域D)中的Windows Server 2008 R2虚拟机称为源。 分配给源上的pipe理员组的域D用户u_source 。
Powershell在两个虚拟机上都有2.0版本。
目标上的所有命令u_target具有pipe理权限的u_target执行,所有源上的命令u_source具有pipe理权限的u_source执行。 我三重检查,powershell已经开始作为pipe理员在所有情况下。
大约一年前,我在两台虚拟机上启用了psremoting,如下所示:
在目标上,u_target在admin中执行powershell enable-psremoting -force和set-item wsman:\local\client\TrustedHosts -value 'source' enable-psremoting -force set-item wsman:\local\client\TrustedHosts -value 'source'之后机器重新启动。
两个命令都没有任何错误地执行。 后来,当我遇到麻烦时,我用*replace了“来源”,以确保问题不是由于打字错误造成的。
在源代码中, u_source在admin 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
我试图解决这个问题或找出什么是错的:
所以这是我的问题:
当然,这一个;-):你有什么想法可能导致脚本突然失败?
我不确定的事情是端口和HTTP URL WSpipe理正在监听,我将如何检查? 我执行了'winrm enumerate winrm / config / listener',因为事件中的一些旧消息告诉我这样做,我注意到这里的主机名似乎是未定义的。 CertificateThumbprint似乎也没有任何价值,但Transport是HTTP。
我想到的一些更荒谬的想法可能不是太荒谬(?):
如果为WSMan提供程序启用跟踪选项(至less在源服务器上,可能还有远程),则可能能够获得有关此类问题的更多信息。 没有这个,没有太多logging。 要启用跟踪logging:
Import-Module PSDiagnostics Enable-PsWsmanCombinedTrace <run your script> Disable-PsWsmanCombinedTrace
查看PowerShell事件日志(Applications and Services Logs / Microsoft / Windows / PowerShell / Operational)
如果WinRM使用SSL,证书应该在计算机帐户中进行个人访问。
您可以使用以下命令确认configuration为侦听的端口: winrm get winrm/config 。 这将包括如信任的地址/主机,如果源是手动configuration或GPO(这将覆盖您的configuration),并且如果启用证书身份validation的信息。
检查源服务器和目标服务器上的Windows远程pipe理/操作事件日志。 日志logging很薄弱,但如果有错误,可能会logging在那里。
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数据包捕获以确认发生了什么networking活动,这也将有所帮助。