1
\$\begingroup\$
function ExecuteWindowsTaskScheduler {
param(
    [Parameter(Mandatory = $true)]
    [String]$TaskName, #e.g. "Open Notepad task"

    [Parameter(Mandatory = $true)]
    [String]$TimeToExecute, #e.g. "3:45pm/am"

    [Parameter(Mandatory = $true)]
    [ValidateSet('Once','Daily','Weekly, Monthly')]
    [string]$FrequencyToExecute,

    [Parameter(Mandatory = $true)]
    [String]$DomainAndUser, #e.g. "yourdomain\yourusername"

    [Parameter(Mandatory = $true)]
    [String]$ProgramWithPath, #e.g. "C:\PowerShell\yourFile.ps1"

    [Parameter(Mandatory = $false)]
    [bool]${DebugMode}
)

$TriggerParams = @{
    At = $TimeToExecute
}

# Add the appropriate frequency value to the splatting table
if ($FrequencyToExecute -eq 'Monthly') {
    $TriggerParams.Add('Weekly',$true)
}
else {
    $TriggerParams.Add($FrequencyToExecute,$true)
}

# Specify the trigger settings
if ($FrequencyToExecute -eq "Weekly") {
    $Trigger = New-ScheduledTaskTrigger @TriggerParams -WeeksInterval 1 -DaysOfWeek Monday
}
elseIf  ($FrequencyToExecute -eq "Monthly") {
    $Trigger = New-ScheduledTaskTrigger @TriggerParams -WeeksInterval 4 -DaysOfWeek Monday
}
else {
    $Trigger = New-ScheduledTaskTrigger @TriggerParams
}

# Specify what script to run and with its parameters
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument $ProgramWithPath 
$TaskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $TaskName }

if($TaskExists) {
    Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false
}

I'm definitely not happy with this part of the code:

# Add the appropriate frequency value to the splatting table
    if ($FrequencyToExecute -eq 'Monthly') {
        $TriggerParams.Add('Weekly',$true)
    }
    else {
        $TriggerParams.Add($FrequencyToExecute,$true)
    }

    # Specify the trigger settings
    if ($FrequencyToExecute -eq "Weekly") {
        $Trigger = New-ScheduledTaskTrigger @TriggerParams -WeeksInterval 1 -DaysOfWeek Monday
    }
    elseIf  ($FrequencyToExecute -eq "Monthly") {
        $Trigger = New-ScheduledTaskTrigger @TriggerParams -WeeksInterval 4 -DaysOfWeek Monday
    }
    else {
        $Trigger = New-ScheduledTaskTrigger @TriggerParams
    }

Is there a way to improve this part? I mean, I had to create a small hack because there is no Monthly parameter for New-ScheduledTaskTrigger.

\$\endgroup\$
3
  • \$\begingroup\$ You could probably change [bool]$DebugMode to [switch]$DebugMode \$\endgroup\$ Sep 6, 2018 at 19:24
  • \$\begingroup\$ @themadtechnician could you explain why? I don't get it. \$\endgroup\$
    – Pankwood
    Sep 7, 2018 at 1:15
  • \$\begingroup\$ I wrote that before thinking much into it, but [bool] to me looks like it expects input, like -DebugMode $true or -DebugMode $false, while a switch is $false when omitted, and $true is there. I admit, I haven't tested it, it just makes more sense to me in context of syntax and purpose. It feels more intuitive. \$\endgroup\$ Sep 7, 2018 at 18:07

1 Answer 1

1
\$\begingroup\$

Your instincts are good to dislike that bit of code.

Whenever you can, you should put code in data structures rather than in control statements. It makes the code clearer and easier to maintain.

So for instance you could put your settings in a hash table like this:

$FrequencySettings = @{
    Once     = @{Once   = $true}
    Daily    = @{Daily  = $true}
    Weekly   = @{Weekly = $true; WeeksInterval = 1; DaysOfWeek = 'Monday'}
    Monthly  = @{Weekly = $true; WeeksInterval = 4; DaysOfWeek = 'Monday'}
    }

# Let's test it:
$FrequencyParams = $FrequencySettings['Monthly']
New-ScheduledTaskTrigger @FrequencyParams -At "0:00"

I haven't checked that the particular settings I've put in above are all correct. I just want to show you the basic idea.

\$\endgroup\$
1
  • \$\begingroup\$ To expand on this, you could define your other trigger params in $TriggerParams =@{ At = $TimeToExecute} and then just add the schedule to that like $TriggerParams += $FrequencySettings[$FrequencyToExecute]. \$\endgroup\$ Sep 6, 2018 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.