diff --git a/optimization.ps1 b/optimization.ps1 index ee49d24..e990994 100644 --- a/optimization.ps1 +++ b/optimization.ps1 @@ -1,269 +1,73 @@ -$ScriptResult = @{ - success = $true - system_optimization = @{ - "chkdsk" = @{ - "run" = $false - "success" = $false - "exit_code" = $null - "message" = "" - "reboot_required" = $false - "diskSpace" = "" - "errors" = @() - } - "sfc" = @{ - "run" = $false - "success" = $false - "exit_code" = $null - "message" = "" - "files_repaired" = 0 - "errors" = @() - } - "dism" = @{ - "run" = $false - "success" = $false - "exit_code" = $null - "message" = "" - "component_repaired" = $false - "errors" = @() - } - } -} - -# Temp files for output capture -$tempPath = $env:TEMP -$chkdskStdout = "$tempPath\chkdsk_stdout.txt" -$chkdskStderr = "$tempPath\chkdsk_stderr.txt" -$sfcStdout = "$tempPath\sfc_stdout.txt" -$sfcStderr = "$tempPath\sfc_stderr.txt" -$dismStdout = "$tempPath\dism_stdout.txt" -$dismStderr = "$tempPath\dism_stderr.txt" - -# Run CHKDSK -Write-Host "Running CHKDSK with /R option..." -Write-Host "Note: If volume is in use, CHKDSK will be scheduled for next reboot." - -try { - # Use cmd /c with echo Y piped, redirect output - $process = Start-Process -FilePath "cmd" -ArgumentList "/c", "echo Y | chkdsk C: /R" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $chkdskStdout -RedirectStandardError $chkdskStderr -ErrorAction Stop - $ChkdskExitCode = $process.ExitCode +# Function to run process with true live streaming output +function Start-ProcessWithLiveStreaming { + param( + [string]$FilePath, + [string]$Arguments, + [string]$Name + ) - # Read output - $outputText = "" - if (Test-Path $chkdskStdout) { - $outputText = Get-Content -Path $chkdskStdout -Raw -ErrorAction SilentlyContinue - } - if (Test-Path $chkdskStderr) { - $stderrText = Get-Content -Path $chkdskStderr -Raw -ErrorAction SilentlyContinue - if ($stderrText) { - $outputText += $stderrText - } - } + $tempPath = $env:TEMP + $stdoutFile = "$tempPath\${Name}_stdout.txt" + $stderrFile = "$tempPath\${Name}_stderr.txt" - $ScriptResult.system_optimization.chkdsk.run = $true - $ScriptResult.system_optimization.chkdsk.exit_code = $ChkdskExitCode + # Clean up old files + if (Test-Path $stdoutFile) { Remove-Item $stdoutFile -ErrorAction SilentlyContinue } + if (Test-Path $stderrFile) { Remove-Item $stderrFile -ErrorAction SilentlyContinue } - # Parse output - if ($outputText -match "will be checked on next boot|Chkdsk cannot run because the volume is in use") { - $ScriptResult.system_optimization.chkdsk.reboot_required = $true - } + # Create file handles for immediate reading + $fileStream = [System.IO.File]::Create($stdoutFile) - # Parse disk space freed (if available in output) - if ($outputText -match "(\d+) bytes in (\d+) data streams recovered") { - $bytesRecovered = [int64]$matches[1] - $ScriptResult.system_optimization.chkdsk.diskSpace = "{0:N2} MB" -f ($bytesRecovered / 1MB) - } + Write-Host "Starting $Name..." - # Parse exit codes - switch ($ChkdskExitCode) { - 0 { - $ScriptResult.system_optimization.chkdsk.success = $true - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed successfully. No errors found." - } - 1 { - $ScriptResult.system_optimization.chkdsk.success = $true - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed successfully. Errors corrected." - } - 2 { - $ScriptResult.system_optimization.chkdsk.success = $false - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK did not run due to a parameter error." - } - 3 { - $ScriptResult.system_optimization.chkdsk.success = $true - $ScriptResult.system_optimization.chkdsk.reboot_required = $true - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed with errors and requires a reboot to complete." - } - 4 { - $ScriptResult.system_optimization.chkdsk.success = $false - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK encountered errors but could not fix them." - } - 5 { - $ScriptResult.system_optimization.chkdsk.success = $false - $ScriptResult.system_optimization.chkdsk.reboot_required = $true - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK found errors but requires a reboot to fix them." - } - default { - $ScriptResult.system_optimization.chkdsk.success = $false - $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed with exit code: $ChkdskExitCode" - } - } + # Start the process + $process = Start-Process -FilePath $FilePath -ArgumentList $Arguments -NoNewWindow -PassThru -RedirectStandardOutput $stdoutFile -RedirectStandardError $stderrFile -ErrorAction Stop - Write-Host $outputText - Write-Host "CHKDSK exit code: $ChkdskExitCode" - Write-Host "CHKDSK message: $($ScriptResult.system_optimization.chkdsk.message)" - -} catch { - $ErrorMsg = "Failed to run CHKDSK: $($_.Exception.Message)" - $ScriptResult.system_optimization.chkdsk.errors += $ErrorMsg - Write-Host $ErrorMsg -} - -# Run SFC -Write-Host "Running System File Checker (SFC /scannow)..." - -try { - $process = Start-Process -FilePath "sfc" -ArgumentList "/scannow" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $sfcStdout -RedirectStandardError $sfcStderr -ErrorAction Stop - $ExitCode = $process.ExitCode - - # Read output - $outputText = "" - if (Test-Path $sfcStdout) { - $outputText = Get-Content -Path $sfcStdout -Raw -ErrorAction SilentlyContinue - } - if (Test-Path $sfcStderr) { - $stderrText = Get-Content -Path $sfcStderr -Raw -ErrorAction SilentlyContinue - if ($stderrText) { - $outputText += $stderrText - } - } - - $ScriptResult.system_optimization.sfc.run = $true - $ScriptResult.system_optimization.sfc.exit_code = $ExitCode - - # Parse files repaired from output - if ($outputText -match "Windows Resource Protection found integrity violations|found corrupt files and repaired them") { - if ($outputText -match "repairing corrupted files") { - $ScriptResult.system_optimization.sfc.files_repaired = 1 - } - } - - # Parse exit codes - switch ($ExitCode) { - 0 { - $ScriptResult.system_optimization.sfc.success = $true - $ScriptResult.system_optimization.sfc.message = "SFC completed successfully. No integrity violations found." - $ScriptResult.system_optimization.sfc.files_repaired = 0 - } - 1 { - $ScriptResult.system_optimization.sfc.success = $true - $ScriptResult.system_optimization.sfc.message = "SFC completed successfully. Corrupted files were repaired." - $ScriptResult.system_optimization.sfc.files_repaired = 1 - } - 2 { - $ScriptResult.system_optimization.sfc.success = $false - $ScriptResult.system_optimization.sfc.message = "SFC could not perform the operation. User cancelled or Windows is in safe mode." - } - 3 { - $ScriptResult.system_optimization.sfc.success = $false - $ScriptResult.system_optimization.sfc.message = "SFC could not fix some files. See CBS.log for details." - $ScriptResult.system_optimization.sfc.files_repaired = -1 - } - -1 { - $ScriptResult.system_optimization.sfc.success = $false - $ScriptResult.system_optimization.sfc.message = "SFC encountered an error. Check CBS.log for details." - } - default { - $ScriptResult.system_optimization.sfc.success = $false - $ScriptResult.system_optimization.sfc.message = "SFC completed with unexpected exit code: $ExitCode" - } - } - - Write-Host $outputText - Write-Host "SFC exit code: $ExitCode" - Write-Host "SFC message: $($ScriptResult.system_optimization.sfc.message)" - -} catch { - $ErrorMsg = "Failed to run SFC: $($_.Exception.Message)" - $ScriptResult.system_optimization.sfc.errors += $ErrorMsg - Write-Host $ErrorMsg -} - -# Run DISM -Write-Host "Running DISM /Online /Cleanup-Image /RestoreHealth..." - -try { - $process = Start-Process -FilePath "DISM" -ArgumentList "/Online /Cleanup-Image /RestoreHealth" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $dismStdout -RedirectStandardError $dismStderr -ErrorAction Stop - $ExitCode = $process.ExitCode - - # Read output - $outputText = "" - if (Test-Path $dismStdout) { - $outputText = Get-Content -Path $dismStdout -Raw -ErrorAction SilentlyContinue - } - if (Test-Path $dismStderr) { - $stderrText = Get-Content -Path $dismStderr -Raw -ErrorAction SilentlyContinue - if ($stderrText) { - $outputText += $stderrText - } - } - - $ScriptResult.system_optimization.dism.run = $true - $ScriptResult.system_optimization.dism.exit_code = $ExitCode - - # Parse exit codes - switch ($ExitCode) { - 0 { - $ScriptResult.system_optimization.dism.success = $true - $ScriptResult.system_optimization.dism.component_repaired = $true - $ScriptResult.system_optimization.dism.message = "DISM completed successfully. The component store was repaired." - } - 87 { - $ScriptResult.system_optimization.dism.success = $false - $ScriptResult.system_optimization.dism.message = "DISM failed. A parameter was invalid. Check the command syntax." - } - 3010 { - $ScriptResult.system_optimization.dism.success = $true - $ScriptResult.system_optimization.dism.component_repaired = $true - $ScriptResult.system_optimization.dism.message = "DISM completed successfully. A reboot is required." - } - 1726 { - $ScriptResult.system_optimization.dism.success = $false - $ScriptResult.system_optimization.dism.message = "DISM failed. The remote procedure call failed." - } - 1910 { - $ScriptResult.system_optimization.dism.success = $false - $ScriptResult.system_optimization.dism.message = "DISM failed. The specified image file could not be found." - } - default { - if ($ExitCode -ge 0 -and $ExitCode -le 100) { - $ScriptResult.system_optimization.dism.success = $true - $ScriptResult.system_optimization.dism.message = "DISM completed with exit code: $ExitCode" - } else { - $ScriptResult.system_optimization.dism.success = $false - $ScriptResult.system_optimization.dism.message = "DISM completed with unexpected exit code: $ExitCode" + # Read output while process runs + $lastPosition = 0 + while (-not $process.HasExited) { + Start-Sleep -Milliseconds 500 + + if (Test-Path $stdoutFile) { + $currentLength = (Get-Item $stdoutFile).Length + if ($currentLength -gt $lastPosition) { + $bytesToRead = $currentLength - $lastPosition + $stream = [System.IO.File]::OpenRead($stdoutFile) + $stream.Seek($lastPosition, [System.IO.SeekOrigin]::Begin) | Out-Null + $buffer = New-Object byte[] $bytesToRead + $stream.Read($buffer, 0, $bytesToRead) | Out-Null + $stream.Close() + $text = [System.Text.Encoding]::UTF8.GetString($buffer) + Write-Host $text -NoNewline + $lastPosition = $currentLength } } } - Write-Host $outputText - Write-Host "DISM exit code: $ExitCode" - Write-Host "DISM message: $($ScriptResult.system_optimization.dism.message)" + # Wait for process to complete + $process.WaitForExit() -} catch { - $ErrorMsg = "Failed to run DISM: $($_.Exception.Message)" - $ScriptResult.system_optimization.dism.errors += $ErrorMsg - Write-Host $ErrorMsg -} - -# Cleanup temp files -Write-Host "Cleaning up temporary files..." -$tempFiles = @($chkdskStdout, $chkdskStderr, $sfcStdout, $sfcStderr, $dismStdout, $dismStderr) -foreach ($file in $tempFiles) { - if (Test-Path $file) { - Remove-Item $file -ErrorAction SilentlyContinue + # Read any remaining output + if (Test-Path $stdoutFile) { + $content = Get-Content -Path $stdoutFile -Raw -ErrorAction SilentlyContinue + if ($content) { Write-Host $content } } -} - -# Output JSON result -Write-Host "System optimization section completed." -$result = $ScriptResult | ConvertTo-Json -Compress -Depth 10 -Write-Output $result \ No newline at end of file + if (Test-Path $stderrFile) { + $content = Get-Content -Path $stderrFile -Raw -ErrorAction SilentlyContinue + if ($content) { Write-Host $content } + } + + # Get output for return + $outputText = "" + if (Test-Path $stdoutFile) { $outputText = Get-Content -Path $stdoutFile -Raw -ErrorAction SilentlyContinue } + if (Test-Path $stderrFile) { $outputText += Get-Content -Path $stderrFile -Raw -ErrorAction SilentlyContinue } + + # Cleanup + Remove-Item $stdoutFile -ErrorAction SilentlyContinue + Remove-Item $stderrFile -ErrorAction SilentlyContinue + $fileStream.Close() + + return @{ + ExitCode = $process.ExitCode + Output = $outputText + } +} \ No newline at end of file