优化PowerShell的性能和内存消耗 4


PowerShell性能优化系列文章

  1. PowerShell优化和性能测试
  2. 让你的PowerShell For循环提速四倍
  3. 优化PowerShell的性能和内存消耗
  4. PowerShell提速和多线程
  5. 优化PowerShell脚本的几个小技巧
  6. 轻量级的PowerShell性能测试

PowerShell可能是非常属于资源密集型,尤其在你如果用它从活动目录中来检索数据时。我觉的吧,把最近在PowerShell新闻组中讨论过的这个问题分享出来,并变通的解决它非常实用。

症结

当你尝试使用下面的代码后续处理检索到的所有用户数据时:

$users = Get-QADUser -IncludeAllProperties -SizeLimit 0

计算机会抛出下面的异常:

Get-QADUser : Exception retrieving members: “Exception of type
‘System.OutOfMemoryException’ was thrown.”

(貌似方向正确,对吧?SizeLimit设置成0让PowerShell检索所有的用户对象,IncludeAllProperties 让它检索整个用户对象属性(可不仅仅是默认的属性集),然后集合被分配给一个变量作为后续使用,这也就是为什么有这个异常?请继续阅读!)

原因

实际上在一个相当大的域环境中,上面引用的一行代码,通过这种简单的检索整个AD数据库,并把它封装成Powershell对象,几乎消耗了机器所有的内存。

你应当避免检索和把你的脚本中没有使用到的数据保存到内存中。下面看怎么做到它。

解决方法

在使用活动目录时,这里有一些小技巧需要大家记住,去优化你的PowerShell代码:

使用管道

不要把整个集合保存到一个变量中。这会让PowerShell去检索所有的对象并且把它们保持在当前整个会话中。相反的,使用管道吧,这会让PowerShell把对象一个一个传递给各个命令。

看这个,把它:

users = Get-QADUser
ForEach ($user in $users) { here goes the code }

替换成:

Get-QADUser | ForEach { here goes the code }

按需所取

-IncludeAllAttributes是一个危险的参数,因为它保持了所有的属性。甚至一些你都压根就不知道怎么使用的二进制的块文件。如果cmdlets默认检索出的属性就能满足你(获取属性列表,只须运行:Get-QADUser | Get-Member),那就这样简单使用:

Get-QADUser -SizeLimit 0

如果你真的还需要几个额外的参数,使用-IncludedProperties ,添加你只需要的(而不是全部属性)。

Get-QADUser -SizeLimit 0 -IncludedProperties proxyAddresses

如果你还想更进一步的优化,还可以使用DontUseDefaultIncludedProperties参数,排除一些默认会被检索到的属性。

Get-QADUser -DontUseDefaultIncludedProperties -IncludedProperties SamAccountName,proxyAddresses

使用Parameters的参数过滤

最后,如果你需要的这是对象的一个子集,可以使用cmdlet的参数过滤,而不是where语句。

所以要把:

Get-QADUser | where { $_.City -eq Amsterdam} | { here goes the code }

替换成:

Get-QADUser -City Amsterdam | { here goes the code }

这可是云泥之别啊。前者PowerShell检索了所有的用户数据,然后在客户端做过滤。但是后者,过滤条件会作为 LDAP查询的一部分,自动在域控制服务器端完成数据检索。

总结

理想的PowerShell脚本:

  1. 不要把整个对象集合保存起来,而是一边检索一边逐个处理它们(流模式)。
  2. 只检索你需要的属性。
  3. 在检索的过程中过滤对象。
Get-QADUser -City Amsterdam -DontUseDefaultIncludedProperties -IncludedProperties
SamAccountName,proxyAddresses | ForEach { here goes the code }

荔非苔注:不要纠结这些AD命令,我没测试过,因为本文是7年前的文章了,可能命令早已过时。但是文章的思想仍旧适用于现在,甚至其它领域,比如“SQL Server”。

原文作者:Dmitry Sotnikov
原文链接Optimize PowerShell Performance and Memory Consumption 

本文链接: https://www.pstips.net/optimize-powershell-performance-and-memory-consumption.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

回复 YanFeng Xie 取消回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

4 条评论 “优化PowerShell的性能和内存消耗