如何在没有管理员权限的情况下在PowerShell中等待应用程序启动?

edqdpe6u  于 2023-04-30  发布在  Shell
关注(0)|答案(1)|浏览(130)

这是我以前问过的一个问题:How do I wait for an executable to open before continuing the code in PowerShell?
我找到了一个可行的解决方案,但它需要管理权限。我想知道有没有办法在没有管理许可的情况下做到这一点。.
我试图完成的主要任务是替换Register-CimIndicationEvent,但不需要任何管理权限。
如果你有任何想法来做这件事,我将非常感谢!
我已经尝试使用Register-CimIndicationEvent -ClassName 'Win32_ProcessStartTrace' -SourceIdentifier "ProcessStarted",但它需要管理权限才能工作。
我也试过:

$Q = "Select * from win32_ProcessStartTrace where processname = 'Process.exe'"

Register-CimIndicationEvent -Query $q -SourceIdentifier Q -Action {Stop-Process $event.SourceEventArgs.newevent.processID}

上面的代码假定每次打开一个进程时都会关闭它,这是我的主要目标。如果您能帮助我在没有管理权限的情况下做这样的事情,我将不胜感激。

bpzcxfmw

bpzcxfmw1#

实际上,监视Win32_ProcessStartTrace CIM/WMI事件需要 elevation(以admin身份运行)-Register-CimIndicationEvent在尝试从非提升会话注册事件处理程序时报告Access denied错误。

  • This answer显示了Win32_ProcessStartTrace示例代码(因此需要提升)。

作为非提升 * 代码次优解决方案,您可以实现一个(无限)* 轮询循环 ,它根据进程的开始时间定期监视所有进程列表中的新添加*,但请注意以下几点:

  • 为了避免过多的CPU负载,您必须在轮询操作之间使用Start-Sleep进行休眠
  • 因此,您有可能会错过创建短命进程的机会,i。即那些在你睡觉的时候被创建和终止的。
  • 调整睡眠间隔,以在CPU负载和可能丢失的进程之间找到适当的平衡。
  • 请注意,如果您真的打算使用Stop-Process杀死新进程,那么您唯一被允许杀死的进程是您自己的、未提升的进程。
Write-Verbose -Verbose "Monitoring for new processes; press Ctrl-C to exit..."
$timestamp = [datetime]::Now
while ($true) {
  # Get all processes that were launched since the last (successful)
  # polling operation.
  $newPs = 
    [System.Diagnostics.Process]::GetProcesses().
    Where({ $_.StartTime -gt $timestamp })
  if ($newPS) { # At least 1 new process found.
    # Work with $newPS.Id here, for instance.
    # For demo purposes, the new processes are simply printed here.
    $newPs | Out-Host
    Write-Host '-----------'
    # Update the timestamp based on the most recently launched process.
    $timestamp = ($newPS | Measure-Object -Maximum -Property StartTime).Maximum
  }
  # Sleep a little, to avoid excessive CPU load.
  Start-Sleep -Milliseconds 50
}

或者使用__InstanceCreationEvent CIM/WMI类

  • 使用这个类并不需要提升,但它也使用了一种轮询机制,这可能会导致它错过短期进程的创建。
    • 最小 * 轮询间隔为 *1秒 *。
Write-Verbose -Verbose "Monitoring for new processes; press Ctrl-C to exit..."
try {

  $query = '
    SELECT TargetInstance FROM __InstanceCreationEvent 
    WITHIN 1 WHERE 
    TargetInstance ISA "Win32_Process"
  '

  Register-CimIndicationEvent -ErrorAction Stop -Query $query -SourceIdentifier ProcessStarted

  while ($true) {
    ($e = Wait-Event -SourceIdentifier ProcessStarted) | Remove-Event
    # Get the PID (process ID) from the event
    $procId = $e.SourceEventArgs.NewEvent.TargetInstance.Handle
    # Sample processing: print the properties of the process.
    Get-Process -Id $procId | Format-List
  }
}
finally {
  UnRegister-Event ProcessStarted
}

相关问题