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
.
1 Answer 1
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.
-
\$\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\$TheMadTechnician– TheMadTechnician2018年09月06日 19:22:57 +00:00Commented Sep 6, 2018 at 19:22
[bool]$DebugMode
to[switch]$DebugMode
\$\endgroup\$[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\$