<span class="ContentText ContentTextvariantbodyNormal” data-testid=”content-text”>[Editor’s Note: This is Part 2 of a three-part series on building a Windows storage dashboard.]
In the previous installment of this series, we explored the creation of a fundamental disk monitoring dashboard utilizing PowerShell. Now, we turn our attention to the vital task of importing historical data, which necessitates a robust method for data collection.
Gathering historical data comprises two essential steps. The first involves crafting a script that retrieves and saves the data of interest. The second step requires configuring the Windows Task Scheduler to execute this script at predetermined intervals, allowing for a comprehensive view of storage consumption trends over time.
While I have previously detailed the process of using the Windows Task Scheduler to run PowerShell scripts on a schedule, I will not delve into that here. Instead, it is crucial to note that when creating a scheduled task, one cannot directly call the PowerShell script. The task must be set up to execute PowerShell.exe, with the Add Arguments field containing the -File parameter, followed by the script’s path and filename, enclosed in quotation marks. For those seeking further insights, my original article provides a wealth of information.
<h2 class="ContentText ContentTextvarianth2 ContentTextalignleft” data-testid=”content-text” id=”Storing the Data”>Storing the Data
At this juncture, our focus shifts to developing the script responsible for collecting storage data. A pivotal decision in this process is determining where to store the data. Several viable options are available, including writing to a SQL Server database, a text file, or even a JSON file. However, the most straightforward choice is likely to be a CSV file.
The script I devised is succinct yet effective. Below is the script:
<span class="ContentText ContentTextvariantbodyNoneStyle" data-testid="content-text">$LogFile = "C:ScriptsDiskUsageHistory.csv" Get-PSDrive -PSProvider 'FileSystem' | ForEach-Object { [PSCustomObject]@{ Timestamp = (Get-Date) Drive = $_.Name UsedGB = "{0:N2}" -f ($_.Used / 1GB) FreeGB = "{0:N2}" -f ($_.Free / 1GB) TotalGB = "{0:N2}" -f (($.Used + $.Free) / 1GB) } } | Export-Csv -Path $LogFile -Append -NoTypeInformation
The initial command in this script establishes a variable named $LogFile, which specifies the full path and filename for storing the logging data—in this instance, C:ScriptsDiskUsageHistory.csv.
Subsequently, the script employs the Get-PSDrive cmdlet to compile a list of the system’s drives. It is noteworthy that executing this command alone retrieves more than just a list of disks; it also encompasses PowerShell’s Variable, WSMan, Registry, Function, Alias, Certificate, and Environment drives. To refine the results, I utilize the -PSProvider parameter, ensuring that only file system drives are included, thereby capturing both local and network drives.
The script then engages a ForEach loop to gather data for each drive identified by the Get-PSDrive command. Within this loop, a custom PowerShell object is created, generating columns for Timestamp, Drive, UsedGB, FreeGB, and TotalGB. As demonstrated in the first part of this series, the used, free, and total disk space figures are expressed in gigabytes and rounded to two decimal places to maintain clarity and conciseness.
<h2 class="ContentText ContentTextvarianth2 ContentTextalignleft” data-testid=”content-text” id=”Exporting to CSV: Key Parameters”>Exporting to CSV: Key Parameters
Once the custom objects are generated (one for each drive), the results are piped to the Export-CSV cmdlet, which is responsible for creating the CSV file. Notably, I employ three parameters with this cmdlet.
- -Path: This parameter directs the script to write the CSV file to the location specified in the $LogFile variable.
- -Append: This parameter ensures that new data is added to the end of the existing CSV file, creating a new file if it does not already exist. Without this, the CSV file would be overwritten with each execution of the script.
- -NoTypeInformation: This parameter prevents type information from being included in the file’s header row, making the CSV file easier to navigate.
Here is a sample of the data generated when I executed the script twice:
<span class="ContentText ContentTextvariantbodyNoneStyle" data-testid="content-text">"Timestamp","Drive","UsedGB","FreeGB","TotalGB" "5/30/2025 3:29:22 PM","C","387.48","1,474.53","1,862.01" "5/30/2025 3:29:22 PM","D","0.00","0.00","0.00" "5/30/2025 3:29:22 PM","E","0.00","0.00","0.00" "5/30/2025 3:29:22 PM","F","0.00","0.00","0.00" "5/30/2025 3:29:22 PM","G","0.00","0.00","0.00" "5/30/2025 3:29:22 PM","H","0.00","0.00","0.00" "5/30/2025 3:29:22 PM","M","7,885.12","2,114.76","9,999.87" "5/30/2025 3:29:22 PM","Q","15,142.20","25,817.67","40,959.87" "5/30/2025 3:29:22 PM","R","604.36","1,258.64","1,863.00" "5/30/2025 3:29:22 PM","V","97.73","3,998.14","4,095.87" "5/30/2025 3:29:22 PM","W","92.00","1,771.00","1,863.00" "5/30/2025 3:29:52 PM","C","387.48","1,474.53","1,862.01" "5/30/2025 3:29:52 PM","D","0.00","0.00","0.00" "5/30/2025 3:29:52 PM","E","0.00","0.00","0.00" "5/30/2025 3:29:52 PM","F","0.00","0.00","0.00" "5/30/2025 3:29:52 PM","G","0.00","0.00","0.00" "5/30/2025 3:29:52 PM","H","0.00","0.00","0.00" "5/30/2025 3:29:52 PM","M","7,885.12","2,114.76","9,999.87" "5/30/2025 3:29:52 PM","Q","15,142.20","25,817.67","40,959.87" "5/30/2025 3:29:52 PM","R","604.36","1,258.64","1,863.00" "5/30/2025 3:29:52 PM","V","97.73","3,998.14","4,095.87" "5/30/2025 3:29:52 PM","W","92.00","1,771.00","1,863.00"
The CSV file showcases a header row alongside a timestamp, drive letter, used space, free space, and total capacity for each disk. With this foundational knowledge of collecting historical data for your disks, the next part of this series will guide you in integrating this data into the script we began in Part 1.