Сбой сценария PowerShell для настройки производительности с System.outOfMemoryException

У меня есть следующий сценарий PowerShell, который завершается с ошибкой после 30 минут выполнения с System.outOfMemoryException

$csv = get-content "C:\test\groups.txt" 
$result = $csv | foreach-object { 
$group=$_ 
get-QADGroupMember "$_" -PageSize 500 -sizelimit 0 | 
select-object    sAMAccountName,@{n="GroupName";e={$group}},type
} 
$result | export-csv C:\test\groupMembers.csv -Delimiter "|" -notypeinformation

Сценарий получает содержимое из текстового файла. groups.txt это список всех групп, найденных в Active Directory, затем для каждой группы он извлекает в csv имя группы, имя члена и тип члена.

Если я не ошибаюсь, сценарий обрабатывает слишком много данных в памяти и дает сбой при достижении предела. Есть ли способ настроить сценарий, например, для освобождения памяти при каждой обработке группы или что-то еще?

2 ответа

Вы также можете попробовать прочитать этот файл, используя поток вместо get-content, чтобы свести к минимуму использование памяти.

Что-то вроде этого:

$file = New-Object System.IO.StreamReader -Arg "c:\test\groups.txt"
$outstream = [System.IO.StreamWriter] "c:\test\groupMembers.csv"
while ($line = $file.ReadLine()) {
  # $line has your line, parse to get each piece of csv

  #create a csv string and stream it to the output file
  $s = "`"{0}`",`"{1}`",`"{2}`",`"{3}`"" -f ($each,$piece,$of,$csv)
  $outstream.WriteLine($s)
}
$file.close()
$outstream.close()

Моя организация недостаточно велика, чтобы я мог столкнуться с подобными проблемами, но некоторые первоначальные предложения, которые вы должны рассмотреть, - это удалить $result переменная, поскольку это сохранит весь прогресс в памяти перед записью в файл.

$csv = get-content "C:\test\groups.txt" 

$csv | foreach-object { 
    $group=$_ 
    get-QADGroupMember "$_" -PageSize 500 -sizelimit 0 | 
    select-object    sAMAccountName,@{n="GroupName";e={$group}},type
} | export-csv C:\test\groupMembers.csv -Delimiter "|" -notypeinformation

Чтобы продолжить, если у вас есть хотя бы PowerShell 3.0, вы можете использовать -ReadCount который будет тянуть несколько строк одновременно вместо одной строки за раз. Не уверен на 100%, поможет ли это вашей ситуации, хотя

get-content "C:\test\groups.txt" -ReadCount 500 | foreach-object { 
    $group=$_ 
    get-QADGroupMember "$_" -PageSize 500 -sizelimit 0 | 
    select-object    sAMAccountName,@{n="GroupName";e={$group}},type
} | export-csv C:\test\groupMembers.csv -Delimiter "|" -notypeinformation
Другие вопросы по тегам