PowerShell 作业节流阻塞服务器

PowerShell Job throttle blocking the server

我遇到了一个奇怪的问题,我们的脚本服务器超载并且 运行 资源不足。我们有一个将数据从一个位置复制到另一个位置的脚本,这是在一个包含 200 多行文本的大型输入文件中定义的,格式为 'Source path, Destination path'.

我们现在正在尝试限制我们同时启动的最大作业数,我认为它运行良好。但是由于某种原因,当输入文件包含超过 94 行时,我们仍然 运行 耗尽服务器上的资源。经过一些测试后,这一点变得很明显。

我们尝试将带有 PowerShell 4.0 的 Windows 2008 R2 服务器升级到 4 个处理器和 8 GB RAM,但没有成功。所以我假设我的节流没有按设计工作。

错误代码:

Insufficient system resources exist to complete the requested service. 

代码:

$MaxThreads = 4
$FunctionFeed = Import-Csv -Path $File -Delimiter ',' -Header 'Source', 'Destination'
$Jobs=@()

Function Wait-MaxRunningJobs {
    Param (
        $Name,
        [Int]$MaxThreads
    )
    Process {
        $Running = @($Name | where State -eq Running)
        while ($Running.Count -ge $MaxThreads) {
            $Finished = Wait-Job -Job $Name -Any
            $Running = @($Name | where State -eq Running)
        }
    }
}

$ScriptBlock = {
    Try {
        Robocopy.exe $Using:Line.Source $Using:Line.Destination $Using:Line.File /MIR /Z /R:3 /W:15 /NP /MT:8 | Out-File $Using:LogFile

        [PSCustomObject]@{
            Source = if ($Using:Line.Source) {$Using:Line.Source} else {'NA'}
            Target = if ($Using:Line.Destination) {$Using:Line.Destination} else {'NA'}
        }
    }
    Catch {
        "Robocopy | ERROR: $($Error[0].Exception.Message)" | 
            Out-File -LiteralPath $Using:LogFile
        throw $($Error[0].Exception.Message)
    }
}

ForEach ($Line in $FunctionFeed) {
    $LogParams = @{
        LogFolder  = $LogFolder
        Name       = $Line.Destination + '.log'
        Date       = 'ScriptStartTime'
        Unique     = $True
    }
    $LogFile = New-LogFileNameHC @LogParams
    ' ' >> $LogFile # Avoid not being able to write to log

    $Jobs += Start-Job -Name RoboCopy -ScriptBlock $ScriptBlock
    Wait-MaxRunningJobs -Name $Jobs -MaxThreads $MaxThreads
}

if ($Jobs) {
    Wait-Job -Job $Jobs
    $JobResults = $Jobs | Receive-Job
}

我是不是漏掉了什么?感谢您的帮助。

您正在使用后台作业,实际上 运行 在本地计算机的远程会话中。根据会话配置中的设置,远程会话有意限制资源。您可以使用

检查当前设置
Get-PSSessionConfiguration

并调整设置以增加会话可用的资源

Set-PSSessionConfiguration

您可能需要进行一些测试,以确定您正在达到的资源限制,以及需要进行哪些调整才能使该特定应用程序正常工作。

通过将远程会话的 MaxMemoryPerShellMB 从 1GB 扩大到 2GB 解决了问题 here。请记住,正如 mjolinor 已经指出的那样,Start-Job 正在使用远程 PowerShell 会话,因此该变量适用于 PowerShell 作业。

解法:

# 'System.OutOfMemoryException error message' when running Robocopy and over 94 PowerShell-Jobs:

Get-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB # Default 1024
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048

# Set PowerShell plugins memory from 1 GB to 2 GB
Get-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB # Default 1024
Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048

Restart-Service winrm