Created
August 15, 2018 13:27
-
-
Save SMSAgentSoftware/c0b0a03d6cac2d350be2483a9dfcd635 to your computer and use it in GitHub Desktop.
Creates csv and html disk usage reports using WizTree portable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Script to export html and csv reports of file and directory content on the system drive | |
# Use to identify large files/directories for disk space cleanup | |
# Uses WizTree portable to quickly retrieve file and directory sizes from the Master File Table on disk | |
# Download and extract the WizTree64.exe and place in the same directory as this script | |
# Set the running location | |
$RunLocation = $PSScriptRoot | |
#$RunLocation = "C:\temp" | |
$TempLocation = "C:\temp" | |
# Set Target share to copy the reports to | |
$TargetRoot = "\\server-01\sharename\DirectorySizeInfo" | |
# Free disk space thresholds (percentages) for summary report | |
$script:Thresholds = @{} | |
$Thresholds.Warning = 80 | |
$Thresholds.Critical = 90 | |
# Custom function to exit with a specific code | |
function ExitWithCode | |
{ | |
param | |
( | |
$exitcode | |
) | |
$host.SetShouldExit($exitcode) | |
exit | |
} | |
# Function to set the progress bar colour based on the the threshold value in the summary report | |
function Set-PercentageColour { | |
param( | |
[int]$Value | |
) | |
If ($Value -lt $Thresholds.Warning) | |
{ | |
$Hex = "#00ff00" # Green | |
} | |
If ($Value -ge $Thresholds.Warning -and $Value -lt $Thresholds.Critical) | |
{ | |
$Hex = "#ff9900" # Amber | |
} | |
If ($Value -ge $Thresholds.Critical) | |
{ | |
$Hex = "#FF0000" # Red | |
} | |
Return $Hex | |
} | |
# Define Html CSS style | |
$Style = @" | |
<style> | |
table { | |
border-collapse: collapse; | |
} | |
td, th { | |
border: 1px solid #ddd; | |
padding: 8px; | |
} | |
th { | |
padding-top: 12px; | |
padding-bottom: 12px; | |
text-align: left; | |
background-color: #4286f4; | |
color: white; | |
} | |
</style> | |
"@ | |
# Set the filenames of WizTree csv's | |
$FilesCSV = "Files_$(Get-Date -Format 'yyyyMMdd_hhmmss').csv" | |
$FoldersCSV = "Folders_$(Get-Date -Format 'yyyyMMdd_hhmmss').csv" | |
# Set the filenames of customised csv's | |
$ExportedFilesCSV = "Exported_Files_$(Get-Date -Format 'yyyyMMdd_hhmmss').csv" | |
$ExportedFoldersCSV = "Exported_Folders_$(Get-Date -Format 'yyyyMMdd_hhmmss').csv" | |
# Set the filenames of html reports | |
$ExportedFilesHTML = "Largest_Files_$(Get-Date -Format 'yyyyMMdd_hhmmss').html" | |
$ExportedFoldersHTML = "Largest_Folders_$(Get-Date -Format 'yyyyMMdd_hhmmss').html" | |
$SummaryHTMLReport = "Disk_Usage_Summary_$(Get-Date -Format 'yyyyMMdd_hhmmss').html" | |
# Run the WizTree portable app | |
Start-Process -FilePath "$RunLocation\WizTree64.exe" -ArgumentList """$Env:SystemDrive"" /export=""$TempLocation\$FilesCSV"" /admin 1 /sortby=2 /exportfolders=0" -Verb runas -Wait | |
Start-Process -FilePath "$RunLocation\WizTree64.exe" -ArgumentList """$Env:SystemDrive"" /export=""$TempLocation\$FoldersCSV"" /admin 1 /sortby=2 /exportfiles=0" -Verb runas -Wait | |
#region Files | |
# Remove the first 2 rows from the CSVs to leave just the relevant data | |
$CSVContent = Get-Content -Path $TempLocation\$FilesCSV -ReadCount 0 | |
$CSVContent = $CSVContent | Select -Skip 1 | |
$CSVContent = $CSVContent | Select -Skip 1 | |
# Create a table to store the results | |
$Table = [System.Data.DataTable]::new("Directory Structure") | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Name",[System.String])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (Bytes)",[System.Int64])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (KB)",[System.Decimal])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (MB)",[System.Decimal])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (GB)",[System.Decimal])) | |
# Populate the table from the CSV data | |
Foreach ($csvrow in $CSVContent) | |
{ | |
$Content = $csvrow.split(',') | |
[void]$Table.rows.Add(($Content[0].Replace('"','')),$Content[2],([math]::Round(($Content[2] / 1KB),2)),([math]::Round(($Content[2] / 1MB),2)),([math]::Round(($Content[2] / 1GB),2))) | |
} | |
# Export the table to a new CSV | |
$Table | Sort 'Size (Bytes)' -Descending | Export-CSV -Path $TempLocation\$ExportedFilesCSV -NoTypeInformation -UseCulture | |
# Export the largest 100 results into html format | |
$Table | | |
Sort 'Size (Bytes)' -Descending | | |
Select -First 100 | | |
ConvertTo-Html -Property 'Name','Size (Bytes)','Size (KB)','Size (MB)','Size (GB)' -Head $style -Body "<h2>100 largest files on $env:COMPUTERNAME</h2>" -CssUri "http://www.w3schools.com/lib/w3.css" | | |
Out-String | Out-File $TempLocation\$ExportedFilesHTML | |
#endregion | |
#region Folders | |
# Remove the first 2 rows from the CSVs to leave just the relevant data | |
$CSVContent = Get-Content -Path $TempLocation\$FoldersCSV -ReadCount 0 | |
$CSVContent = $CSVContent | Select -Skip 1 | |
$CSVContent = $CSVContent | Select -Skip 1 | |
# Create a table to store the results | |
$Table = [System.Data.DataTable]::new("Directory Structure") | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Name",[System.String])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (Bytes)",[System.Int64])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (KB)",[System.Decimal])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (MB)",[System.Decimal])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Size (GB)",[System.Decimal])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Files",[System.String])) | |
[void]$Table.Columns.Add([System.Data.DataColumn]::new("Folders",[System.String])) | |
# Populate the table from the CSV data | |
Foreach ($csvrow in $CSVContent) | |
{ | |
$Content = $csvrow.split(',') | |
[void]$Table.rows.Add($($Content[0].Replace('"','')),$Content[2],([math]::Round(($Content[2] / 1KB),2)),([math]::Round(($Content[2] / 1MB),2)),([math]::Round(($Content[2] / 1GB),2)),$Content[5],$Content[6]) | |
} | |
# Export the table to a new CSV | |
$Table | Sort 'Size (Bytes)' -Descending | Export-CSV -Path $TempLocation\$ExportedFoldersCSV -NoTypeInformation -UseCulture | |
# Export the largest 100 results into html format | |
$Table | | |
Sort 'Size (Bytes)' -Descending | | |
Select -First 100 | | |
ConvertTo-Html -Property 'Name','Size (Bytes)','Size (KB)','Size (MB)','Size (GB)','Files','Folders' -Head $style -Body "<h2>100 largest directories on $env:COMPUTERNAME</h2>" -CssUri "http://www.w3schools.com/lib/w3.css" | | |
Out-String | Out-File $TempLocation\$ExportedFoldersHTML | |
#endregion | |
#region Create HTML disk usage summary report | |
# Get system drive data | |
$WMIDiskInfo = Get-CimInstance -ClassName Win32_Volume -Property Capacity,FreeSpace,DriveLetter | Where {$_.DriveLetter -eq $env:SystemDrive} | Select Capacity,FreeSpace,DriveLetter | |
$DiskInfo = [pscustomobject]@{ | |
DriveLetter = $WMIDiskInfo.DriveLetter | |
'Capacity (GB)' = [math]::Round(($WMIDiskInfo.Capacity / 1GB),2) | |
'FreeSpace (GB)' = [math]::Round(($WMIDiskInfo.FreeSpace / 1GB),2) | |
'UsedSpace (GB)' = [math]::Round((($WMIDiskInfo.Capacity / 1GB) - ($WMIDiskInfo.FreeSpace / 1GB)),2) | |
'Percent Free' = [math]::Round(($WMIDiskInfo.FreeSpace * 100 / $WMIDiskInfo.Capacity),2) | |
'Percent Used' = [math]::Round((($WMIDiskInfo.Capacity - $WMIDiskInfo.FreeSpace) * 100 / $WMIDiskInfo.Capacity),2) | |
} | |
# Create html header | |
$html = @" | |
<!DOCTYPE html> | |
<html> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css"> | |
<body> | |
"@ | |
# Set html | |
$html = $html + @" | |
<h2>Disk Space Usage for Drive $($DiskInfo.DriveLetter) on $env:COMPUTERNAME</h2> | |
<table cellpadding="0" cellspacing="0" width="700"> | |
<tr> | |
<td style="background-color:$(Set-PercentageColour -Value $($DiskInfo.'Percent Used'));padding:10px;color:#ffffff;" width="$($DiskInfo.'Percent Used')%"> | |
$($DiskInfo.'UsedSpace (GB)') GB ($($DiskInfo.'Percent Used') %) | |
</td> | |
<td style="background-color:#eeeeee;padding-top:10px;padding-bottom:10px;color:#333333;" width="$($DiskInfo.'Percent Used')%"> | |
</td> | |
</tr> | |
</table> | |
<table cellpadding="0" cellspacing="0" width="700"> | |
<tr> | |
<td style="padding:5px;" width="80%"> | |
Capacity: $($DiskInfo.'Capacity (GB)') GB | |
</td> | |
</tr> | |
<tr> | |
<td style="padding:5px;" width="80%"> | |
FreeSpace: $($DiskInfo.'FreeSpace (GB)') GB | |
</td> | |
</tr> | |
<tr> | |
<td style="padding:5px;" width="80%"> | |
Percent Free: $($DiskInfo.'Percent Free') % | |
</td> | |
</tr> | |
</table> | |
"@ | |
If ($DiskInfo.'FreeSpace (GB)' -lt 20) | |
{ | |
$html = $html + @" | |
<table cellpadding="0" cellspacing="0" width="700"> | |
<tr> | |
<td style="padding:5px;color:red;font-weight:bold" width="80%"> | |
You need to free $(20 - $DiskInfo.'FreeSpace (GB)') GB on this disk to pass the W10 readiness check! | |
</td> | |
</tr> | |
</table> | |
"@ | |
} | |
# Close html document | |
$html = $html + @" | |
</body> | |
</html> | |
"@ | |
# Export to file | |
$html | | |
Out-string | | |
Out-File $TempLocation\$SummaryHTMLReport | |
#endregion | |
#region Copy files to share | |
# Create a subfolder with computername if doesn't exist | |
If (!(Test-Path $TargetRoot\$env:COMPUTERNAME)) | |
{ | |
$null = New-Item -Path $TargetRoot -Name $env:COMPUTERNAME -ItemType Directory | |
} | |
# Create a subdirectory with current date-time | |
$DateString = ((Get-Date).ToUniversalTime() | get-date -Format "yyyy-MM-dd_HH-mm-ss").ToString() | |
If (!(Test-Path $TargetRoot\$env:COMPUTERNAME\$DateString)) | |
{ | |
$null = New-Item -Path $TargetRoot\$env:COMPUTERNAME -Name $DateString -ItemType Directory | |
} | |
# Set final target location | |
$TargetLocation = "$TargetRoot\$env:COMPUTERNAME\$DateString" | |
# Copy files | |
$Files = @( | |
$ExportedFilesCSV | |
$ExportedFoldersCSV | |
$ExportedFilesHTML | |
$ExportedFoldersHTML | |
$SummaryHTMLReport | |
) | |
Try | |
{ | |
Robocopy $TempLocation $TargetLocation $Files /R:10 /W:5 /NP | |
} | |
Catch {} | |
#endregion | |
# Cleanup temp files | |
$Files = @( | |
$FilesCSV | |
$FoldersCSV | |
$ExportedFilesCSV | |
$ExportedFoldersCSV | |
$ExportedFilesHTML | |
$ExportedFoldersHTML | |
$SummaryHTMLReport | |
) | |
Foreach ($file in $files) | |
{ | |
Remove-Item -Path $TempLocation\$file -Force | |
} | |
# Force a code 0 on exit, in case of some non-terminating error. | |
ExitWithCode 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment