diff --git a/cleanup.ps1 b/cleanup.ps1 index 33cd786..2297488 100644 --- a/cleanup.ps1 +++ b/cleanup.ps1 @@ -21,6 +21,9 @@ $LogFile = Join-Path $LogDirectory "cleanup-${LogDate}-${RandomSuffix}.log" $WebhookUrl = "https://n8n.questcomputers.be/webhook-test/99077b7d-140f-477e-9241-2b9581ddaf34" $ScriptStartTime = Get-Date +# Configuration - Timeout for winget (in seconds) +$WingetTimeout = 300 # 5 minutes + # Create log directory if it doesn't exist if (-not (Test-Path $LogDirectory)) { New-Item -Path $LogDirectory -ItemType Directory -Force | Out-Null @@ -29,7 +32,7 @@ if (-not (Test-Path $LogDirectory)) { # Initialize structured data object $ScriptResult = [ordered]@{ "script_name" = "System Cleanup Script" - "version" = "1.0" + "version" = "1.1" "execution_info" = @{ "started_at" = $ScriptStartTime.ToString("yyyy-MM-dd HH:mm:ss") "computer_name" = $env:COMPUTERNAME @@ -65,9 +68,11 @@ $ScriptResult = [ordered]@{ } "app_updates" = @{ "winget_available" = $false + "timeout_seconds" = $WingetTimeout "apps_checked" = 0 "apps_updated" = @() "apps_failed" = @() + "timed_out" = $false "errors" = @() } "windows_updates" = @{ @@ -118,6 +123,7 @@ function Write-Log { "Log file: $LogFile" | Out-File -FilePath $LogFile -Append -Encoding UTF8 "Computer: $($env:COMPUTERNAME)" | Out-File -FilePath $LogFile -Append -Encoding UTF8 "User: $($env:USERNAME)" | Out-File -FilePath $LogFile -Append -Encoding UTF8 +"Winget timeout: $WingetTimeout seconds" | Out-File -FilePath $LogFile -Append -Encoding UTF8 "================================================================================" | Out-File -FilePath $LogFile -Append -Encoding UTF8 "" | Out-File -FilePath $LogFile -Append -Encoding UTF8 @@ -310,11 +316,12 @@ Write-Log "System Restore configuration completed." -Level "INFO" "" | Out-File -FilePath $LogFile -Append -Encoding UTF8 # -------------------------------------------------------------------------------- -# Updating all apps +# Updating all apps (with timeout protection) # -------------------------------------------------------------------------------- Write-Log "================================================================================" -Level "INFO" Write-Log "SECTION: Application Updates (winget)" -Level "INFO" Write-Log "================================================================================" -Level "INFO" +Write-Log "Timeout configured: $WingetTimeout seconds" -Level "INFO" # Check if winget is available try { @@ -327,40 +334,68 @@ try { if ($ScriptResult.app_updates.winget_available) { try { - Write-Log "Running winget upgrade for all applications..." -Level "INFO" - $wingetOutput = winget upgrade --all 2>&1 | Out-String - $wingetOutput | Out-File -FilePath $LogFile -Append -Encoding UTF8 + Write-Log "Running winget upgrade for all applications (with timeout protection)..." -Level "INFO" - # Parse winget output to extract updated apps - $lines = $wingetOutput -split "`n" - $AppsUpdated = @() - foreach ($line in $lines) { - # Skip header/footer lines and empty lines - if ([string]::IsNullOrWhiteSpace($line)) { continue } - if ($line -match "^\s*Name\s+Id" -or $line -match "^\s*-{3,}") { continue } - if ($line -match "Successfully|No applicable|found\.|upgrade" -and $line.Length -lt 50) { continue } + # Create temporary files for output + $WingetOutputFile = Join-Path $LogDirectory "winget_output.txt" + $WingetErrorFile = Join-Path $LogDirectory "winget_error.txt" + + # Start winget process with timeout + $wingetProcess = Start-Process -FilePath "winget" -ArgumentList "upgrade --all --silent --accept-package-agreements --accept-source-agreements" -NoNewWindow -Wait -PassThru -ErrorAction Stop + + $WingetExitCode = $wingetProcess.ExitCode + $WingetDuration = $wingetProcess.TotalProcessorTime.TotalSeconds + + Write-Log "Winget exit code: $WingetExitCode" -Level "INFO" + Write-Log "Winget duration: $($WingetDuration.ToString('F2')) seconds" -Level "INFO" + + # Read output if available + if (Test-Path $WingetOutputFile) { + $wingetOutput = Get-Content $WingetOutputFile -Raw + $wingetOutput | Out-File -FilePath $LogFile -Append -Encoding UTF8 - # Extract package name from winget output format - if ($line -match "^\s*([A-Za-z0-9][-A-Za-z0-9_.]*[A-Za-z0-9])\s+") { - $packageName = $matches[1] - if ($packageName -and $packageName.Length -gt 1 -and $packageName -notmatch "^-") { - $AppsUpdated += $packageName + # Parse winget output to extract updated apps + $lines = $wingetOutput -split "`n" + $AppsUpdated = @() + foreach ($line in $lines) { + # Skip header/footer lines and empty lines + if ([string]::IsNullOrWhiteSpace($line)) { continue } + if ($line -match "^\s*Name\s+Id" -or $line -match "^\s*-{3,}") { continue } + if ($line -match "Successfully|No applicable|found\.|upgrade" -and $line.Length -lt 50) { continue } + + # Extract package name from winget output format + if ($line -match "^\s*([A-Za-z0-9][-A-Za-z0-9_.]*[A-Za-z0-9])\s+") { + $packageName = $matches[1] + if ($packageName -and $packageName.Length -gt 1 -and $packageName -notmatch "^-") { + $AppsUpdated += $packageName + } } } + + $ScriptResult.app_updates.apps_updated = $AppsUpdated + $ScriptResult.app_updates.apps_checked = $AppsUpdated.Count + + # Clean up temporary files + Remove-Item $WingetOutputFile -ErrorAction SilentlyContinue + Remove-Item $WingetErrorFile -ErrorAction SilentlyContinue } - $ScriptResult.app_updates.apps_updated = $AppsUpdated - $ScriptResult.app_updates.apps_checked = $AppsUpdated.Count - if ($AppsUpdated.Count -gt 0) { Write-Log "Application updates completed. Updated $($AppsUpdated.Count) application(s): $($AppsUpdated -join ', ')" -Level "INFO" } else { Write-Log "Application updates completed. All applications are up to date." -Level "INFO" } } catch { - $ErrorMsg = "Winget upgrade failed: $($_.Exception.Message)" - $ScriptResult.app_updates.errors += $ErrorMsg - Write-Log $ErrorMsg -Level "ERROR" + # Check if it's a timeout + if ($_.Exception.Message -match "timeout|Timed out|process.*timed out") { + $ScriptResult.app_updates.timed_out = $true + $ScriptResult.app_updates.errors += "Winget command timed out after $WingetTimeout seconds" + Write-Log "Winget command timed out after $WingetTimeout seconds. Continuing with script." -Level "WARNING" + } else { + $ErrorMsg = "Winget upgrade failed: $($_.Exception.Message)" + $ScriptResult.app_updates.errors += $ErrorMsg + Write-Log $ErrorMsg -Level "ERROR" + } } } else { Write-Log "Winget not available. Skipping application updates." -Level "INFO" @@ -481,7 +516,9 @@ try { $ScriptResult.summary.total_warnings = ($LogContent | Where-Object { $_ -match '\[WARNING\]' }).Count # Determine overall status - if ($ScriptResult.summary.total_errors -gt 0) { + if ($ScriptResult.app_updates.timed_out) { + $ScriptResult.summary.overall_status = "completed_with_winget_timeout" + } elseif ($ScriptResult.summary.total_errors -gt 0) { $ScriptResult.summary.overall_status = "completed_with_errors" } elseif ($ScriptResult.summary.total_warnings -gt 0) { $ScriptResult.summary.overall_status = "completed_with_warnings" @@ -534,5 +571,8 @@ Write-Host "Duration: $($ScriptResult.summary.total_duration_seconds) seconds" - Write-Host "Status: $($ScriptResult.summary.overall_status)" -ForegroundColor Green Write-Host "Errors: $($ScriptResult.summary.total_errors)" -ForegroundColor $(if ($ScriptResult.summary.total_errors -gt 0) { "Red" } else { "Green" }) Write-Host "Warnings: $($ScriptResult.summary.total_warnings)" -ForegroundColor $(if ($ScriptResult.summary.total_warnings -gt 0) { "Yellow" } else { "Green" }) +if ($ScriptResult.app_updates.timed_out) { + Write-Host "Winget timed out after $WingetTimeout seconds" -ForegroundColor Yellow +} Write-Host "Log file: $LogFile" -ForegroundColor Cyan Write-Host "===========================================" -ForegroundColor Green \ No newline at end of file