scripts/optimization.ps1
2026-02-21 15:41:48 +01:00

221 lines
No EOL
10 KiB
PowerShell

$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" = @()
}
}
}
$tempPath = $env:TEMP
# Function to run process in new window with live output
function Start-ProcessWithNewWindow {
param(
[string]$FilePath,
[string]$Arguments,
[string]$Name
)
$stdoutFile = "$tempPath\${Name}_stdout.txt"
$stderrFile = "$tempPath\${Name}_stderr.txt"
# Clean up old files
if (Test-Path $stdoutFile) { Remove-Item $stdoutFile -Force -ErrorAction SilentlyContinue }
if (Test-Path $stderrFile) { Remove-Item $stderrFile -Force -ErrorAction SilentlyContinue }
Write-Host "Starting $Name in new window..."
# Start process in new window (removed -NoNewWindow)
$process = Start-Process -FilePath $FilePath -ArgumentList $Arguments -PassThru -RedirectStandardOutput $stdoutFile -RedirectStandardError $stderrFile -ErrorAction Stop
# Poll output files while process runs
$lastStdoutPos = 0
$lastStderrPos = 0
while (-not $process.HasExited) {
Start-Sleep -Milliseconds 300
# Read new stdout content
if (Test-Path $stdoutFile) {
$stdoutSize = (Get-Item $stdoutFile).Length
if ($stdoutSize -gt $lastStdoutPos) {
$stream = [System.IO.File]::OpenRead($stdoutFile)
$stream.Seek($lastStdoutPos, [System.IO.SeekOrigin]::Begin) | Out-Null
$bytesToRead = $stdoutSize - $lastStdoutPos
$buffer = New-Object byte[] $bytesToRead
$stream.Read($buffer, 0, $bytesToRead) | Out-Null
$stream.Close()
$text = [System.Text.Encoding]::UTF8.GetString($buffer)
if ($text) { Write-Host $text -NoNewline }
$lastStdoutPos = $stdoutSize
}
}
# Read new stderr content
if (Test-Path $stderrFile) {
$stderrSize = (Get-Item $stderrFile).Length
if ($stderrSize -gt $lastStderrPos) {
$stream = [System.IO.File]::OpenRead($stderrFile)
$stream.Seek($lastStderrPos, [System.IO.SeekOrigin]::Begin) | Out-Null
$bytesToRead = $stderrSize - $lastStderrPos
$buffer = New-Object byte[] $bytesToRead
$stream.Read($buffer, 0, $bytesToRead) | Out-Null
$stream.Close()
$text = [System.Text.Encoding]::UTF8.GetString($buffer)
if ($text) { Write-Host $text -NoNewline }
$lastStderrPos = $stderrSize
}
}
}
# Wait a moment for any final output
Start-Sleep -Milliseconds 500
# Read final output
$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 -Force -ErrorAction SilentlyContinue
Remove-Item $stderrFile -Force -ErrorAction SilentlyContinue
return @{
ExitCode = $process.ExitCode
Output = $outputText
}
}
# Run CHKDSK
Write-Host "=========================================="
Write-Host "Running CHKDSK with /R option..."
Write-Host "Note: A new window will open for CHKDSK"
Write-Host "=========================================="
try {
$result = Start-ProcessWithNewWindow -FilePath "cmd" -Arguments "/c echo Y | chkdsk C: /R" -Name "chkdsk"
$ChkdskExitCode = $result.ExitCode
$outputText = $result.Output
$ScriptResult.system_optimization.chkdsk.run = $true
$ScriptResult.system_optimization.chkdsk.exit_code = $ChkdskExitCode
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
}
switch ($ChkdskExitCode) {
0 { $ScriptResult.system_optimization.chkdsk.success = $true; $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed successfully." }
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." }
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." }
default { $ScriptResult.system_optimization.chkdsk.success = $false; $ScriptResult.system_optimization.chkdsk.message = "CHKDSK completed with exit code: $ChkdskExitCode" }
}
Write-Host "CHKDSK exit code: $ChkdskExitCode"
} catch {
$ErrorMsg = "Failed to run CHKDSK: $($_.Exception.Message)"
$ScriptResult.system_optimization.chkdsk.errors += $ErrorMsg
Write-Host $ErrorMsg
}
# Run SFC
Write-Host "=========================================="
Write-Host "Running System File Checker (SFC /scannow)..."
Write-Host "Note: A new window will open for SFC"
Write-Host "=========================================="
try {
$result = Start-ProcessWithNewWindow -FilePath "sfc" -Arguments "/scannow" -Name "sfc"
$ExitCode = $result.ExitCode
$outputText = $result.Output
$ScriptResult.system_optimization.sfc.run = $true
$ScriptResult.system_optimization.sfc.exit_code = $ExitCode
switch ($ExitCode) {
0 { $ScriptResult.system_optimization.sfc.success = $true; $ScriptResult.system_optimization.sfc.message = "SFC completed successfully."; $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." }
3 { $ScriptResult.system_optimization.sfc.success = $false; $ScriptResult.system_optimization.sfc.message = "SFC could not fix some files."; $ScriptResult.system_optimization.sfc.files_repaired = -1 }
-1 { $ScriptResult.system_optimization.sfc.success = $false; $ScriptResult.system_optimization.sfc.message = "SFC encountered an error." }
default { $ScriptResult.system_optimization.sfc.success = $false; $ScriptResult.system_optimization.sfc.message = "SFC completed with exit code: $ExitCode" }
}
Write-Host "SFC exit code: $ExitCode"
} catch {
$ErrorMsg = "Failed to run SFC: $($_.Exception.Message)"
$ScriptResult.system_optimization.sfc.errors += $ErrorMsg
Write-Host $ErrorMsg
}
# Run DISM
Write-Host "=========================================="
Write-Host "Running DISM /Online /Cleanup-Image /RestoreHealth..."
Write-Host "Note: A new window will open for DISM"
Write-Host "=========================================="
try {
$result = Start-ProcessWithNewWindow -FilePath "DISM" -Arguments "/Online /Cleanup-Image /RestoreHealth" -Name "dism"
$ExitCode = $result.ExitCode
$outputText = $result.Output
$ScriptResult.system_optimization.dism.run = $true
$ScriptResult.system_optimization.dism.exit_code = $ExitCode
switch ($ExitCode) {
0 { $ScriptResult.system_optimization.dism.success = $true; $ScriptResult.system_optimization.dism.component_repaired = $true; $ScriptResult.system_optimization.dism.message = "DISM completed successfully." }
87 { $ScriptResult.system_optimization.dism.success = $false; $ScriptResult.system_optimization.dism.message = "DISM failed. A parameter was invalid." }
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." }
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 exit code: $ExitCode"
}
}
}
Write-Host "DISM exit code: $ExitCode"
} catch {
$ErrorMsg = "Failed to run DISM: $($_.Exception.Message)"
$ScriptResult.system_optimization.dism.errors += $ErrorMsg
Write-Host $ErrorMsg
}
# Output JSON result
Write-Host "=========================================="
Write-Host "System optimization section completed."
Write-Host "=========================================="
$result = $ScriptResult | ConvertTo-Json -Compress -Depth 10
Write-Output $result