如何使用 powershell 运行 将 Azure VM 中的长 运行ning .CMD 文件作为后台作业

How to run a long running .CMD file inside an Azure VM as a background job using powershell

我已使用自定义脚本扩展将文件夹从容器复制到订阅中的所有 Azure 虚拟机。我在该文件夹中有一个 .cmd 文件,我需要在订阅中的每个虚拟机上 运行。 .cmd 文件是一个长 运行ning 命令,永远不会结束。我需要在后台 运行 它。我试过 invoke-command、start-process、invoke-expression、invoke-azvm运行command -asjob 等,但实际上没有任何东西触发 .cmd 文件。我可以通过登录 vm 或直接从 运行 命令 运行 来 运行 它,但我想 运行 它在后台。我也试过设置计划任务,但没有用。有什么方法可以更有效地做到这一点吗?

您不能直接在 ScriptBlock 中传递变量。使用 '-ArgumentList' 参数或 'Using' 变量。 这适用于 Start-Job、Invoke-Command 等

此 ScriptBlock 将无法正确执行 因为 $path 的值将始终为 null:

Start-Job -ScriptBlock { set-location $path ; &filename.cmd }

虽然这些命令会起作用:

# With '-ArgumentList' parameter
Start-Job -ScriptBlock { Set-Location $args[0] ; &.\filename.cmd } -ArgumentList $path

# With 'Using' variable
Start-Job -ScriptBlock { Set-Location $Using:path ; &.\filename.cmd }

请注意,最新版本的 Powershell 添加了一个参数,以便能够为 Start-Job 和 Invoke-Command cmdlet 指定工作目录(-WorkingDirectory )

在测试时,我注意到一些问题很可能与作业中使用的 Set-Location 命令有关。没有详细说明,我发现这样 运行 更可靠:

# With '-ArgumentList' parameter
Start-Job -ScriptBlock { &"$($args[0])filename.cmd" } -ArgumentList $path

# With 'Using' variable
Start-Job -ScriptBlock { &"$($Using:path)filename.cmd" }

最后,如果适用于您的情况,您可以考虑使用 Start-Process cmdlet 而不是 Start-Job。 Start-Process 允许您继续执行脚本而无需等待 *.cmd 批处理完成...而且使用起来更简单:

Start-Process -FilePath "filename.cmd" -WorkingDirectory $path