PowerShell foreach循环中的高内存消耗

时间:2014-11-18 17:41:54

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

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

我认为我的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
}

2 个答案:

答案 0 :(得分:0)

这听起来像是内存泄漏。关于XML操作的another a question表明了类似的情况。解决方案是升级到Powershell 3+。通过向循环添加remove-variable[GC]::Collect()语句以释放资源,可以进行一些解决方法。

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

答案 1 :(得分:0)

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

另一方面,我确实试图寻找任务cmdlet的更新版本,但现在它们已经消失了吗?我知道戴尔买了它们,但你只能从戴尔购买Active Roles服务器,不再需要免费的quest.activeroles.admanagement?如果有人知道在哪里更新Quest for Active Directory cmdlet,请告诉我。