PowerShell 远程调用神秘挂起

PowerShell remote invocation mysteriously hangs

我创建了一系列函数,这些函数基本上收集了关于一个站点的所有 IIS 配置,当 运行 在本地服务器上时它执行没有问题(尽管很慢)但是当我 运行 它们远程使用 PowerShell 2 中的 invoke-command 它 运行 完成并神秘地停止了大约 15-20 秒的过程。它通常会根据相同的请求停止,但并非总是如此。在本地执行的相同命令可以毫无问题地工作。没有引发异常,它只是无限期地挂起。

如果需要,我可以 post 代码,但是它有几百行,所以我更想寻找有关如何调查此类问题或是否有人遇到过类似问题的指导。

Comparing IISConfig between [targetserver] and localhost.
Checking Installed IIS version on [targetserver]:
IIS major version : 7
IIS minor version : 5
IIS7+ detected, using WebAdmin module and IIS metabase

Name                                                        Value
----                                                        -----
name                                                        Default Web Site
id                                                          1
serverAutoStart                                             True
state                                                       1


Site Configuration:

Name        Path        PSPath      Handlers_Ac Access_sslF Asp_AppAllo Asp_AppAllo Asp_limits_ Asp_EnableP Asp_limits_
                                    cessFlags   lags        wClientDebu  wDebugging bufferingLi  arentPaths queueTimeou
                                                                      g                     mit             t
----        ----        ------      ----------- ----------- ----------- ----------- ----------- ----------- -----------
Default ... IIS:Site... WebAdmin... Read,Script                   False       False    25000000        True 00:00:00


WebApp VDir: /MyApp, App Pool: MyApp
App pool Configuration:

AppPoolID   Enable32Bit managedPipe managedRunt AppPoolName AppPoolAuto processMode processMode processMode recycling_l
             AppOnWin64 lineMode    imeVersion                    Start l_idleTimeo l_identityT l_UserName  ogEventOnRe
                                                                        ut          ype                     cycle
---------   ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
                  False Classic     v2.0        MyApp                True 00:20:00    LocalSer...             Time,Req...


Analyzing web directories for /MyApp, this could take a while....
Initial Collection Completed, found 141... took 0.9516122 seconds
0 C:\inetpub\wwwroot\MyApp\Core
1 C:\inetpub\wwwroot\MyApp\Core\AdminTools
2 C:\inetpub\wwwroot\MyApp\Core\AdminTools\Cache
3 C:\inetpub\wwwroot\MyApp\Core\AdminTools\Extra
4 C:\inetpub\wwwroot\MyApp\Core\AdminTools\HTTPPostTest
5 C:\inetpub\wwwroot\MyApp\Core\AdminTools\IISAdmin
6 C:\inetpub\wwwroot\MyApp\Core\AdminTools\Profiling
7 C:\inetpub\wwwroot\MyApp\Core\AdminTools\RecordTestData
8 C:\inetpub\wwwroot\MyApp\Core\AdminTools\ScrambleTest
9 C:\inetpub\wwwroot\MyApp\Core\AdminTools\Sessions
Analyzed 10 so far... took 6.7236862 seconds, remaining time 88.08028922 seconds
Current Folder: C:\inetpub\wwwroot\MyApp\Core\AdminTools\Sessions
10 C:\inetpub\wwwroot\MyApp\Core\AdminTools\SoapTest
11 C:\inetpub\wwwroot\MyApp\Core\AdminTools\StaticContent

有时会达到 15 左右。我尝试从我的笔记本电脑和从一台服务器到另一台服务器,行为是一样的。

这是挂起的循环:

$start = [System.DateTime]::Now
$numanalyzed = 0
if ($true) #skip to test
{
# loop through all physical folders as it is much faster
foreach ($folder in $folders)
{

    write-host $numanalyzed $folder.fullname
    #figure out the virtual path to the folder
    $iis7vwebfolderpath = $folder.FullName.Replace($iis7webapp.PhysicalPath, $iis7VDirWebApppath)
    #Get-item $iis7vwebfolderpath | gm
    $iis7VWebDirConfigItem = Get-LNOSIIS7ConfigForPSPath -PSPath $iis7vwebfolderpath

    # add new item to list
    $iis7VWebDirConfig += $iis7VWebDirConfigItem

    # increment counter and report out progress every 10
    $numAnalyzed++
    if ($numanalyzed % 10 -eq 0) 
    {

       $end = [System.DateTime]::Now
       $timeSoFar = (NEW-TIMESPAN –Start $Start –End $End).TotalSeconds
       $timeremaining = ($folders.Count - $numAnalyzed) * ($timeSoFar / $numanalyzed)
       "Analyzed {0} so far... took {1} seconds, remaining time {2} seconds" -f $numanalyzed,$timeSoFar,$timeremaining  | write-host 
       "Current Folder: {0}" -f $folder.FullName | Write-Host
    }
}
}



$end = [System.DateTime]::Now
"Processed web dirs: {0} took {1} seconds" -f $iis7VWebDirConfig.Count,(NEW-TIMESPAN –Start $Start –End $End).TotalSeconds | write-host   | Write-Host

我遇到性能问题的函数,我有一个单独的问题,但是这个 post 有函数的源代码:

web-administration vs WMI to query web directory properties performance problems

我想我可能已经发现了问题,我开始在脚本的其他部分出现一些奇怪的故障:

 [SEVERNAME] Processing data from remote server SERVERNAME failed with the following error message: The WSMan provider host process did not return a proper response.  A provider in the host process may have behaved improperly. For more information, see the about_Remote_Troubleshooting Help topic. 
 + CategoryInfo          : OpenError: (SERVERNAME:String) [], PSRemotingTransportException
 + FullyQualifiedErrorId : 1726,PSSessionStateBroken

Processing data for a remote command failed with the following error message: Not enough storage is available to complete this operation. For more information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo          : OperationStopped (System.Manageme...pressionSyncJob:PSInvokeExpressionSyncJob) [], PSRemotingTransportException
+ FullyQualifiedErrorId : JobFailure

这将我带到以下站点:http://www.gsx.com/blog/bid/83018/Troubleshooting-unknown-PowerShell-error-messages

虽然我还有一些测试要做,但以下建议似乎已经解决了大部分问题。

摘自以下网站:

正如第一条错误消息所指出的,远程会话中发生了内存溢出。在远程服务器上打开 PowerShell 提示符并使用以下命令显示 winrs 的配置:

winrm get winrm/config/winrs

检查 "MaxMemoryPerShellMB" 值。在 Windows Server 2008 R2 和 Windows 7 上默认设置为 150 MB。这是 Microsoft 在 Windows Server 2012 和 Windows 8 中更改为 1024 MB。

为了解决这个问题,您需要使用以下命令将该值增加到至少 512 MB:

winrm set winrm/config/winrs `@`{MaxMemoryPerShellMB=`"512`"`}

就我而言,我的 PowerShell 调用似乎由于空闲超时过期而冻结(调用运行了很长时间)。

IdleTimeout 值设置为足够长的持续时间解决了我的问题。

再次使用

查询当前配置
winrm get winrm/config/winrs

并使用

设置超时
winrm set winrm/config/winrs '@{IdleTimeout="18000000"}'

如果 Invoke-Command 总是 挂起,请参考:

  1. 尝试对系统执行一个简单的命令: Invoke-Command -ComputerName XXXXX -ScriptBlock { Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion }

  2. 启动 Windows 远程管理服务(在该系统上)

  3. 检查监听端口:

     netstat -aon | findstr "5985"
          TCP    0.0.0.0:5985           0.0.0.0:0              LISTENING       4
          TCP    [::]:5985              [::]:0                 LISTENING       4