Windows 작업 스케줄러 + PowerShell로 주간 유지보수 자동화
주간 유지보수를 자동화하면 매주 몇 분으로 안정성과 속도를 확보할 수 있습니다. 아래 스크립트는 TEMP/휴지통 정리, 폴더 백업(robocopy), 앱 목록 백업(winget/레지스트리), 로그 기록을 한 번에 처리합니다.
참고: 에디터 환경에 따라 코드 블록 복사가 제한될 수 있어, 복사 버튼은 **숨김 원본 텍스트**에서 직접 복사합니다.

1) PowerShell 스크립트
C:\Scripts\weekly_maintenance.ps1로 저장하세요. 필요 시 경로·옵션을 수정합니다.
# weekly_maintenance.ps1
$ErrorActionPreference = 'SilentlyContinue'
$Host.UI.RawUI.WindowTitle = "Weekly Maintenance"
# === 사용자 설정 =================================================
$LogDir = Join-Path $HOME "MaintenanceLogs"
$BackupJobs = @(
@{ Source = Join-Path $HOME "Documents"; Dest = "D:\Backups\Documents" },
@{ Source = Join-Path $HOME "Pictures"; Dest = "D:\Backups\Pictures" }
)
$IncludeSystemTemp = $false
$CreateRestorePoint = $false
$ResetThumbCache = $false
# === 준비 =======================================================
if (-not (Test-Path $LogDir)) { New-Item -Path $LogDir -ItemType Directory | Out-Null }
$TimeStamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$LogPath = Join-Path $LogDir "weekly_$TimeStamp.log"
$TransPath = Join-Path $LogDir "trans_$TimeStamp.txt"
Function Write-Log($msg){ $line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') $msg"; $line | Tee-Object -FilePath $LogPath -Append }
Function Get-FreeBytes($drive='C'){ try { (Get-PSDrive -Name $drive).Free } catch { 0 } }
Start-Transcript -Path $TransPath -Append -ErrorAction SilentlyContinue | Out-Null
Function Clear-Temp{
Write-Log "[Temp] 사용자 TEMP 정리 시작"
$userTemp = $env:TEMP
if (Test-Path $userTemp){
Get-ChildItem -Path $userTemp -Force -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
Write-Log "[Temp] 사용자 TEMP 정리 완료: $userTemp"
} else { Write-Log "[Temp] 사용자 TEMP 폴더 없음: $userTemp" }
if ($IncludeSystemTemp){
$sysTemp = "C:\Windows\Temp"
Write-Log "[Temp] 시스템 TEMP 정리 시도: $sysTemp"
if (Test-Path $sysTemp){
Get-ChildItem -Path $sysTemp -Force -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
Write-Log "[Temp] 시스템 TEMP 정리 완료"
} else { Write-Log "[Temp] 시스템 TEMP 폴더 없음: $sysTemp" }
}
}
Function Clear-Bin{
try{
Write-Log "[Bin] 휴지통 비우기"
Clear-RecycleBin -Force -Confirm:$false -ErrorAction SilentlyContinue | Out-Null
} catch { Write-Log "[Bin] 오류: $($_.Exception.Message)" }
}
Function Run-Backups{
foreach ($job in $BackupJobs){
$src=$job.Source; $dst=$job.Dest
if (-not (Test-Path $src)){ Write-Log "[Backup] 원본 없음: $src"; continue }
if (-not (Test-Path $dst)){ New-Item -Path $dst -ItemType Directory -Force | Out-Null }
Write-Log "[Backup] 시작: `"$src`" → `"$dst`" (MIR)"
robocopy $src $dst /MIR /R:2 /W:2 /FFT /XJ /XD ".cache" "node_modules" "temp" "tmp" /NFL /NDL /NP /LOG+:$LogPath | Out-Null
Write-Log "[Backup] 완료"
}
}
Function Backup-Apps{
$appsJson = Join-Path $LogDir "apps_$TimeStamp.json"
if (Get-Command winget -ErrorAction SilentlyContinue){
Write-Log "[Apps] winget export"
winget export -o $appsJson --accept-source-agreements --accept-package-agreements | Out-Null
} else {
Write-Log "[Apps] 레지스트리로 대체 수집"
$keys = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
$apps = foreach ($k in $keys){
Get-ItemProperty $k -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName } |
Select-Object DisplayName, DisplayVersion, Publisher
}
$apps | Sort-Object DisplayName | ConvertTo-Json -Depth 3 | Set-Content -Path $appsJson -Encoding UTF8
}
Write-Log "[Apps] 저장: $appsJson"
}
Function Make-RestorePoint{
if ($CreateRestorePoint){
try{
Write-Log "[RP] 복원 지점 생성"
Checkpoint-Computer -Description "WeeklyMaintenance $(Get-Date -Format 'yyyy-MM-dd')" -RestorePointType "MODIFY_SETTINGS"
} catch { Write-Log "[RP] 실패: $($_.Exception.Message)" }
}
}
Function Reset-ThumbCache{
if ($ResetThumbCache){
try{
Write-Log "[Thumb] 캐시 초기화"
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
$thumbPath = Join-Path $env:LOCALAPPDATA "Microsoft\Windows\Explorer"
Get-ChildItem $thumbPath -Filter "thumbcache*.db" -Force -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
Start-Process "explorer.exe"
} catch { Write-Log "[Thumb] 실패: $($_.Exception.Message)" }
}
}
$before = Get-FreeBytes "C"
Write-Log "=== Weekly Maintenance 시작 ==="
Clear-Temp
Clear-Bin
Run-Backups
Backup-Apps
Make-RestorePoint
Reset-ThumbCache
$after = Get-FreeBytes "C"
$freed = [math]::Round(($after - $before)/1GB, 2)
Write-Log ("[Summary] C: 여유 공간 변화: {0} GB" -f $freed)
Write-Log "=== Weekly Maintenance 끝 ==="
Stop-Transcript | Out-Null
실행 테스트
아래 두 줄로 동작과 로그를 확인합니다.
powershell -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\weekly_maintenance.ps1"
Get-Content "$HOME\MaintenanceLogs\weekly_*.log" -Tail 50
복사 버튼으로 스크립트를 복사한 뒤 파일로 저장하려면 PowerShell에서 다음 한 줄을 실행하세요.
Set-Content -Path "$env:USERPROFILE\Downloads\weekly_maintenance.ps1" -Value (Get-Clipboard) -Encoding UTF8
2) 작업 스케줄러 등록(주간 자동 실행)
한 줄 명령
schtasks /Create /TN "WeeklyMaintenance" /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"C:\Scripts\weekly_maintenance.ps1\"" /SC WEEKLY /D SUN /ST 03:00 /RL HIGHEST /F
- /D SUN: 매주 일요일, /ST 03:00: 03:00 KST(로컬 기준)
- /RL HIGHEST: 높은 권한 실행(옵션). 노트북은 “AC 전원에서만 실행” 권장