【问题标题】:How can I effectively conserve resources using the PowerShell pipeline?如何使用 PowerShell 管道有效地节省资源?
【发布时间】:2015-04-25 09:04:30
【问题描述】:

我有几个 PowerShell 脚本用于管理中型 Microsoft Exchange 组织(约 10,000 个邮箱)。一些脚本以某种方式处理组织的所有邮箱。我在运行这些脚本时遇到的一个常见问题是资源耗尽。这些脚本最终会使用千兆字节的 RAM。

我的研究表明,使用管道可以避免内存消耗,因为在处理之前不会将结果加载到数组中。但是,在某些情况下,Get-Mailbox 似乎仍会将整个结果列表加载到内存中,然后再尝试将这些结果传递给管道中的下一个命令。

例如,我假设以下示例代码将在命令执行后立即开始列出与每个邮箱关联的移动设备:

示例 1

function GetMailboxDevices
{
    process
    {
        Write-Host $_.Alias -ForegroundColor Green
        Get-MobileDevice -Mailbox $_
    }
}

Get-Mailbox -ResultSize Unlimited | GetMailboxDevices

但是,当 Get-Mailbox cmdlet 运行时,此代码似乎不会实时处理结果。相反,Get-Mailbox 似乎需要几分钟才能运行,然后立即将所有结果传递给管道中的第二个命令。在此过程中,PowerShell 会话的 RAM 使用率攀升至 1.5 GB 或更高。

不过,我可以使用类似于以下的代码来解决此问题:

示例 2

function GetMailboxAliases
{ 
    process 
    {
        Write-Host $_.Alias -ForegroundColor Green
        $_.Alias
    } 
}

$aliases = Get-Mailbox -ResultSize Unlimited | GetMailboxAliases

foreach ($alias in $aliases)
{
    Get-MobileDevice -Mailbox $alias
}

在第二个示例中,Get-Mailbox 确实将每个结果实时传递到管道中,而不是一次全部传递(Write-Host 证实了这一点),并且 RAM 使用量没有显着增加。当然,这段代码并不像我必须将别名收集到一个数组中那样优雅,然后使用 foreach 语句处理该数组。

如果我在函数中做一些简单的事情(例如简单地返回每个邮箱的别名),管道似乎很有效,但是一旦我将另一个 Exchange cmdlet 引入函数(例如 Get-MobileDevices )。

我的问题是:为什么示例 1 中的代码不能有效地利用管道,而示例 2 可以?可以采取哪些步骤来确保有效利用管道?

【问题讨论】:

    标签: powershell exchange-server pipeline


    【解决方案1】:

    当您运行返回大量对象的脚本时,将它们加载到变量中是帮助内存使用的好方法。这就是版本 2 性能更好的原因。

    此外,从另一台服务器或工作站远程运行此脚本还可以使代码执行更容易,并使资源使用更容易排除故障。

    你可以试试这个来检查你的印象:

    Measure-Command { script1.ps1 }
    
    Measure-command { script2.ps1 }
    

    【讨论】:

      【解决方案2】:

      我并没有如此频繁地使用 Exchange,但在我的脚本中我会这样做:

      function GetMailboxDevices ($mb)
      {
          process
          {
              Write-Host $_.Alias -ForegroundColor Green
              Get-MobileDevice -Mailbox $mb
          }
      }
      
      
      Get-Mailbox -ResultSize Unlimited | Foreach-object { GetMailboxDevices $_}
      

      Get-Mailbox -ResultSize Unlimited | % { GetMailboxDevices $_}
      

      【讨论】:

        猜你喜欢
        • 2022-10-17
        • 2013-01-13
        • 2017-07-24
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多