【问题标题】:Scheduling Powershell and batch jobs to run synchronously安排 Powershell 和批处理作业同步运行
【发布时间】:2012-04-10 13:42:40
【问题描述】:

我有 4 台服务器需要进行一些处理。处理分为两部分:

  1. 运行批处理文件
  2. 运行 powershell 脚本

我需要批处理文件在所有服务器上同时运行,最好是同时运行。我目前在所有服务器上都设置了计划任务,因为我们使用网络时间服务,所以它们是同步的。

然后我需要一个接一个地运行 Powershell 脚本,即当 Server1 上的脚本完成时,Server2 上的脚本开始,然后当它完成时,Server3 开始,等等。这可以按照与第 1 部分相同的方式完成1,即计划任务,但是这些任务需要大量不同的时间来完成。

我想避免批处理文件的计划任务选项,即使时间同步,我也希望它们都从一个地方开始。最后,我需要有关如何在不同服务器上以类似队列的方式调用 Powershell 脚本的建议。这可能吗?

编辑 2012-04-11

在 Keith Hill 的回答的帮助下,我设法接近了我需要的东西。在这一点上发布我的代码对我来说是有意义的:

# $strServers[0] must correspond to $strFiles[0]
# $strServers[1] must correspond to $strFiles[1]
# etc.
$strServers = @(
    "di-ads-02",
    "di-ads-03", 
    "si-ads-02",
    "vm-ads-02"
);    
$strFiles = @(
    "D:\Utilities\test.ps1",
    "D:\Utilities\test.ps1", 
    "C:\Utilities\test.ps1",
    "D:\Utilities\test.ps1"
);

try 
{
    for ($i = 0; $i -lt $strFiles.Count; $i++)
    {
        $job = Invoke-Command -cn $strServers[$i] -ScriptBlock {Invoke-Expression $strFiles[$i]} -AsJob;
        # Wait for $job to finish for a maximum of 60 minutes
        Wait-Job $job -Timeout 3600;
    }
}
catch 
{
    Write-Host "ERROR : " + $_;
}

我从 PowerShell 得到以下输出:

Id              Name            State      HasMoreData     Location             Command                  
--              ----            -----      -----------     --------             -------                  
47              Job47           Failed     False           di-ads-02            Invoke-Expression $str...
49              Job49           Failed     False           di-ads-03            Invoke-Expression $str...
51              Job51           Failed     False           si-ads-02            Invoke-Expression $str...
53              Job53           Failed     False           vm-ads-02            Invoke-Expression $str...

它看起来已经完成了一半,但执行失败了。首先,我认为它可能正在运行,但只是没有正确报告。然后我修改了test.ps1 脚本,使其在运行时输出两个文件(stderr 和stdout),以便留下一些证据。当我远程访问这些服务器并在本地运行脚本时,会生成这些文件,但按照上述脚本执行此操作不起作用。

任何帮助将不胜感激。

【问题讨论】:

    标签: windows powershell batch-file scheduled-tasks scheduling


    【解决方案1】:

    如果您可以在服务器上启用 PowerShell 远程处理,则可以使用来自一台机器的作业来编排 PowerShell 脚本的执行,例如:

    $servers = 'server1','server2','server3','server4'
    foreach ($server in $servers)
    {
        $job = Invoke-Command -cn $server -Filepath c:\myscript.ps1 -AsJob
        Wait-Job $job -Timeout 180 # wait maximum of 3 minutes
    }
    

    【讨论】:

    • -FilePath引用的文件是否需要为远程目录格式,例如: \\servername\c$\myscript.ps1?或者它是否将其理解为运行它的服务器的本地?
    • 我刚找到下面here:“当你使用这个参数时,PowerShell将指定脚本文件的内容转换成一个脚本块,将这个脚本块传输到远程计算机,并运行它远程计算机”
    • 是否可以强制它使用远程机器上的脚本?
    • @a12jun - 当然。只需使用 -ScriptBlock 参数而不是 -FilePath 参数,例如$job = Invoke-Command -cn $server -ScriptBlock {C:\myscript.ps1} -AsJob。在这种情况下,myscript.ps1 必须位于每台远程计算机上的相同位置。您还可以使用网络路径 \\server\share\myscript.ps1。
    • @a12jun 不要使用Invoke-Expression,您需要像这样传递文件名:Invoke-Command -cn $strServers[$i] -ScriptBlock {param($file) & $file} -Arg $strFiles[$i] -AsJob。请记住,脚本块被传递给远程计算机以运行,并且它无权访问您的任何本地变量,例如 $strFiles。它只能访问传递给脚本块的参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 2021-01-15
    • 2015-07-30
    • 1970-01-01
    相关资源
    最近更新 更多