9

I am working on some release automation scripts that use Powershell to update existing scheduled tasks which execute various applications. In my script, I can set the Path and Working Directory of the application, but it doesn't seem to save the changes back to the task.

function CreateOrUpdateTaskRunner {
    param (
        [Parameter(Mandatory = $TRUE, Position = 1)][string]$PackageName,
        [Parameter(Mandatory = $TRUE, Position = 2)][Version]$Version,
        [Parameter(Mandatory = $TRUE, Position = 3)][string]$ReleaseDirectory
    )

    $taskScheduler = New-Object -ComObject Schedule.Service
    $taskScheduler.Connect("localhost")
    $taskFolder = $taskScheduler.GetFolder('\')

    foreach ($task in $taskFolder.GetTasks(0)) {

        # Check each action to see if it references the current package
        foreach ($action in $task.Definition.Actions) {

            # Ignore actions that do not execute code (e.g. send email, show message)
            if ($action.Type -ne 0) {
                continue
            }

            # Ignore actions that do not execute the specified task runner
            if ($action.WorkingDirectory -NotMatch $application) {
                continue
            }

            # Find the executable
            $path = Join-Path $ReleaseDirectory -ChildPath $application | Join-Path -ChildPath $Version
            $exe = Get-ChildItem $path -Filter "*.exe" | Select -First 1

            # Update the action with the new working directory and executable
            $action.WorkingDirectory = $exe.DirectoryName
            $action.Path = $exe.FullName
        }
    }
}

I have so far been unable to find an obvious Save function in the documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/aa383607(v=vs.85).aspx). Am I taking the wrong approach here, and need to mess around with the task XML?

3
  • What version of powershell are you working with? Use Get-Host to find out.
    – Colyn1337
    Feb 11, 2015 at 18:30
  • Version 2.0 (see serverfault.com/questions/666671/… for some of my verson-related woes!). If your solution works with a later version of Powershell that is supported by Server 2008 R2 then that will give me extra "push" to get the servers upgraded :-) Feb 12, 2015 at 3:37
  • Server 2008R2 supports up to 4.0 currently. See Windows PowerShell Requirements: technet.microsoft.com/en-us/library/hh847769.aspx
    – Davidw
    Feb 18, 2015 at 4:59

1 Answer 1

2

The RegisterTask method has an update flag that you would use. Something like this:

# Update the action with the new working directory and executable
$action.WorkingDirectory = $exe.DirectoryName
$action.Path = $exe.FullName

#Update Task
$taskFolder.RegisterTask($task.Name, $task.Definition, 4, "<username>", "<password>", 1, $null)

See the msdn article for details on each parameter.

4
  • I really hope this isn't the only solution, as I don't want to be storing username/password combinations in my release scripts if I can help it... Feb 19, 2015 at 1:48
  • I believe you can specify the local system account and leave the password null. Feb 19, 2015 at 2:24
  • My scheduled tasks run under specifically-created service accounts, with database access using Windows authentication, so I would still need to keep the existing credentials. Feb 20, 2015 at 0:37
  • Only well known system accounts get to skip the password requirement same as if you'd update these tasks manually. Even the new powershell cmdlets require the username and password when using a non-well known account. I suppose you could prompt for a password during run time, store it as a secure string in a variable, then access it when needed so it's only stored in memory when running the script. Feb 20, 2015 at 1:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .