Загрузка данных
$ErrorActionPreference = "SilentlyContinue"
$ScanRoot = "C:\"
$TimeStamp = Get-Date -Format "yyyyMMdd_HHmmss"
$Report = "C:\Disk_C_Audit_$TimeStamp.txt"
$IsAdmin = (
New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
if (-not $IsAdmin) {
Write-Host ""
Write-Host "ОШИБКА: PowerShell необходимо запустить от имени администратора." -ForegroundColor Red
Write-Host ""
return
}
function Convert-Size {
param(
[long]$Bytes
)
if ($Bytes -ge 1TB) {
return "{0:N2} TB" -f ($Bytes / 1TB)
}
elseif ($Bytes -ge 1GB) {
return "{0:N2} GB" -f ($Bytes / 1GB)
}
elseif ($Bytes -ge 1MB) {
return "{0:N2} MB" -f ($Bytes / 1MB)
}
elseif ($Bytes -ge 1KB) {
return "{0:N2} KB" -f ($Bytes / 1KB)
}
else {
return "$Bytes B"
}
}
function Add-Size {
param(
[hashtable]$Table,
[string]$Key,
[long]$Length
)
if ([string]::IsNullOrEmpty($Key)) {
return
}
if ($Table.ContainsKey($Key)) {
$Table[$Key] += $Length
}
else {
$Table[$Key] = $Length
}
}
function Add-ReportText {
param(
[string]$Text
)
$Text | Out-File `
-FilePath $Report `
-Encoding UTF8 `
-Append `
-Width 300
}
function Add-ReportObject {
param(
$Object
)
$Object |
Out-String -Width 300 |
Out-File `
-FilePath $Report `
-Encoding UTF8 `
-Append
}
$TopLevelSizes = @{}
$SecondLevelSizes = @{}
$WatchPathSizes = @{}
$ExtensionSizes = @{}
$LargeFiles = New-Object System.Collections.ArrayList
$WatchPaths = [ordered]@{
"C:\Windows\Temp" = "Windows TEMP"
"C:\Windows\SoftwareDistribution\Download" = "Кэш обновлений Windows"
"C:\Windows\Logs\CBS" = "Логи CBS"
"C:\Windows\Logs\DISM" = "Логи DISM"
"C:\Windows\Minidump" = "Минидампы Windows"
"C:\Windows\Installer" = "Windows Installer — вручную не удалять"
"C:\Windows\WinSxS" = "WinSxS — вручную не удалять"
"C:\inetpub\logs\LogFiles" = "Логи IIS"
"C:\ProgramData\Microsoft\Windows\WER" = "Отчёты об ошибках WER"
"C:\ProgramData\Package Cache" = "Package Cache — вручную не удалять"
"C:\`$Recycle.Bin" = "Корзина"
}
foreach ($Label in $WatchPaths.Values) {
$WatchPathSizes[$Label] = 0L
}
$WatchPathSizes["TEMP всех пользователей"] = 0L
$Drive = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
$OS = Get-WmiObject Win32_OperatingSystem
"" | Out-File -FilePath $Report -Encoding UTF8
Add-ReportText "============================================================"
Add-ReportText "ОТЧЁТ ПО ИСПОЛЬЗОВАНИЮ ДИСКА C:"
Add-ReportText "============================================================"
Add-ReportText ""
Add-ReportText ("Компьютер: {0}" -f $env:COMPUTERNAME)
Add-ReportText ("Операционная ОС: {0}" -f $OS.Caption)
Add-ReportText ("Версия ОС: {0}" -f $OS.Version)
Add-ReportText ("Дата проверки: {0}" -f (Get-Date))
Add-ReportText ""
Add-ReportText ("Размер диска C: {0}" -f (Convert-Size $Drive.Size))
Add-ReportText ("Занято: {0}" -f (Convert-Size ($Drive.Size - $Drive.FreeSpace)))
Add-ReportText ("Свободно: {0}" -f (Convert-Size $Drive.FreeSpace))
Add-ReportText ("Свободно, %: {0:N1}%" -f (($Drive.FreeSpace / $Drive.Size) * 100))
Add-ReportText ""
Write-Host ""
Write-Host "============================================================"
Write-Host "СКАНИРОВАНИЕ ДИСКА C:"
Write-Host "============================================================"
Write-Host ""
Write-Host "Проверка может занять 5–20 минут."
Write-Host "Никакие файлы не удаляются."
Write-Host ""
$Stack = New-Object System.Collections.Stack
$Stack.Push((Get-Item -LiteralPath $ScanRoot -Force))
$FileCount = 0L
$DirectoryCount = 0L
$ReadErrors = 0L
$TotalFoundSize = 0L
while ($Stack.Count -gt 0) {
$CurrentDirectory = $Stack.Pop()
$DirectoryCount++
if (($DirectoryCount % 1000) -eq 0) {
Write-Host (
"Папок: {0:N0}; файлов: {1:N0}; найдено: {2}" -f `
$DirectoryCount,
$FileCount,
(Convert-Size $TotalFoundSize)
)
}
try {
$Files = $CurrentDirectory.GetFiles()
}
catch {
$ReadErrors++
$Files = @()
}
foreach ($File in $Files) {
try {
$Length = [long]$File.Length
$FullName = $File.FullName
}
catch {
$ReadErrors++
continue
}
$FileCount++
$TotalFoundSize += $Length
$RelativePath = $FullName.Substring($ScanRoot.Length)
$Parts = $RelativePath.Split("\")
if ($Parts.Count -eq 1) {
$TopLevelName = "[Файлы в корне C:\]"
}
else {
$TopLevelName = $Parts[0]
}
Add-Size `
-Table $TopLevelSizes `
-Key $TopLevelName `
-Length $Length
if ($Parts.Count -ge 2) {
if ($TopLevelName -ne "[Файлы в корне C:\]") {
$SecondLevelName = $Parts[0] + "\" + $Parts[1]
Add-Size `
-Table $SecondLevelSizes `
-Key $SecondLevelName `
-Length $Length
}
}
foreach ($WatchPath in $WatchPaths.Keys) {
if (
$FullName.StartsWith(
$WatchPath + "\",
[System.StringComparison]::OrdinalIgnoreCase
) -or
$FullName.Equals(
$WatchPath,
[System.StringComparison]::OrdinalIgnoreCase
)
) {
$WatchPathSizes[$WatchPaths[$WatchPath]] += $Length
}
}
if (
$FullName -match "\\Users\\[^\\]+\\AppData\\Local\\Temp\\"
) {
$WatchPathSizes["TEMP всех пользователей"] += $Length
}
$Extension = $File.Extension
if ([string]::IsNullOrEmpty($Extension)) {
$Extension = "[без расширения]"
}
else {
$Extension = $Extension.ToLower()
}
Add-Size `
-Table $ExtensionSizes `
-Key $Extension `
-Length $Length
if ($Length -ge 50MB) {
[void]$LargeFiles.Add(
[pscustomobject]@{
Path = $FullName
SizeBytes = $Length
Size = Convert-Size $Length
LastWriteTime = $File.LastWriteTime
}
)
}
}
try {
$SubDirectories = $CurrentDirectory.GetDirectories()
}
catch {
$ReadErrors++
$SubDirectories = @()
}
foreach ($SubDirectory in $SubDirectories) {
try {
$IsReparsePoint = (
$SubDirectory.Attributes -band
[System.IO.FileAttributes]::ReparsePoint
)
if (-not $IsReparsePoint) {
$Stack.Push($SubDirectory)
}
}
catch {
$ReadErrors++
}
}
}
Write-Host ""
Write-Host "Сканирование завершено." -ForegroundColor Green
Write-Host ""
Add-ReportText "============================================================"
Add-ReportText "1. РАЗМЕР КАТАЛОГОВ В КОРНЕ C:"
Add-ReportText "============================================================"
Add-ReportText ""
$TopLevelReport = $TopLevelSizes.GetEnumerator() |
Sort-Object Value -Descending |
ForEach-Object {
[pscustomobject]@{
Folder = $_.Key
Size = Convert-Size $_.Value
SizeBytes = $_.Value
}
}
Add-ReportObject (
$TopLevelReport |
Select-Object Folder, Size
)
Add-ReportText "============================================================"
Add-ReportText "2. КРУПНЕЙШИЕ КАТАЛОГИ ВТОРОГО УРОВНЯ"
Add-ReportText "============================================================"
Add-ReportText ""
$SecondLevelReport = $SecondLevelSizes.GetEnumerator() |
Sort-Object Value -Descending |
Select-Object -First 50 |
ForEach-Object {
[pscustomobject]@{
Folder = "C:\" + $_.Key
Size = Convert-Size $_.Value
}
}
Add-ReportObject $SecondLevelReport
Add-ReportText "============================================================"
Add-ReportText "3. КРУПНЫЕ ФАЙЛЫ — ОТ 50 MB"
Add-ReportText "============================================================"
Add-ReportText ""
$LargeFilesReport = $LargeFiles |
Sort-Object SizeBytes -Descending |
Select-Object -First 80 `
Path,
Size,
LastWriteTime
Add-ReportObject $LargeFilesReport
Add-ReportText "============================================================"
Add-ReportText "4. СИСТЕМНЫЕ КАТАЛОГИ И ВОЗМОЖНЫЕ КАНДИДАТЫ НА ОЧИСТКУ"
Add-ReportText "============================================================"
Add-ReportText ""
$WatchPathReport = $WatchPathSizes.GetEnumerator() |
Sort-Object Value -Descending |
ForEach-Object {
[pscustomobject]@{
Location = $_.Key
Size = Convert-Size $_.Value
}
}
Add-ReportObject $WatchPathReport
Add-ReportText "============================================================"
Add-ReportText "5. КРУПНЕЙШИЕ ТИПЫ ФАЙЛОВ"
Add-ReportText "============================================================"
Add-ReportText ""
$ExtensionReport = $ExtensionSizes.GetEnumerator() |
Sort-Object Value -Descending |
Select-Object -First 30 |
ForEach-Object {
[pscustomobject]@{
Extension = $_.Key
Size = Convert-Size $_.Value
}
}
Add-ReportObject $ExtensionReport
Add-ReportText "============================================================"
Add-ReportText "6. PAGEFILE, MEMORY DUMP И СИСТЕМНЫЕ ФАЙЛЫ"
Add-ReportText "============================================================"
Add-ReportText ""
$SystemFiles = @(
"C:\pagefile.sys",
"C:\swapfile.sys",
"C:\hiberfil.sys",
"C:\Windows\MEMORY.DMP"
)
$SystemFileReport = foreach ($Path in $SystemFiles) {
if (Test-Path -LiteralPath $Path) {
$Item = Get-Item -LiteralPath $Path -Force
[pscustomobject]@{
Path = $Item.FullName
Size = Convert-Size $Item.Length
LastWriteTime = $Item.LastWriteTime
}
}
}
Add-ReportObject $SystemFileReport
Add-ReportText "Использование файлов подкачки:"
Add-ReportText ""
$PageFileUsage = Get-WmiObject Win32_PageFileUsage |
Select-Object `
Name,
AllocatedBaseSize,
CurrentUsage,
PeakUsage
Add-ReportObject $PageFileUsage
Add-ReportText "Настройки файлов подкачки:"
Add-ReportText ""
$PageFileSettings = Get-WmiObject Win32_PageFileSetting |
Select-Object `
Name,
InitialSize,
MaximumSize
Add-ReportObject $PageFileSettings
Add-ReportText "============================================================"
Add-ReportText "7. ТЕНЕВЫЕ КОПИИ VSS"
Add-ReportText "============================================================"
Add-ReportText ""
$VssOutput = & vssadmin.exe list shadowstorage 2>&1
Add-ReportText ($VssOutput | Out-String -Width 300)
Add-ReportText "============================================================"
Add-ReportText "8. СОСТОЯНИЕ ХРАНИЛИЩА КОМПОНЕНТОВ WINDOWS"
Add-ReportText "============================================================"
Add-ReportText ""
$DismOutput = & dism.exe /Online /Cleanup-Image /AnalyzeComponentStore 2>&1
Add-ReportText ($DismOutput | Out-String -Width 300)
Add-ReportText "============================================================"
Add-ReportText "9. ИТОГ СКАНИРОВАНИЯ"
Add-ReportText "============================================================"
Add-ReportText ""
Add-ReportText ("Обработано каталогов: {0:N0}" -f $DirectoryCount)
Add-ReportText ("Обработано файлов: {0:N0}" -f $FileCount)
Add-ReportText ("Размер файлов: {0}" -f (Convert-Size $TotalFoundSize))
Add-ReportText ("Ошибок чтения: {0:N0}" -f $ReadErrors)
Add-ReportText ""
Add-ReportText "ВАЖНО:"
Add-ReportText "Не удаляйте вручную содержимое Windows\Installer, WinSxS,"
Add-ReportText "System32, ProgramData и неизвестные файлы из Program Files."
Add-ReportText ""
Write-Host "============================================================"
Write-Host "ОТЧЁТ СОЗДАН"
Write-Host "============================================================"
Write-Host ""
Write-Host $Report -ForegroundColor Cyan
Write-Host ""
Write-Host "Размер отчёта:"
Write-Host ((Get-Item $Report).Length.ToString() + " байт")
Write-Host ""