Скрипт PowerShell с Procdump

Вопрос или проблема

Итак, у меня есть система, которая работает довольно медленно ночью при запуске отчета. Я настроил Монитор производительности для мониторинга системы. Что я выяснил, так это то, что есть процесс, который использует все ЦП. Я хочу написать скрипт на Powershell, который создает дамп памяти по идентификатору процесса, когда достигается счетчик производительности. Вот что у меня есть на данный момент:

$programid = (Get-Process | Sort-Object CPU -desc | Select-Object -index 1 | Format-Table Id -Autosize -hidetableheader)
$app = "C:\procdump\procdump.exe"
$argument1 = '-ma'
$argument2 = 'c:\appdumps\ -accepteula'
& $app $argument1 $programid $argument2

Когда я запускаю скрипт, я получаю следующий результат:

& $app $argument1 $programid $argument2

ProcDump v7.1 - Записывает файлы дампов процессов
Copyright (C) 2009-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
С участием Эндрю Ричардса

Мониторит процесс и записывает файл дампа, когда процесс превышает
указанные критерии или возникает исключение.

использование: procdump [-a] [[-c|-cl использование CPU] [-u] [-s секунд]] [-n превышает] [-e [1] [-b]] [-f <фильтр,...>] [-g] [-h] [
-l] [-m|-ml использование памяти] [-ma | -mp] [-o] [-p|-pl порог счетчика] [-r [1..5]] [-t] [-d <callback DLL>] [-64] <[-
w] <имя процесса или имя службы или PID> [файл дампа] | -i [папка дампа] | -u | -x <файл дампа> <образец файла> [аргументы
s] >

   -a      Избежать отключения. Требует -r. Если триггер вызовет остановку
           цели на продолжительное время из-за превышенного
           лимита одновременных дампов, триггер будет пропущен.
   -b      Рассматривать точки останова отладки как исключения (в противном случае игнорировать их).
   -c      Порог ЦП, при превышении которого необходимо создать дамп процесса.
   -cl     Порог ЦП, при котором нужно создать дамп процесса.
   -d      Вызвать вызов обратного мини-дампа, названный MiniDumpCallbackRoutine
           указанного DLL.
   -e      Записать дамп, когда процесс сталкивается с необработанным исключением.
           Включите 1, чтобы создать дамп на исключениях первой возможности.
   -f      Фильтр по содержимому исключений и журналирования отладки.
           Поддерживаются подстановочные знаки (*).
   -g      Запускать в качестве нативного отладчика в управляемом процессе (без взаимодействия).
   -h      Записать дамп, если процесс имеет зависшее окно (не отвечает на
           сообщения окна как минимум 5 секунд).
   -i      Установить ProcDump в качестве отладчика посмертного анализа AeDebug.
           Поддерживаются только -ma, -mp, -d и -r как дополнительные параметры.
           Удаление (-u только) восстанавливает предыдущее состояние.
   -l      Отобразить журналирование отладки процесса.
   -m      Порог памяти в МБ, при котором необходимо создать дамп.
   -ml     Срабатывает, когда использование памяти падает ниже указанного значения в МБ.
   -ma     Записать файл дампа со всей памятью процесса. Формат файла дампа по умолчанию
           включает только информацию о потоках и дескрипторах.
   -mp     Записать файл дампа с информацией о потоках и дескрипторах, и всей
           читаемой/записываемой памяти процесса. Чтобы минимизировать размер дампа,
           области памяти больше 512 МБ ищутся, и если найдены, то
           самая большая область исключается. Область памяти — это коллекция
           областей выделения памяти одного размера. Исключение этой (кэшевой)
           памяти снижает дампы Exchange и SQL Server более чем на 90%.
   -n      Количество дампов, которые необходимо записать перед выходом.
   -o      Перезаписать существующий файл дампа.
   -p      Срабатывает на указанном счетчике производительности, когда порог
           превышен. Примечание: чтобы указать счетчик процесса, когда
           запущено несколько экземпляров процесса, используйте идентификатор процесса
           с использованием следующего синтаксиса: "\Process(<name>_<pid>)\counter"
   -pl     Срабатывает, когда счетчик производительности падает ниже указанного значения.
   -r      Создать дамп с использованием клона. Параллельный лимит является необязательным (по умолчанию 1, максимум 5).
           ОСТОРОЖНО: высокое значение параллелизма может повлиять на производительность системы.
           - Windows 7   : Использует Reflection. ОС не поддерживает -e.
           - Windows 8.0 : Использует Reflection. ОС не поддерживает -e.
           - Windows 8.1+: Использует PSS. Поддерживаются все типы триггеров.
   -s      Последовательные секунды, прежде чем дамп будет записан (по умолчанию 10).
   -t      Записать дамп, когда процесс завершится.
   -u      Рассматривать использование ЦП относительно одного ядра (используется с -c).
           Как единственный параметр, удаляет ProcDump в качестве отладчика посмертного анализа.
   -w      Ожидать запуска указанного процесса, если он не работает.
   -x      Запустить указанный образ с необязательными аргументами. 
           Если это приложение или пакет Store, ProcDump запустится
           при следующей активации (только).
   -64     По умолчанию ProcDump будет захватывать 32-битный дамп 32-битного процесса
           при запуске на 64-битной Windows. Этот параметр переопределяет создание
           64-битного дампа. Используйте только для отладки подсистемы WOW64.

Используйте параметр командной строки -accepteula, чтобы автоматически принять
лицензионное соглашение Sysinternals.

Используйте -? -e, чтобы увидеть примеры командных строк.

Если вы опустите имя файла дампа, оно по умолчанию будет равно <имя процесса>_<дата и время>.dmp.

Если я запущу эту команду вручную:

C:\procdump>procdump.exe -ma 5264 c:\appdumps\ -accepteula

Я получаю этот вывод:

ProcDump v7.1 - Записывает файлы дампов процессов
Copyright (C) 2009-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
С участием Эндрю Ричардса

[12:25:06] Дамп 1 инициирован: c:\appdumps\notepad.exe_151212_122506.dmp
[12:25:07] Дамп 1 записывается: предварительный размер файла дампа составляет 53 МБ.
[12:25:07] Дамп 1 завершен: 53 МБ записано за 1.0 секунды
[12:25:08] Достигнуто количество дампов.

Я знаю, что команда работает, просто интересно, что не передается правильно. Есть ли способ настроить журнал, чтобы определить, что именно передается в procdump, когда он запускается?

Вы объединяете здесь две вещи в один аргумент:

$argument2 = 'c:\appdumps\ -accepteula'

Powershell не разбивает это на два аргумента, и ProcessDump не понимает это как единый аргумент. Поэтому вам нужно разместить каждый аргумент в отдельных переменных.

Ответ или решение

Чтобы создать скрипт PowerShell, который делает дамп памяти процесса при достижении определенного порога производительности, вам нужно учесть несколько моментов, чтобы убедиться, что все параметры правильно передаются в программу ProcDump. Поскольку вы уже настроили мониторинг производительности на вашей системе и определили проблему с использованием процессора, мы сосредоточимся на написании корректного скрипта.

Как вы заметили, проблема заключается в том, что вы объединяете два аргумента в одну строку. Это приводит к тому, что PowerShell не разделяет их корректно. Вам нужно убедиться, что каждый аргумент передается отдельно. Вот исправленный вариант вашего скрипта:

# Получение ID процесса с максимальным использованием ЦП
$programid = (Get-Process | Sort-Object CPU -Descending | Select-Object -First 1).Id
$app = "C:\procdump\procdump.exe"
$argument1 = '-ma'
$outputDirectory = 'c:\appdumps\'
$argument3 = '-accepteula'

# Проверка наличия директории для дампов
if (-not (Test-Path -Path $outputDirectory)) {
    New-Item -ItemType Directory -Path $outputDirectory
}

# Запуск команды ProcDump с корректной передачей аргументов
& $app $argument1 $programid $outputDirectory $argument3

Объяснение изменений:

  1. Отдельная передача аргументов: Мы разделили -accepteula и путь к директории дампов на отдельные переменные, чтобы ProcDump не путал их.

  2. Создание директории для дампов: Добавлена проверка на существование директории для дампов. Если она не существует, создаётся новая.

  3. Получение процесс ID: Вместо использования Format-Table для получения ID процесса, используется прямое извлечение значения с помощью Select-Object -First 1. Это позволяет сразу получить только значение ID.

Логирование выполнения:

Для логирования того, какие команды передаются в ProcDump, вы можете добавить простую запись в файл:

# Логирование перед запуском
$logFile = "C:\appdumps\procdump_log.txt"
$commandLine = "$app $argument1 $programid $outputDirectory $argument3"
Add-Content -Path $logFile -Value $(Get-Date)":" $commandLine

# Запуск команды ProcDump
& $app $argument1 $programid $outputDirectory $argument3

Данный фрагмент кода создаст лог-файл в C:\appdumps\, в который будет записываться команда, передаваемая в ProcDump, вместе с временной меткой. Это поможет вам отслеживать, что именно выполняется в момент запуска.

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

Оцените материал
Добавить комментарий

Капча загружается...