diff --git a/foam_sync.ps1 b/foam_sync.ps1 index 8ea2d0d..0c6c9b6 100644 --- a/foam_sync.ps1 +++ b/foam_sync.ps1 @@ -33,6 +33,7 @@ # --- Configuration --- $frequencyMinutes = 2 # How often the Scheduled Task should attempt to run this script +$executionTimeLimitBufferSeconds = 30 # Buffer: task stops if it runs longer than (frequency - buffer) # --- Script Setup --- $scriptPath = $MyInvocation.MyCommand.Path @@ -85,58 +86,82 @@ $expectedRetrievedActionArgument = "-NoProfile -NonInteractive -ExecutionPolicy $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $actionArgumentForRegistration # Task settings -$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Hours 1) ` - -StopIfGoingOnBatteries:$false # Explicitly ensure it doesn't stop +# Calculate a realistic execution time limit based on the frequency +$executionTimeLimitTotalSeconds = ($frequencyMinutes * 60) - $executionTimeLimitBufferSeconds +if ($executionTimeLimitTotalSeconds -lt 30) { + # Ensure a minimum sensible execution time (e.g., 30 seconds) + $executionTimeLimitTotalSeconds = 30 +} +$taskExecutionTimeLimit = New-TimeSpan -Seconds $executionTimeLimitTotalSeconds +$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit $taskExecutionTimeLimit # Check and configure the scheduled task try { $existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue - $needsUpdateOrCreation = $true if ($existingTask) { Write-Host "Scheduled task '$taskName' already exists. Checking configuration..." $currentTrigger = $existingTask.Triggers[0] $currentAction = $existingTask.Actions[0] + # You could also compare $existingTask.Principal.UserId with $taskPrincipal.UserId + # and $existingTask.Description with $taskDescription if strict matching is needed for those. # Check Trigger $triggerMatches = $false if ($currentTrigger -is [Microsoft.Management.Infrastructure.CimInstance] ` -and $currentTrigger.RepetitionInterval.TotalMinutes -eq $frequencyMinutes ` -and $currentTrigger.RepetitionDuration -eq ([TimeSpan]::MaxValue)) { - # Check duration too $triggerMatches = $true } + + # Check Action $actionMatches = $false if ($currentAction -is [Microsoft.Management.Infrastructure.CimInstance] ` -and $currentAction.Execute -eq "powershell.exe" ` - -and $currentAction.Argument -eq $expectedRetrievedActionArgument) { # Compare with the expected retrieved format + -and $currentAction.Argument -eq $expectedRetrievedActionArgument) { $actionMatches = $true } - if ($triggerMatches -and $actionMatches) { + # Check Principal (example, can be expanded) + $principalMatches = ($existingTask.Principal.UserId -eq $taskPrincipal.UserId) + + # Check Settings (specifically ExecutionTimeLimit for this change) + $settingsMatch = $false + if ($existingTask.Settings.ExecutionTimeLimit -eq $taskExecutionTimeLimit) { + $settingsMatch = $true + } + + if ($triggerMatches -and $actionMatches -and $principalMatches -and $settingsMatch) { Write-Host "Scheduled task '$taskName' is already correctly configured." - $needsUpdateOrCreation = $false } else { - Write-Host "Scheduled task '$taskName' configuration differs. It will be updated." - Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue + Write-Host "Scheduled task '$taskName' configuration differs. Attempting to update in-place..." + try { + Set-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Principal $taskPrincipal -Description $taskDescription -ErrorAction Stop + Write-Host "Scheduled task '$taskName' updated successfully." + } + catch { + Write-Warning "Failed to update scheduled task '$taskName' in-place. Error: $($_.Exception.Message)" + Write-Warning "The task remains in its previous state. Manual intervention may be required or re-run with Administrator privileges." + # We intentionally DO NOT unregister here to avoid the scenario you described. + } } } - - if ($needsUpdateOrCreation) { - if ($existingTask -and -not ($triggerMatches -and $actionMatches)) { - Write-Host "Updating scheduled task '$taskName'..." + else { + Write-Host "Creating scheduled task '$taskName'..." + try { + Register-ScheduledTask -TaskName $taskName -Description $taskDescription -Principal $taskPrincipal -Trigger $trigger -Action $action -Settings $settings -ErrorAction Stop + Write-Host "Scheduled task '$taskName' created successfully." } - else { - Write-Host "Creating scheduled task '$taskName'..." + catch { + Write-Warning "Failed to create scheduled task '$taskName'. Error: $($_.Exception.Message)" + Write-Warning "You may need to run this script as Administrator." } - Register-ScheduledTask -TaskName $taskName -Description $taskDescription -Principal $taskPrincipal -Trigger $trigger -Action $action -Settings $settings -ErrorAction Stop - Write-Host "Scheduled task '$taskName' registered/updated successfully." } } catch { - Write-Warning "Failed to register or update scheduled task '$taskName'. Error: $($_.Exception.Message)" - Write-Warning "You may need to run this script as Administrator once to register the scheduled task." + # This outer catch is for unexpected errors, e.g., if Get-ScheduledTask had -ErrorAction Stop + Write-Warning "An unexpected error occurred during scheduled task setup for '$taskName'. Error: $($_.Exception.Message)" } # --- Git Operations ---