【问题标题】:Task Scheduler can't kill a process properly using PowerShell script任务计划程序无法使用 PowerShell 脚本正确终止进程
【发布时间】:2020-11-13 00:48:16
【问题描述】:

我想使用任务计划程序和 PowerShell 脚本终止一个进程。 当特定进程启动时,任务调度程序会触发 PS 脚本。该脚本获取进程 ID 并尝试停止它。 我的问题是,在进程完成其工作之前,脚本无法终止进程。但是,我想在脚本触发后立即终止该进程,而无需等待任何内容。请注意,我要杀死的进程也以管理员权限运行,并在窗口模式下运行(而不是在后台)

计划任务设置:以具有最高权限的 SYSTEM 运行。我还使用了 executionPloicyBypass 参数,如下所示: powershell -ExecutionPolicy Bypass -File C:\Scripts\KillProcess.ps1.

在脚本中,我基本上有以下代码

$process = Get-Process -Id $pid
$process.PriorityClass = 'High'
$events=Get-WinEvent -FilterHashtable @{LogName="Security"; Id = <eventId>; StartTime = [datetime]::Now.AddMinutes(-5)} |Where-Object -Property Message -Match '<string to search for>' | Where-Object -Property Message -Match ('<string to search for>') -ErrorAction Stop 

if (!$events[0].message) {  

    Exit
   
}

else {
    
    $processes = @()

    #for each event, get process Id and kill it. 
    #this is because the process can spawn multiple process.

    foreach ($event in $events) {

    #parse the process Id.-*
    $processId=[int][regex]::Match($event.message,'Process\sID\:\s+(0x.+)\s').captures.groups[1].Value
        
    $processes += $processId
    }
    
    $processes = $processes | Select -Unique
    
    foreach ($proc in $processes) {
    Stop-Process -Id $proc -Force -ErrorAction SilentlyContinue
}
}

当我以管理员身份运行 PowerShell ISE 并在那里手动运行脚本时,它会立即终止该进程。但是,当任务调度程序触发脚本时,它会等待进程完成其工作。我的任务调度程序有什么问题吗?

【问题讨论】:

  • 任务是如何被触发的?
  • 在具有特定 EventID 的事件上。然后脚本读取相同的事件并获取进程 ID 并尝试终止它。
  • 所以上面的“snipped code”部分有一些代码可以提取进程ID。似乎是一个时间问题,你确定事件是在你试图杀死的进程开始时记录的吗?如果没有额外的代码,我也担心隔离正确的事件等......这里有很多复杂的空间,有什么办法可以发布 sn-p 吗?净化版?
  • 我编辑了原始消息并放置了经过清理的代码。在任务历史记录中,我看到进程开始运行。任务触发器的 EventID 相同。所以我确信脚本会找到正确的事件并获取进程 ID。无论如何,它无法杀死他们。要被杀死的进程运行大约 60 秒或更长时间。脚本有足够的时间来杀死它。我还尝试运行任务的并行实例,因为它为同一进程多次触发。它也没有工作。
  • 从事件的属性集合中提取进程 ID 会容易得多。只需确定它所在的索引。您可以看到 here 的示例。至于延迟进程终止,我不确定。但是,如果我要对此进行故障排除,我要么开始记录,要么只是将一堆调试文本(包括时间戳)写入文件。至少可以告诉您延迟发生的位置,然后从那里获取...

标签: powershell scheduled-tasks taskscheduler


【解决方案1】:

我不知道Stop-Process 有什么问题,但我通过首先使用Get-Process -Id $proc 获取进程对象将其更改为process.Kill() 方法。现在它可以正常工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 2019-05-08
    • 2022-01-16
    • 2020-08-07
    • 2022-12-01
    • 2014-01-27
    • 2018-12-02
    相关资源
    最近更新 更多