章鱼部署 Windows 计划任务

Octopus Deploy Windows Scheduled Task

这个问题是针对所有使用 Octopus Deploy 到 运行 计划任务的人的。

https://library.octopusdeploy.com/step-template/actiontemplate-windows-scheduled-task-create

有没有遇到过定时任务必须指定"Start in (optional):"参数的情况?

我想知道这是否可以通过 Octopus Deploy 实现,或者是否有任何解决方法?

Octopus 部署社区步骤只是带有变量的 Powershell 脚本。您可以编辑 Powershell 为 "Start in" 路径设置任何变量并将其传递给计划任务。我可以给你一个你需要的例子。

更新

在准确查看任务的 Posh 脚本后,我认为更好的选择是为定义任务参数的 XML 文件添加一个参数,并在 Octopus 部署步骤中进行设置。如果您需要提供除 "Start in" 参数之外的任何其他参数,这将为您提供最大的可修复性。

更新 2

所以我写了一个自定义步骤来做你想做的事,然后看着社区提要,傻我。已经有用于从 XML 文件创建计划任务的 stemp 模板。 XML 会让你设置工作目录。步骤模板名为 "Create Scheduled Tasks From XML",您可以在 http://library.octopusdeploy.com/step-templates/26c779af-4cce-447e-98bb-4741c25e0b3c/actiontemplate-create-scheduled-tasks-from-xml.

找到它

此外,这里是我进行自定义步骤的地方,它只是 Powershell:

$ErrorActionPreference = "Stop";
Set-StrictMode -Version "Latest";

function New-ScheduledTask {
    param (
        [Parameter(Mandatory = $true)][hashtable] $octopusParameters
    )

    $arguments = @{
        TaskName = $octopusParameters['TaskName']
        User = $octopusParameters['RunAsUser']
    }

    if ($octopusParameters['RunAsPassword']) {
        $arguments.Password = $runAsPassword
    }

    if ($octopusParameters.ContainsKey('RunWithElevatedPermissions')) {
        if ([boolean]::Parse($octopusParameters['RunWithElevatedPermissions'])) {
            $arguments.RunLevel = 'Highest'
        }
    }

    switch ($octopusParameters['Schedule']) {
        'Once' {
            $triggerArguments.Once = $true
            $triggerArguments.At = $runAt
        }
        'Daily' {
            $triggerArguments.Daily = $true
            $triggerArguments.At = $runAt

            if ($interval) {
                $triggerArguments.DaysInterval = $octopusParameters['Interval']
            }
        }
        'Weekly' {
            $triggerArguments.Weekly = $true
            $triggerArguments.At = $runAt

            if ($interval) {
                $triggerArguments.WeeksInterval = $octopusParameters['Interval']
            }
        }
        'Startup' {
            $triggerArguments.AtStartup = $true
        }
        'Logon' {
            $triggerArguments.AtLogOn = $true
        }
    }

    $actionArguments = @{
        Execute = $octopusParameters['Executable']
        Argument = $octopusParameters['Arguments']
        WorkingDirectory = $octopusParameters['WorkingDirectory']
    }
    $arguments.Action = New-ScheduledTaskAction @actionArguments

    $triggerArguments = @{
        TaskName = $taskName
        User = $runAsUser
    }
    $arguments.Trigger = New-ScheduledTaskTrigger @triggerArguments

    Write-Output "Creating Scheduled Task - $taskName"

    Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction:SilentlyContinue
    Register-ScheduledTask @arguments | Out-Null

    Write-Output "Successfully Created $taskName"
}

# only execute the step if it's called from octopus deploy,
# and skip it if we're runnning inside a Pester test
if (Test-Path -Path "Variable:octopusParameters") {
    New-ScheduledTask $octopusParameters
}

遇到同样的问题后,我发现 schtasks.exe 没有使用工作目录(开始于(可选))参数。

我做了以下事情:

  1. 使用八达通模板创建计划任务(Windows计划任务-创建-使用密码)
  2. 使用 PowerShell
  3. 将计划任务另存为 XML
  4. 编辑 XML 添加工作目录
  5. 使用八达通模板(从 XML 创建计划任务)使用更新的 XML 创建计划任务。

这是我在 Octopus 中使用的 PowerShell,用于获取计划任务 XML 并插入工作目录节点:

$scheduleFolder = $OctopusParameters["ScheduledTaskFolder"]
$scheduleName = $OctopusParameters["ScheduledTaskName"]
$scheduleWorkingDirectory = $OctopusParameters["ScheduledTaskWorkingDirectory"]
$scheduleXmlFileName = $OctopusParameters["ScheduledTaskXmlFileName"]
$installFolder = $OctopusParameters["InstallFolder"]

Write-Output "Connecting to Schedule Service"
$schedule = New-Object -Com("Schedule.Service") 
$schedule.Connect()

Write-Output "Getting $scheduleName task in folder $scheduleFolder as xml"
$task = $schedule.GetFolder($scheduleFolder).GetTasks(0) | Where {$_.Name -eq 
$scheduleName}

$xml = [xml]$task.Xml

# Parent node
$execNode = $xml.Task.Actions.Exec

# Create WorkingDirectory node
$workingDirectoryElement = $xml.CreateElement("WorkingDirectory", 
$execNode.NamespaceURI) 
$workingDirectoryElement.InnerText = $scheduleWorkingDirectory

# Insert the WorkingDirectory node after the last child node
Write-Output "Inserting WorkingDirectory node in $execNode.Name node"
$numberExecNodes = $execNode.ChildNodes.Count

$execNode.InsertAfter($workingDirectoryElement, $execNode.ChildNodes[$numberExecNodes 
- 1])

# Output the xml to a file
Write-Output "Saving $installFolder$scheduleXmlFileName"
$xml.Save("$installFolder$scheduleXmlFileName")

另一种选择是将 XML 文件(带有工作目录节点)保存为项目的一部分,然后使用 Octopus 模板部署它(从 XML 创建计划任务)。

...
  <Actions Context="Author">
    <Exec>
      <Command>"C:\Program Files\Test Application\Application.exe"</Command>
      <WorkingDirectory>C:\Program Files\Test Application</WorkingDirectory>
    </Exec>
  </Actions>
</Task>