foam_sync.ps1 (LIFEBALANCE) 2025-06-19T00:26:39Z
This commit is contained in:
@ -50,30 +50,43 @@ $taskDescription = "Periodically synchronizes the Git repository at $scriptDir u
|
|||||||
$taskPrincipal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive
|
$taskPrincipal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive
|
||||||
|
|
||||||
# Trigger configuration
|
# Trigger configuration
|
||||||
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes $frequencyMinutes)
|
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes $frequencyMinutes) -RepetitionDuration ([TimeSpan]::MaxValue)
|
||||||
|
|
||||||
# Action configuration:
|
# Action configuration:
|
||||||
# We use an indirection technique to ensure the window is truly hidden.
|
# We use an indirection technique to ensure the window is truly hidden.
|
||||||
# The scheduled task launches an initial PowerShell.
|
# The scheduled task launches an initial PowerShell.
|
||||||
# This initial PowerShell then uses Start-Process to launch the *actual* script in a new, hidden PowerShell process.
|
# This initial PowerShell then uses Start-Process to launch the *actual* script in a new, hidden PowerShell process.
|
||||||
|
|
||||||
# 1. Path to the script, with internal double quotes escaped as "" (for the -File parameter of the innermost PowerShell)
|
# 1. Innermost PowerShell's -File argument: Path to the script, with internal double quotes escaped as ""
|
||||||
|
# e.g., \"C:\path\to your script.ps1\"
|
||||||
$scriptPathForInnermostFileParam = $scriptPath.Replace('"', '""')
|
$scriptPathForInnermostFileParam = $scriptPath.Replace('"', '""')
|
||||||
|
$innermostFileArg = "\`"$scriptPathForInnermostFileParam\`""
|
||||||
|
|
||||||
# 2. Argument string for the innermost PowerShell instance (the one executing the actual script)
|
# 2. Argument string for the innermost PowerShell instance (the one executing the actual script)
|
||||||
$innermostPSArgs = "-NoProfile -NonInteractive -ExecutionPolicy Bypass -File \`"$scriptPathForInnermostFileParam\`""
|
# e.g., -NoProfile -NonInteractive -ExecutionPolicy Bypass -File \"C:\path\to your script.ps1\"
|
||||||
|
$innermostPSArgs = "-NoProfile -NonInteractive -ExecutionPolicy Bypass -File $innermostFileArg"
|
||||||
|
|
||||||
# 3. The innermostPSArgs string needs its single quotes escaped (as '') because it will be wrapped in single quotes for Start-Process's -ArgumentList
|
# 3. The innermostPSArgs string needs its single quotes escaped (as '') because it will be wrapped in single quotes for Start-Process's -ArgumentList
|
||||||
$innermostPSArgsEscapedForStartProcess = $innermostPSArgs.Replace("'", "''")
|
$innermostPSArgsEscapedForStartProcess = $innermostPSArgs.Replace("'", "''")
|
||||||
|
|
||||||
# 4. Command to be executed by the intermediate PowerShell (launched by Task Scheduler). This command uses Start-Process.
|
# 4. Command string that the first PowerShell instance (launched by Task Scheduler) will execute using Start-Process.
|
||||||
$commandForIntermediatePS = "Start-Process -FilePath powershell.exe -ArgumentList '$innermostPSArgsEscapedForStartProcess' -WindowStyle Hidden"
|
# e.g., Start-Process -FilePath powershell.exe -ArgumentList '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File \"C:\path\to your script.ps1\"' -WindowStyle Hidden
|
||||||
$taskActionArgument = "-NoProfile -NonInteractive -ExecutionPolicy Bypass -Command \`"$($commandForIntermediatePS.Replace('"', '`"'))\`"" # Escape " in command as `"`
|
$commandToRunViaStartProcess = "Start-Process -FilePath powershell.exe -ArgumentList '$innermostPSArgsEscapedForStartProcess' -WindowStyle Hidden"
|
||||||
|
|
||||||
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $taskActionArgument
|
# 5. Argument string FOR THE TASK SCHEDULER to pass to the first powershell.exe.
|
||||||
|
# The $commandToRunViaStartProcess is the value for -Command, and needs to be quoted for registration.
|
||||||
|
# e.g., -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Start-Process -FilePath powershell.exe -ArgumentList '-NoProfile -NonInteractive -ExecutionPolicy Bypass -File \"C:\path\to your script.ps1\"' -WindowStyle Hidden"
|
||||||
|
$actionArgumentForRegistration = "-NoProfile -NonInteractive -ExecutionPolicy Bypass -Command \`"$commandToRunViaStartProcess\`""
|
||||||
|
|
||||||
|
# 6. Expected argument string WHEN RETRIEVED by Get-ScheduledTask.
|
||||||
|
# Task Scheduler/PowerShell often strips the outermost quotes from the -Command value when retrieved.
|
||||||
|
$expectedRetrievedActionArgument = "-NoProfile -NonInteractive -ExecutionPolicy Bypass -Command $commandToRunViaStartProcess"
|
||||||
|
|
||||||
|
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $actionArgumentForRegistration
|
||||||
|
|
||||||
# Task settings
|
# Task settings
|
||||||
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 1)
|
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
|
||||||
|
-StopIfGoingOnBatteries:$false # Explicitly ensure it doesn't stop
|
||||||
|
|
||||||
# Check and configure the scheduled task
|
# Check and configure the scheduled task
|
||||||
try {
|
try {
|
||||||
@ -85,16 +98,18 @@ try {
|
|||||||
$currentTrigger = $existingTask.Triggers[0]
|
$currentTrigger = $existingTask.Triggers[0]
|
||||||
$currentAction = $existingTask.Actions[0]
|
$currentAction = $existingTask.Actions[0]
|
||||||
|
|
||||||
|
# Check Trigger
|
||||||
$triggerMatches = $false
|
$triggerMatches = $false
|
||||||
if ($currentTrigger -is [Microsoft.Management.Infrastructure.CimInstance] `
|
if ($currentTrigger -is [Microsoft.Management.Infrastructure.CimInstance] `
|
||||||
-and $currentTrigger.RepetitionInterval.TotalMinutes -eq $frequencyMinutes) {
|
-and $currentTrigger.RepetitionInterval.TotalMinutes -eq $frequencyMinutes `
|
||||||
|
-and $currentTrigger.RepetitionDuration -eq ([TimeSpan]::MaxValue)) {
|
||||||
|
# Check duration too
|
||||||
$triggerMatches = $true
|
$triggerMatches = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
$actionMatches = $false
|
$actionMatches = $false
|
||||||
if ($currentAction -is [Microsoft.Management.Infrastructure.CimInstance] `
|
if ($currentAction -is [Microsoft.Management.Infrastructure.CimInstance] `
|
||||||
-and $currentAction.Execute -eq "powershell.exe" `
|
-and $currentAction.Execute -eq "powershell.exe" `
|
||||||
-and $currentAction.Argument -eq $taskActionArgument) {
|
-and $currentAction.Argument -eq $expectedRetrievedActionArgument) { # Compare with the expected retrieved format
|
||||||
$actionMatches = $true
|
$actionMatches = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user