Search code examples
windowspowershellscheduled-taskspowershell-4.0azure-powershell

Creating Scheduled Task using PowerShell


I am working on script which will execute on next day and then will run every other 1,2 and 3 day(s). Here is my script:

#The script below will run as the specified user (you will be prompted for credentials)
#PATH C:\backup\scripts\ will need to be replaced and created in preferred location where the respective backup scripts will be stored

$jobname0 = "Full Backup"
$jobname1 = "Incremental Backup1"
$jobname2 = "Incremental Backup2"
# Change these script location to whatever you want
$script0 = "C:\backup\scripts\full.bat"
$script1 =  "C:\backup\scripts\inc1.cmd"
$script2 =  "C:\backup\scripts\inc2.ps1"
$repeat = (New-TimeSpan -Hours 72 )


# and is set to be elevated to use the highest privileges.
# The task will run every 72hrs (3days) specified in $repeat.
$action0 = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument  "$script0; quit"
$action1 = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument  "$script1; quit"
$action2 = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument  "$script2; quit"

$duration = (New-TimeSpan -Days (365 * 20))
$trigger0 = New-ScheduledTaskTrigger -Once -At 00:00AM -RepetitionInterval $repeat -RepetitionDuration $duration
$trigger1 = New-ScheduledTaskTrigger -Once -At 00:01AM -RepetitionInterval $repeat -RepetitionDuration $duration
$trigger2 = New-ScheduledTaskTrigger -Once -At (00:01AM).AddTime(48:00) -RepetitionInterval $repeat -RepetitionDuration $duration

$msg = "Enter the username and password that will run the task"; 
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
$username = $credential.UserName
$password = $credential.GetNetworkCredential().Password
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd

Register-ScheduledTask -TaskName $jobname0 -Action $action0 -Trigger $trigger0 -RunLevel Highest -User $username -Password $password -Settings $settings 
Register-ScheduledTask -TaskName $jobname1 -Action $action1 -Trigger $trigger1 -RunLevel Highest -User $username -Password $password -Settings $settings 
Register-ScheduledTask -TaskName $jobname2 -Action $action2 -Trigger $trigger2 -RunLevel Highest -User $username -Password $password -Settings $settings

How I can add days instead of time into the trigger. I appreciate all your help.


Solution

  • To answer your question precisely:

    Just replace $repeat = (New-TimeSpan -Hours 72 ) with $repeat = (New-TimeSpan -Days 3) and you've added days instead of time Hours.


    To add some additional information & tips:

    Consider using Splatting instead of this big bunch of variables. The advantage of using variables is reusability. As you define e.g. $jobname0 only to use it as parameter, it has (nearly) no advantage.

    Your code could look like this

    $credential = $Host.UI.PromptForCredential(
        "Task username and password",
        "Enter the username and password that will run the task",
        "$env:userdomain\$env:username",
        $env:userdomain
    )
    
    $repeat = (New-TimeSpan -Hours 72 )
    $duration = (New-TimeSpan -Days (365 * 20))
    $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable -DontStopOnIdleEnd
    
    $job0 = @{
        "TaskName" = "Full Backup";
        "Action"   = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "C:\backup\scripts\full.bat;quit";
        "Trigger"  = New-ScheduledTaskTrigger -Once -At 00:00AM -RepetitionInterval $repeat -RepetitionDuration $duration;
        "RunLevel" = "Highest";
        "User"     = $credential.UserName;
        "Password" = $credential.GetNetworkCredential().Password;
        "Settings" = $settings;
    }
    
    $job1 = @{
        "TaskName" = "2nd one";
        "Action"   = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "C:\2ndScript;quit";
        "Trigger"  = New-ScheduledTaskTrigger -Once -At 10:00AM -RepetitionInterval $repeat -RepetitionDuration $duration;
        "RunLevel" = "Highest";
        "User"     = $credential.UserName;
        "Password" = $credential.GetNetworkCredential().Password;
        "Settings" = $settings;
    }
    #[...]
    Register-ScheduledTask $job0
    Register-ScheduledTask $job1
    #[...]
    

    Using that technique, one is able to create and reuse templates. This avoids boilerplate and duplicates.

    $template = @{
        "TaskName" = "";
        #[...]
        "Settings" = $settings;
    }
    
    $job0 = $template.psobject.Copy()
    $job1 = $template.psobject.Copy()
    
    $job0.Action = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "MyFirstJob";
    $job0.TaskName = "1stOne"
    $job1.Action = New-ScheduledTaskAction –Execute "$pshome\powershell.exe" -Argument "2ndJob";
    $job1.Trigger = New-ScheduledTaskTrigger -Once -At 00:00AM -RepetitionInterval $repeat -RepetitionDuration $duration;
    #[...] and so on
    
    Register-ScheduledTask @job0
    Register-ScheduledTask @job1
    #[...]