Оптимизация производительности и потребления памяти PowerShell

#powershell #csv #out-of-memory #audit

#powershell #csv #нехватка памяти #аудит

Вопрос:

Приведенный ниже сценарий PowerShell запрашивает журнал событий безопасности на одном или нескольких серверах для событий с идентификатором 4663. При попытке получить все события аудита для события с идентификатором 4663 с помощью следующего кода компьютер выдает следующее исключение: как мы можем оптимизировать этот PowerShell? Поэтому я просто хочу получать журнал событий безопасности на основе конкретных пользователей AD, а не всех пользователей. В противном случае я хочу получить то, что мне нужно.

введите описание изображения здесь
введите описание изображения здесь

 $server = "HOSTNAME"
$out = New-Object System.Text.StringBuilder
$out.AppendLine("ServerName,EventID,TimeCreated,UserName,File_or_Folder,AccessMask")
$ns = @{e = "http://schemas.microsoft.com/win/2004/08/events/event"}
foreach ($svr in $server)
    {    $evts = Get-WinEvent -computer $svr -FilterHashtable @{logname="security";id="4663"} -oldest

    foreach($evt in $evts)
        {
        $xml = [xml]$evt.ToXml()

        $SubjectUserName = Select-Xml -Xml $xml -Namespace $ns -XPath "//e:Data[@Name='SubjectUserName']/text()" | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value

        $ObjectName = Select-Xml -Xml $xml -Namespace $ns -XPath "//e:Data[@Name='ObjectName']/text()" | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value

        $AccessMask = Select-Xml -Xml $xml -Namespace $ns -XPath "//e:Data[@Name='AccessMask']/text()" | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty Value

        $out.AppendLine("$($svr),$($evt.id),$($evt.TimeCreated),$SubjectUserName,$ObjectName,$AccessMask")

        Write-Host $svr
        Write-Host $evt.id,$evt.TimeCreated,$SubjectUserName,$ObjectName,$AccessMask

        }
    }
$out.ToString() | out-file -filepath C:TEMP4663Events.csv
  

Комментарии:

1. Чтобы оптимизировать производительность, сначала измерьте ее: самая медленная часть на сегодняшний Get-WinEvent день. Теперь вы можете начать искать ответы, как ускорить это. Я знаю, что на локальном компьютере Get-EventLog Security -InstanceId 4663 это в 100 или 1000 раз быстрее. Попробуйте протестировать его в своей среде. Если это также медленно, рассмотрите возможность удаленного выполнения задания PS, чтобы оно Get-EventLog выполнялось локально на удаленных компьютерах, а результаты отправлялись обратно на ваш.

Ответ №1:

Реорганизуйте код так, чтобы содержимое stringbuilder время от времени сбрасывалось. Это позволяет управлять его размером. Вот так,

 $out = New-Object System.Text.StringBuilder
$out.AppendLine("ServerName,EventID,TimeCreated,UserName,File_or_Folder,AccessMask")
foreach($evt in $evts) {
    $xml = [xml]$evt.ToXml()
    ...
    $out.AppendLine("$($svr),$($evt.id),$($evt.TimeCreated),$SubjectUserName,$ObjectName,$AccessMask")
    # If the stringbuffer is large enough, flush its contents to disk
    # and start filling empty buffer again
    if($out.length -ge 100MB) {
        $out.ToString() | out-file -filepath C:TEMP4663Events.csv -append
        $out.Clear()
    }
}
# Remember to flush the buffer so that stuff that wasn't flushed in the
# foreach loop is saved as well
$out.ToString() | out-file -filepath C:TEMP4663Events.csv -append
  

Редактировать:

Поскольку ошибка исходит от Out-LineOutput внутреннего командлета, это может быть связано с настройками памяти оболочки. Вы можете попробовать увеличить максимальную память на оболочку, скажем, до 2 ГБ. Вот так,

 Set-Item .MaxMemoryPerShellMB 2048
  

В блоге MS Scripting Guys есть подробная статья о настройке ограничений

Комментарии:

1. спасибо, к сожалению, я все еще сталкиваюсь с той же проблемой, поэтому при запуске кода powershell использование памяти растет, а затем я получаю «из памяти»

2. еще раз спасибо, наконец, как мы можем получать журнал событий безопасности на основе конкретных пользователей AD, а не всех пользователей?

3. Это был бы еще один вопрос, достойный отдельного рассмотрения. Если проблема с памятью решена, пожалуйста, проверьте это как ответ и откройте другое для фильтрации журнала пользователем.