PowerShell性能优化系列文章
- PowerShell优化和性能测试
- 让你的PowerShell For循环提速四倍
- 优化PowerShell的性能和内存消耗
- PowerShell提速和多线程
- 优化PowerShell脚本的几个小技巧
- 轻量级的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脚本:
- 不要把整个对象集合保存起来,而是一边检索一边逐个处理它们(流模式)。
- 只检索你需要的属性。
- 在检索的过程中过滤对象。
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
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
广播: PowerShell优化和性能测试 | PowerShell 中文博客
广播: 让你的PowerShell For循环提速四倍 | PowerShell 中文博客
请问 Get-QADUser 这个命令那来的?
这个应当是活动目录AD对应的PowerShell命令。不是PowerShell默认的。