Обрезание переменных WMI CommandLineTemplate - PullRequest
0 голосов
/ 31 октября 2019

Я работал над решением для мониторинга и реагирования на остановку определенных служб Windows, и я действительно мог бы использовать несколько сотен дополнительных взглядов на это. Я настраиваю подписку WMI в Powershell, и подписка, кажется, выполняет свою работу, но я не получаю ожидаемый результат с помощью CommandLineTemplate. Я пытаюсь переместить имя службы, текущее состояние и предыдущее состояние в сценарий powershell или исполняемый файл (тот же сценарий PS, но скомпилированный), но я получаю только часть первой переменной, прежде чем она отключается. Я попытался отформатировать командную строку в несколько разных способов, экранировать переменные в одинарных / двойных / экранированных кавычках и попытался переупорядочить переменные, но это всегда кажется частью первого, и больше ничего не пропускается. Для тестирования я просто пытаюсь получить переменные и записать их в журнал, прежде чем перейти к более интересным вещам.

Код подписки:

$instanceFilter = ([wmiclass]"\\.\root\subscription:__EventFilter").CreateInstance()
$instanceFilter.QueryLanguage = "WQL"
$instanceFilter.Query = "select * from __instanceModificationEvent within 5 where targetInstance isa 'win32_Service' AND targetInstance.Name LIKE 'ServiceNamex.%'"
$instanceFilter.Name = "ServiceFilter"
$instanceFilter.EventNamespace = 'root\cimv2'
$result = $instanceFilter.Put()
$newFilter = $result.Path

#Creating a new event consumer
$instanceConsumer = ([wmiclass]"\\.\root\subscription:CommandLineEventConsumer").CreateInstance()
$instanceConsumer.Name = 'ServiceConsumer'
$instanceConsumer.CommandLineTemplate = "C:\Tools\ServiceMonitor.exe `"%TargetInstance.Name%`" `"%TargetInstance.State%`" `"%PreviousInstance.State%`""
$instanceConsumer.ExecutablePath = "C:\Tools\ServiceMonitor.exe"
$result = $instanceConsumer.Put()
$newConsumer = $result.Path

#Bind filter and consumer
$instanceBinding = ([wmiclass]"\\.\root\subscription:__FilterToConsumerBinding").CreateInstance()
$instanceBinding.Filter = $newFilter
$instanceBinding.Consumer = $newConsumer
$result = $instanceBinding.Put()
$newBinding = $result.Path

Код цели (PS1 /EXE):

[CmdletBinding()]
param (
    [parameter(Position=0)][string]$serviceName = "Error",
    [parameter(Position=1)][string]$currentState = "Error",
    [parameter(Position=2)][string]$previousState = "Error"
)
Add-Content -path "C:\temp\service.log" -value "$(Get-Date) - The state of $serviceName on $env:Computername has changed from $previousState to $currentState."
If ($currentState -eq "Stopped")
    {
        Add-Content -path "C:\temp\service.log" -value "$(Get-Date) - Attempting to restart $serviceName."
        Start-Service -DisplayName $serviceName
    }

Пример вывода для остановки и запуска ServiceNamex.Funct.QA.12:

10/30/2019 03:52:11 - The state of ServiceNamex.Funct.QA. has changed to Error.
10/30/2019 03:52:16 - The state of ServiceNamex.Funct.QA. has changed to Error.

1 Ответ

0 голосов
/ 01 ноября 2019

Крис, похоже, проблема в переменных, которые вы получаете из первого скрипта. Я не уверен, откуда вы берете эти переменные. Приложение ServiceMonitor.exe не является сценарием PS, и я не вижу, откуда подписка вызывает ServiceMonitor.ps1

. Просто скопировав строки PS в файл ServiceMonitor.ps1, я смог запуститьследующую команду и получите следующую информацию журнала.

.\ServiceMonitor.ps1 TestService Running Stopped

11/01/2019 11:01:24 - Состояние TestService на 7D25PX1 изменилось с Остановлено на Выполняется. 01.11.2009 11:13:11 - Состояние TestService на 7D25PX1 изменилось с Остановлено на Запуск. 01.11.2009 11:13:44 - Состояние TestService на 7D25PX1 изменилось с Остановлено на Запуск.

Надеемся, что это поможет хотя бы направить вас в нужном направлении. Не стесняйтесь ответить с дополнительной информацией, и я буду рад обновить сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...