Windows 任务计划程序“在系统启动时”运行任务与其他任务不同

发布于 2025-01-19 03:33:05 字数 1063 浏览 1 评论 0原文

我有一个需要 24 * 7 运行的 powershell 脚本。

为了确保它执行此操作,我创建了任务计划程序中列出的两个(几乎)相同的任务。一个任务每天午夜启动,另一个设置为使用“系统启动时”触发器运行。该脚本设置为在午夜前一分钟退出。

到目前为止一切都很好,一切都很好。我所有的基地都被覆盖了。计划任务在 99% 的时间内处理脚本,“启动时”任务涵盖了偶尔的电源故障。

但是,当我查看进程详细信息时,我注意到了细微的差异。

如果我打开一个 powershell 会话并使用此命令检查午夜启动的任务的 pid -

PS C:\Users\Elvis> get-wmiobject win32_process | where{$_.ProcessId -eq nnnn}

(其中 nnnn 是 PID),我会看到列出的许多详细信息,包括这个......

CommandLine         : "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -command "&c:\myDir\myScript.ps1"

这是有道理的,这正是我输入的内容任务定义。

如果对启动时启动的任务执行类似的操作,那么我不会看到完整的命令行,而是会得到“

CommandLine         :

这可能看起来并不重要,但我想检查当我启动一个脚本时是否没有其他版本的脚本正在运行”新副本。我通过在脚本中包含这一行来做到这一点。 (基本上它会检查运行相同脚本名称但具有不同PID的其他powershell进程)

get-wmiobject win32_process | where{$_.processname -eq 'powershell.exe' -and $_.ProcessId -ne $pid -and $_.commandline -match 'myScript'}

我需要能够说服任务调度程序将脚本名称包含在进程详细信息中,或者找到另一种方法来检查是否有另一个副本已经运行的脚本的

I have a powershell script that needs to run 24 * 7.

To make sure it does this, I have created two (almost) identical tasks listed in task scheduler. One starts the task every day at midnight, the other is set to run with the trigger 'At System startup'. The script is set to exit at a minute to midnight.

So far so good, everything works fine. All my bases are covered. The scheduled task takes care of the script 99% of the time, and the 'on startup' task covers the occasional power-failure

However, I've noticed a subtle difference when I look at the process details.

If I open a powershell session and check the pid for the task that started at midnight using this -

PS C:\Users\Elvis> get-wmiobject win32_process | where{$_.ProcessId -eq nnnn}

(where nnnn is the PID) I see lots of details listed, including this....

CommandLine         : "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit -command "&c:\myDir\myScript.ps1"

This makes sense, it's exactly what I put into the task definition.

If do a similar thing with the task that starts on boot-up, then instead of seeing the full command line I just get

CommandLine         :

This may not seem important, but I want to check that no other versions of the script are running when I start a new copy. I do this by including this line in the script. (basically it checks for other powershell process running the same script name but with a different PID)

get-wmiobject win32_process | where{$_.processname -eq 'powershell.exe' -and $_.ProcessId -ne $pid -and $_.commandline -match 'myScript'}

I need to be able to either persuade the task scheduler to include the script name in the process details, or find another way to check if there's another copy of the script already running

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

[浮城] 2025-01-26 03:33:05

使用我所说的“PID 锁定文件”。将PID写入已知文件路径,如果该文件已存在,则检查PID。如果它已经在运行,则抛出错误或以其他方式退出。当脚本退出时,让它删除该文件。

$lockfilePath = "\path\to\script.pid"

try {
  if( Test-Path -PathType Leaf $lockFilePath ) {
  
    $oldPid = ( Get-Content -Raw $lockfilePath ).Trim()
    if( Get-Process -Id $oldPid -EA SilentlyContinue ) {
      throw "Only one instance of this script can run at a time"
    }
  }

  $PID > $lockfilePath

  # Rest of your script goes within this try block

} finally {

  # Add a catch block if you like but this finally code
  # guarantees a deletion attempt will be made on the
  # PID file whether the try block succeeds or errors
  if( Test-Path -PathType Leaf $lockfilePath ) {
    Remove-Item $lockfilePath -Force -EA Continue
  }
}

Use what I call a "PID lockfile". Write the PID to a known file path, if the file already exists, check for the PID. If it's already running, throw an error or otherwise exit. When the script exits have it delete that file.

$lockfilePath = "\path\to\script.pid"

try {
  if( Test-Path -PathType Leaf $lockFilePath ) {
  
    $oldPid = ( Get-Content -Raw $lockfilePath ).Trim()
    if( Get-Process -Id $oldPid -EA SilentlyContinue ) {
      throw "Only one instance of this script can run at a time"
    }
  }

  $PID > $lockfilePath

  # Rest of your script goes within this try block

} finally {

  # Add a catch block if you like but this finally code
  # guarantees a deletion attempt will be made on the
  # PID file whether the try block succeeds or errors
  if( Test-Path -PathType Leaf $lockfilePath ) {
    Remove-Item $lockfilePath -Force -EA Continue
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文