Public/computer_space_cleanup_report.ps1
#region PARAMETER BLOCK param( [ValidateSet('report','cleanup','file','dism')] [string]$Mode = 'report', [string]$FilePath, [string]$CommandArgs ) #endregion #region OUTPUT VARIABLES $variableProps = @{ freeSpace = $null Folders = $null systemDiskInfo = $null fileDetails = $null space = $null timeTaken = $null } $outputProps = @{ out = [psobject]::new($variableProps) success = $false } $activityOutput = [psobject]::new($outputProps) #endregion #region FUNCTIONS function GetCleanupReport { $searchPath = @() $searchPath += [PSCustomObject]@{ text = 'Diagnostic Data Viewer database files' path = 'C:\ProgramData\Microsoft\Diagnosis\EventTranscript\' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'User Downloads folder' path = 'C:\Users\username\Downloads' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'Windows WinSxS' path = 'C:\Windows\WinSxS' fileList = "*" reportOnly = 'Yes' } $searchPath += [PSCustomObject]@{ text = 'IIS Log Files' path = 'C:\inetpub\logs\LogFiles\*' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'Windows Log Files' reportOnly = 'Yes' path = 'C:\Windows\Logs\*' fileList = "*" } $searchPath += [PSCustomObject]@{ text = 'Windows System32 Log Files' reportOnly = 'Yes' path = 'C:\Windows\System32\LogFiles\*' fileList = "*" } $searchPath += [PSCustomObject]@{ text = 'Recycle Bin' path = 'C:\$Recycle.bin\*' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'System error memory dump' path = 'C:\windows' fileList = "*.dmp" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'System error memory minidump' path = 'C:\windows\Minidump' fileList = "*.dmp" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'Windows Error Reporting Files' path = 'C:\ProgramData\Microsoft\Windows\WER' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'Windows Temp Files' path = 'C:\windows\Temp' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'User Temp Files' path = 'C:\Users\username\AppData\Local\Temp' fileList = "*" reportOnly = 'No' } $searchPath += [PSCustomObject]@{ text = 'User AppData' path = 'C:\Users\username\AppData\' fileList = "*" reportOnly = 'No' } $Output = @() foreach ($sPath in $searchPath ) { if ((Test-Path $sPath.path.Replace("*","")) -or ($sPath.path -like "C:\\Users\\username*")) { $Folders = @() if ($sPath.path.IndexOf("*") -gt 1) { $Folders += Get-ChildItem $sPath.path.replace("*","") -force| Where-Object {$_.PSisContainer} | ForEach-Object {$_.FullName} } elseif ($sPath.path -like "C:\\Users\\username*") { $Folders += Get-ChildItem C:\Users\ -force| Where-Object {$_.PSisContainer} | ForEach-Object {$sPath.path.Replace("C:\\Users\\username",$_.FullName)} } else { $Folders += $sPath.path } foreach ($folder in $folders) { if (Test-Path $folder) { Write-Host "Getting size of folder $Folder." $SizeGB = $null try { if ($sPath.fileList -eq "*") { $files = Get-ChildItem -Recurse -Force -Path $Folder -Filter $sPath.fileList -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Where {$false -eq $_.PSisContainer} } else { $files = Get-ChildItem -Force -Path $Folder -Filter $sPath.fileList -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Where {$false -eq $_.PSisContainer} } if ($files){ $sizeGB = [math]::round(($files| Measure-Object -Property length -sum).sum / 1gb, 3) } else { $sizeGB = 0 } } catch [System.UnauthorizedAccessException] { write-host "WARNING: Can't access $folder" } if ([string]::IsNullOrWhiteSpace($sizeGB)) { $sizeGB = "Access Error" } $text = $sPath.text if (($folders.count -gt 1) -or ($spath.text -eq "IIS Log Files")) { if ($folder -like "C:\users*") { $text = $text.replace("User", "User $($folder.split("\")[2])") } else { $text = $sPath.text + "\" + ($Folder | Split-Path -Leaf)} } if ($folder -like "*S-1-*") { try { $id = New-Object System.Security.Principal.SecurityIdentifier($Folder | Split-Path -Leaf) $text = $text.replace(($Folder | Split-Path -Leaf), $id.Translate([System.Security.Principal.NTAccount])) } catch {} } $Output += [PSCustomObject]@{ text = $text path = $Folder fileList = $sPath.fileList reportOnly = $sPath.reportOnly sizeGB = $sizeGB } $files = $null } else { Write-host "Could not find folder $Folder" } } } else { Write-host "WARNING: Could not find folder $($sPath.path)" } } $SystemDiskInfo = ([System.IO.DriveInfo]::GetDrives() ` | Where-Object {$_.Name -eq "C:\"}) | Select-Object -Property ` @{N='text';E={if([string]::IsNullOrEmpty(($_.VolumeLavel))){$_.Name}else{$_.VolumeLabel}}},` @{N='value';E={$_.Name}},` @{N='FreeSpace (Gb)'; E={($_.TotalFreeSpace/1GB).ToString('F2')}},` @{N='Total (Gb)'; E={($_.TotalSize/1GB).ToString('F2')}},` @{N='FreePercent'; E={[Math]::Round(($_.TotalFreeSpace / $_.TotalSize) * 100, 2)}} $activityOutput.out.folders = $output $activityOutput.out.freeSpace = ([System.IO.DriveInfo]::GetDrives() | Where-Object {$_.Name -eq "C:\"}).TotalFreeSpace $activityOutput.out.systemDiskInfo = $SystemDiskInfo; $activityOutput.success = $true; return $activityOutput; } function CleanupFolders { $returnFolders = @() foreach ($folder in ($folders | convertfrom-json)) { if ($Folder.reportOnly -eq "No") { Write-host "Deleting items in $($Folder.path)" $joinPath = Join-Path $($Folder.path) '*' Remove-Item -Recurse -Force -Path $joinPath -Filter $folder.fileList -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $sizeGB_post = [math]::round((Get-ChildItem -Recurse -Force -Path $folder.path -Filter $folder.fileList -ErrorAction SilentlyContinue | Measure-Object -Property length -sum).sum / 1gb, 3) $returnFolders += [PSCustomObject]@{ text = $folder.text Path = $folder.path sizeGB_prior = $folder.sizeGB sizeGB_post = $sizeGB_post sizeGB_diff = $folder.sizeGB - $sizeGB_post } } else { Write-Host "Folder is report only, not deleting. $($Folder.path)" } } $activityOutput.out.Folders = @($returnFolders) $activityOutput.success = $true; return $activityOutput; } function GetFileDetails { if (Test-Path $FilePath) { $File = get-item $FilePath $FileDetails = [PSCustomObject]@{ LinkType = $File.LinkType Length = $File.Length CreationTimeUtc = $File.CreationTimeUtc LastAccessTimeUtc = $File.LastAccessTimeUtc LastWriteTimeUtc = $File.LastWriteTimeUtc VersionInfo = $File.VersionInfo } $activityOutput.out.fileDetails = @($FileDetails) $activityOutput.success = $true; } else { Write-Host "WARNING: File $FilePath not found." $activityOutput.success = $false; } return $activityOutput; } function RunDISM { $Drive = "C:\" $Args = $CommandArgs Write-host "Args: $Args" $DISMPath = 'C:\Windows\System32\DISM.exe' $Space_prior = ([System.IO.DriveInfo]::GetDrives() | Where-Object {$_.Name -eq $drive}).TotalFreeSpace $StartTime = get-date $processSettings = New-Object System.Diagnostics.ProcessStartInfo $processSettings.FileName = $DISMPath $processSettings.RedirectStandardError = $true $processSettings.RedirectStandardOutput = $true $processSettings.UseShellExecute = $false $processSettings.Arguments = $Args $DISMprocess = New-Object System.Diagnostics.Process $DISMprocess.StartInfo = $processSettings $DISMprocess.Start() | Out-Null $stdout = $DISMprocess.StandardOutput.ReadToEnd() $stderr = $DISMprocess.StandardError.ReadToEnd() $DISMprocess.WaitForExit() Write-Host "Standard Output:" write-host "$stdout" if (![string]::IsNullOrWhiteSpace($stderr)) { Write-Host "WARNING Error:" Write-Host "$stderr " } if ($DISMprocess.ExitCode -ne 0) { $activityOutput.success = $false; } else { $activityOutput.success = $true; } $Space_post = ([System.IO.DriveInfo]::GetDrives() | Where-Object {$_.Name -eq $drive}).TotalFreeSpace $Space = [PSCustomObject]@{ prior = $Space_prior post = $Space_post change = [math]::round(($Space_prior - $Space_post) / 1GB,2) } $TimeTaken = New-TimeSpan -Start $StartTime -End (Get-Date) $activityOutput.out.space = $space $activityOutput.out.timeTaken = [string]::Format("{0} minutes {1} seconds",$TimeTaken.Minutes,$TimeTaken.Seconds) return $activityOutput; } function ExecuteActivity { try { switch ($Mode) { 'report' { return GetCleanupReport } 'cleanup' { return CleanupFolders } 'file' { return GetFileDetails } 'dism' { return RunDISM } default { throw "Unknown mode: $Mode" } } } catch { Write-Host "Error in ExecuteActivity: $($_.Exception.Message)" $activityOutput.success = $false return $activityOutput } } #endregion function ComputerSpaceCleanupReport { if ($MyInvocation.InvocationName -eq $MyInvocation.MyCommand.Name) { Write-Host "Computer Space Cleanup Report" Write-Host "=============================" $result = ExecuteActivity if ($result.success) { Write-Host "`nOperation completed successfully!" Write-Host "Data available in: `$result.out" } else { Write-Host "`nOperation completed with errors." } return $result } } |