Windows WMI命令行模板变量关闭

Windows WMI命令行模板变量关闭,windows,powershell,events,wmi,Windows,Powershell,Events,Wmi,我一直在研究一种解决方案来监视和响应某些windows服务的停止,我真的可以在这方面多用几百双眼睛。我正在Powershell中设置WMI订阅,该订阅似乎完成了它的工作,但我没有使用CommandLineTemplate获得预期的输出。我试图将服务名称、当前状态和以前的状态推送到powershell脚本或可执行文件(与PS脚本相同,但已编译),但在第一个变量被切断之前,我只得到了它的一部分。我尝试了多种不同的方式格式化commandlinetemplate,用单引号/双引号/转义引号转义变量,并

我一直在研究一种解决方案来监视和响应某些windows服务的停止,我真的可以在这方面多用几百双眼睛。我正在Powershell中设置WMI订阅,该订阅似乎完成了它的工作,但我没有使用CommandLineTemplate获得预期的输出。我试图将服务名称、当前状态和以前的状态推送到powershell脚本或可执行文件(与PS脚本相同,但已编译),但在第一个变量被切断之前,我只得到了它的一部分。我尝试了多种不同的方式格式化commandlinetemplate,用单引号/双引号/转义引号转义变量,并尝试对变量重新排序,但它似乎总是第一种方式的一部分,没有传递任何其他方式。为了进行测试,我只是尝试获取变量并将它们写入日志,然后再继续进行更有趣的事情

订阅代码:

$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):

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.

克里斯,问题似乎在于你从第一个脚本中得到的变量。我不确定这些变量是从哪里来的。ServiceMonitor.exe应用程序不是PS脚本,我看不到订阅在哪里调用ServiceMonitor.ps1

只需将PS行复制到ServiceMonitor.ps1文件中,我就能够运行以下命令并获取后续日志信息

.\ServiceMonitor.ps1 TestService Running Stopped
2019年11月1日11:01:24-7D25PX1上的TestService状态已从停止更改为运行。 2019年11月1日11:13:11-7D25PX1上的TestService状态已从停止更改为运行。 2019年11月1日11:13:44-7D25PX1上的TestService状态已从停止更改为运行


希望这至少能帮你指明正确的方向。请随时回复更多信息,我很乐意更新帖子。

如何调用PowerShell脚本?@HAL9256在上面的示例中,我使用的是使用“ServiceMonitor.exe”的编译版本,但我也尝试使用以下命令(以及五十种转义)将其称为PS1脚本$instanceConsumer.CommandLineTemplate=“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe-ExecutionPolicy Bypass-文件C:\Tools\ServiceMonitor.ps1
%TargetInstance.DisplayName%
%TargetInstance.State%
%PreviousInstance.State%
”@TheldesOfMark感谢您的关注,您是对的,在第一个脚本中,我调用ServiceMonitor.exe,但这只是ServiceMonitor.ps1的编译版本,我这样做是为了尝试排除调用完整powershell.exe路径调用ps1脚本时出现的问题。无论我使用的是.ps1还是.exe版本,当我使用硬值从powershell运行它时,我都会得到正确的输出,如您的示例中所示。只有当我启用WMI订阅(第一个代码块)并且WMI调用脚本或exe时,才会出现此问题。WMI的输出似乎被切断。字符限制。。。。因此,在我的示例中,如果服务名为'ServiceNamex.Funct.QA.12',并且它从开始到停止,我将只得到'ServiceNamex.Funct.QA'作为服务名称,而没有得到其他两个变量(当前和以前的状态)。如果我切换两个脚本上的变量以将服务名称放在最后,则第一个状态将被截断为类似“stop”的内容,而其他两个状态则不会截断。您是否使用ServoceMonitor.ps1-args
%arg1%
”等进行过尝试?我不能在这里做太多测试,我的管理员权限还没有通过,所以我的PS模块非常有限,并且我没有访问WMI模块的权限。感谢您尝试以任何方式提供帮助!我只是尝试一下,将ps1简化为基于args 1、2和3设置变量,得到了相同的结果。服务名称的最后两位数字被截断,状态值为空。我真的希望现在有人会插话。如果您仍在处理此问题,我建议您尝试在每个操作之前捕获$instanceConsumer.CommandLineTemplate的输出,以查看输出何时被过滤或获取错误的值。我也不确定其中有多少是作为批处理运行的,有多少是作为pwsh运行的,所以您可能会以不同的方式来看待转义字符串。对于批处理脚本,“/”是标准转义字符。
.\ServiceMonitor.ps1 TestService Running Stopped