【问题标题】:high memory consumption in powershell foreach looppowershell foreach循环中的高内存消耗
【发布时间】:2015-01-16 00:14:44
【问题描述】:

我正在尝试编写一个 powershell 脚本,该脚本将从我们的 oracle DB 导出 (CSV) 中获取用户,并使用它来更新 Active Directory 中的信息或创建新帐户(使用 Quest AD cmdlet、set-qaduser)。我的脚本正在运行,但是它不会完成 foreach 循环,因为它内存不足。 CSV 有大约 1,300 行要循环,盒子有 12GB 的内存。

我认为我的 foreach 循环存在问题,只是以最有效的方式处理它,所以这就是我寻求帮助的地方。脚本如下:

Add-PSSnapin Quest.Activeroles.ADManagement

Import-Csv \\pathtocsv\importusers.csv | foreach {

[string]$upn=$_.FIRST_NAME[0]+$_.LAST_NAME+"."+$_.ASSOC+"@innout.corp"

#check to see if the AD account already exists, if not, create it
if (!(get-qaduser $upn))
{

#because there are some blank/null values for phone numbers we need to only put in the variable values that have data, otherwise the script will bomb out
if($_.HOME){
$homephone=$_.home}
else{
$homephone=" "}

if($_.CELL){
$cellphone=$_.cell}
else{
$cellphone=" "}

$mgr=Get-QADUser -IncludedProperties employeeid -oa @{employeeid=$_.mgr}

#Object attribute hashtable, ADattribute and the value you want to put.

$oa=@{
Department=$_.ctr_name;
division=$_.division;
employeeid=$_.assoc;
ExtensionAttribute10=$_.mgr;
ExtensionAttribute11=$_.region_name;
ExtensionAttribute12=$_.hire_date;
ExtensionAttribute13=$_.dob;
ExtensionAttribute14=$_.region;
ExtensionAttribute15=$_.mgr_name;
DepartmentNumber=$_.ctr
}

New-QADUser -ParentContainer "OU=StoreManagers,OU=Stores,DC=contoso,DC=com" -Name $_.full_name -title $_.title -DisplayName $_.full_name -firstname $_.first_name -lastname $_.last_name -upn $upn -homephone $homephone -mobilephone $cellphone -manager $mgr -telephonenumber $_.work -ObjectAttributes $oa

}

#this else statement is if the AD account already exists, then just come here and update the account.
else

{

if($_.HOME){
$homephone=$_.home}
else{
$homephone=" "}

if($_.CELL){
$cellphone=$_.cell}
else{
$cellphone=" "}

$mgr=Get-QADUser -IncludedProperties employeeid -oa @{employeeid=$_.mgr}

$oa=@{
Department=$_.ctr_name;
division=$_.division;
employeeid=$_.assoc;
ExtensionAttribute10=$_.mgr;
ExtensionAttribute11=$_.region_name;
ExtensionAttribute12=$_.hire_date;
ExtensionAttribute13=$_.dob;
ExtensionAttribute14=$_.region;
ExtensionAttribute15=$_.mgr_name;
DepartmentNumber=$_.ctr
}

set-qaduser -identity $upn -DisplayName $_.full_name -firstname $_.first_name -lastname $_.last_name -title $_.title -homephone $homephone -mobilephone $cellphone -manager $mgr -telephonenumber $_.work -ObjectAttributes $oa 

}
}

#This section will disable/move/delete managers that have left the company or stepped down to a non-managment role. 

$deletedusers=Import-Csv \\pathtocsv\importusers.csv
foreach ($deleteduser in $deletedusers) {
[string]$samdelete=$deleteduser.FIRST_NAME[0]+$deleteduser.LAST_NAME+"."+$deleteduser.ASSOC
Disable-QADUser $samdelete
Move-QADObject $samdelete -NewParentContainer "OU=ToBeDeleted,OU=StoreManagers,OU=Stores,DC=contoso,DC=com"
set-qaduser $samdelete 
}

#This section sets all the DM Division numbers

$dmusers=Import-Csv \\pathtocsv\importusers.csv

foreach ($dmuser in $dmusers) {
$oa=@{
division=$dmuser.division
}
Get-QADUser -oa @{employeeid=$dmuser.assoc} | set-qaduser -oa $oa
}

【问题讨论】:

  • 您是否尝试将 -DontUseDefaultIncludedProperties 添加到 Get-QADUser 调用中?
  • 谢谢米奇。我确实尝试使用 -DontUseDefaultIncludedProperties,然后只包含了我需要设置的所有属性,但它仍在增长。我认为 Quest cmdlet 中可能存在内存泄漏。请参阅下面的评论。

标签: powershell memory-management foreach out-of-memory cmdlets


【解决方案1】:

这听起来像是内存泄漏。关于 XML 操作的 another a question 显示了类似的情况。解决方案是升级到 Powershell 3+。将remove-variable[GC]::Collect() 语句添加到循环中以释放资源可能会解决一些问题。

此外,a blog article 描述了 Quest AD cmdlet 资源的使用并提供了一些提示。主要的警告是 Quest cmdlet 可以轻松检索所有 AD 用户,将数据包装为 Powershell 对象 - 这会消耗大量内存。

【讨论】:

  • 感谢 vonPryz。我尝试启用垃圾收集器并删除变量,但它仍在增长(每个 get-qaduser 查找大约 3MB)。如果我只是从 powershell(在脚本之外)运行 get-qaduser,powershell.exe 的内存会增加 3MB 并且不会释放。 Quest cmdlet 中的内存泄漏?
  • 哦,我刚刚更新到 Powershell 4 以确保我运行的是最新的 shell,以防万一他们修复了一些内存泄漏。
【解决方案2】:

事实证明存在内存泄漏(至少在我运行的 Quest cmdlet 版本中)。我在我的用户帐户上只运行了一个 get-qaduser(在脚本之外),我看到 powershell.exe 进程增长了 6MB。然后我一次又一次地运行它,它每次都会增长6MB,并且永远不会释放内存。我最终将上面的脚本转换为使用内置的 set-aduser 并且它在整个脚本持续时间内总共只使用了 50MB。

顺便说一句,我确实尝试过寻找任务 cmdlet 的更新版本,但它们现在消失了吗?我知道戴尔买了它们,但你只能从戴尔购买 Active Roles Server,没有免费的 quest.activeroles.admanagement?如果有人知道在哪里可以获取更新的 Quest for Active Directory cmdlet,请告诉我。

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 2011-12-15
    • 2019-10-10
    • 2012-05-18
    • 2016-09-17
    • 2016-07-11
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多