Functions/Helper/ScheduledTask/Set-ValentiaScheduledTask.ps1
#Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to set TaskScheduler and define them as enumerable. .DESCRIPTION You can pass several task scheduler definition at once. .NOTES Author: guitarrapc Created: 11/Aug/2014 .EXAMPLE $param = @{ taskName = "Sample Repeatable Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true }, @{ taskName = "Sample Daily Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]"00:00:00" Daily = $true Hidden = $true Disable = $false Force = $true }, @{ taskName = "Sample OneTime Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true } $Credential = Get-ValentiaCredential foreach ($p in $param.GetEnumerator()) { Set-ValentiaScheduledTask @p -Credential $Credential } # Multipole task With Credential .EXAMPLE $param = @{ taskName = "Sample No Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true } Set-ValentiaScheduledTask @param # single task without credential .EXAMPLE $param = @{ taskName = "Sample High Runlevel without Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true RunLevel = "Highest" } Set-ValentiaScheduledTask @param # single task without credential and set Runlevel High .EXAMPLE $param = @{ taskName = "Sample High Runlevel with Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true RunLevel = "Highest" } $Credential = Get-ValentiaCredential Set-ValentiaScheduledTask @param -Credential $Credential # single task with credential and set Runlevel High .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Set-ValentiaScheduledTask { [CmdletBinding(DefaultParameterSetName = "ScheduledDuration")] param ( [parameter(mandatory = $false, Position = 0)] [string]$Execute, [parameter(mandatory = $false, Position = 1)] [string]$Argument = "", [parameter(mandatory = $false, Position = 2)] [string]$WorkingDirectory = "", [parameter(mandatory = $true, Position = 3)] [string]$TaskName, [parameter(mandatory = $false, Position = 4)] [string]$TaskPath = "\", [parameter(mandatory = $false, Position = 5)] [datetime[]]$ScheduledAt, [parameter(mandatory = $false, Position = 6, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledTimeSpan = ([TimeSpan]::FromHours(1)), [parameter(mandatory = $false, Position = 7, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledDuration = [TimeSpan]::MaxValue, [parameter(mandatory = $false, Position = 8, parameterSetName = "Daily")] [bool]$Daily = $false, [parameter(mandatory = $false, Position = 9, parameterSetName = "Once")] [bool]$Once = $false, [parameter(mandatory = $false, Position = 10)] [string]$Description, [parameter(mandatory = $false, Position = 11)] [PScredential]$Credential = $null, [parameter(mandatory = $false, Position = 12)] [bool]$Disable = $true, [parameter(mandatory = $false, Position = 13)] [bool]$Hidden = $true, [parameter(mandatory = $false, Position = 14)] [TimeSpan]$ExecutionTimeLimit = ([TimeSpan]::FromDays(3)), [parameter(mandatory = $false,Position = 15)] [ValidateSet("At", "Win8", "Win7", "Vista", "V1")] [string]$Compatibility = "Win8", [parameter(mandatory = $false,Position = 16)] [ValidateSet("Highest", "Limited")] [string]$Runlevel = "Limited", [parameter(mandatory = $false, Position = 17)] [bool]$Force = $false ) end { Write-Verbose ($VerboseMessages.CreateTask -f $TaskName, $TaskPath) # exist $existingTaskParam = @{ TaskName = $TaskName TaskPath = $TaskPath } $currentTask = GetExistingTaskScheduler @existingTaskParam #region Exclude Action Change : Only Disable / Enable Task if (($Execute -eq "") -and (TestExistingTaskScheduler -Task $currentTask)) { EnableDisableScheduleTask -Disable $Disable return; } #endregion #region Include Action Change # credential if($Credential -ne $null) { # Credential $credentialParam = @{ User = $Credential.UserName Password = $Credential.GetNetworkCredential().Password } # Principal $principalParam = @{ UserId = $Credential.UserName RunLevel = $Runlevel LogOnType = "InteractiveOrPassword" } } # validation if ($Execute -eq ""){ throw New-Object System.InvalidOperationException ($ErrorMessages.ExecuteBrank) } if (Test-ValentiaPowerShellElevated) { if (TestExistingTaskSchedulerWithPath @existingTaskParam) { throw New-Object System.InvalidOperationException ($ErrorMessages.SameNameFolderFound -f $taskName) } } # Action $actionParam = @{ Argument = $Argument Execute = $Execute WorkingDirectory = $WorkingDirectory } # trigger $triggerParam = @{ ScheduledTimeSpan = $scheduledTimeSpan ScheduledDuration = $scheduledDuration ScheduledAt = $ScheduledAt Daily = $Daily Once = $Once } # Description if ($Description -eq ""){ $Description = "No Description"} # Setup Task items $action = CreateTaskSchedulerAction @actionParam $trigger = CreateTaskSchedulerTrigger @triggerParam $settings = New-ScheduledTaskSettingsSet -Disable:$Disable -Hidden:$Hidden -Compatibility $Compatibility -ExecutionTimeLimit $ExecutionTimeLimit $registerParam = if ($null -ne $Credential) { Write-Verbose $VerboseMessages.UsePrincipal $principal = New-ScheduledTaskPrincipal @principalParam $scheduledTask = New-ScheduledTask -Description $Description -Action $action -Settings $settings -Trigger $trigger -Principal $principal @{ InputObject = $scheduledTask TaskName = $TaskName TaskPath = $TaskPath Force = $Force } } else { Write-Verbose $VerboseMessages.SkipPrincipal @{ Action = $action Settings = $settings Trigger = $trigger Description = $Description TaskName = $TaskName TaskPath = $TaskPath Runlevel = $Runlevel Force = $Force } } # Register if ($force -or -not(TestExistingTaskScheduler -Task $currentTask)) { if ($null -ne $Credential) { Register-ScheduledTask @registerParam @credentialParam return; } else { Register-ScheduledTask @registerParam return; } } #endregion } begin { $ErrorMessages = Data { ConvertFrom-StringData -StringData @" InvalidTrigger = "Invalid Operation detected, you can't set same or greater timespan for RepetitionInterval '{0}' than RepetitionDuration '{1}'." ExecuteBrank = "Invalid Operation detected, Execute detected as blank. You must set executable string." SameNameFolderFound = "Already same FolderName existing as TaskPath : \\{0}\\ . Please change TaskName or Rename TaskFolder.." "@ } $VerboseMessages = Data { ConvertFrom-StringData -StringData @" CreateTask = "Creating Task Scheduler Name '{0}', Path '{1}'" UsePrincipal = "Using principal with Credential. Execution will be fail if not elevated." SkipPrincipal = "Skip Principal and Credential. Runlevel Highest requires elevated." "@ } $WarningMessages = Data { ConvertFrom-StringData -StringData @" TaskAlreadyExist = '"{0}" already exist on path "{1}". Please Set "-Force $true" to overwrite existing task.' "@ } function GetExistingTaskScheduler ($TaskName, $TaskPath) { return Get-ScheduledTask | where TaskName -eq $taskName | where TaskPath -eq $taskPath } function TestExistingTaskScheduler ($Task) { $result = ($task | Measure-Object).count -ne 0 if ($result){ Write-Verbose ($WarningMessages.TaskAlreadyExist -f $task.taskName, $task.taskPath) } return $result } function TestExistingTaskSchedulerWithPath ($TaskName, $TaskPath) { if ($TaskPath -ne "\"){ return $false } # only run when taskpath is \ $path = Join-Path $env:windir "System32\Tasks" $result = Get-ChildItem -Path $path -Directory | where Name -eq $TaskName if (($result | measure).count -ne 0) { return $true } return $false } function CreateTaskSchedulerAction ($Argument, $Execute, $WorkingDirectory) { if (($Argument -eq "") -and ($WorkingDirectory -eq "")) { return New-ScheduledTaskAction -Execute $execute } if (($Argument -ne "") -and ($WorkingDirectory -eq "")) { return New-ScheduledTaskAction -Execute $Execute -Argument $Argument } if (($Argument -ne "") -and ($WorkingDirectory -ne "")) { return New-ScheduledTaskAction -Execute $Execute -Argument $Argument -WorkingDirectory $WorkingDirectory } } function CreateTaskSchedulerTrigger ($ScheduledTimeSpan, $ScheduledDuration, $ScheduledAt, $Daily, $Once) { $trigger = if (($false -eq $Daily) -and ($false -eq $Once)) { $ScheduledTimeSpanPair = New-ValentiaZipPairs -first $ScheduledTimeSpan -Second $ScheduledDuration $ScheduledAtPair = New-ValentiaZipPairs -first $ScheduledAt -Second $ScheduledTimeSpanPair $ScheduledAtPair ` | %{ if ($_.Item2.Item1 -ge $_.Item2.Item2){ throw New-Object System.InvalidOperationException ($ErrorMessages.InvalidTrigger -f $_.Item2.Item1, $_.Item2.Item2)} New-ScheduledTaskTrigger -At $_.Item1 -RepetitionInterval $_.Item2.Item1 -RepetitionDuration $_.Item2.Item2 -Once } } elseif ($Daily) { $ScheduledAt | %{New-ScheduledTaskTrigger -At $_ -Daily} } elseif ($Once) { $ScheduledAt | %{New-ScheduledTaskTrigger -At $_ -Once} } return $trigger } function EnableDisableScheduleTask { [OutputType([Void])] [CmdletBinding()] param ( [bool]$Disable ) switch ($Disable) { $true { $currentTask | Disable-ScheduledTask return; } $false { $currentTask | Enable-ScheduledTask return; } } } } } |