Disk Space Sleuth: A Tale of PowerShell Optimization #
Hey there, tech enthusiasts and fellow script-wranglers! Today, we’re diving into the world of PowerShell optimization. Buckle up, because we’re about to turn a simple disk space query into a lean, mean, data-collecting machine.
The Mission #
Our mission, should we choose to accept it (and let’s face it, we’re geeks, of course we will), is to gather disk information from multiple servers efficiently. We’re talking system names, device IDs, and disk sizes - all neatly packaged in a CSV file. Sounds simple, right? Well, hold onto your keyboards, because we’re about to kick it up a notch.
The Original Script: A Diamond in the Rough #
Sometimes, us old-timers have a script that we have used for many years. Many will tell you the wise words of “If it is not broke, don’t fix it”. But sometimes, you do not know it is broke until you fix it. That is what happened to me here. We started with this little gem:
Get-WMIObject Win32_LogicalDisk -computer (Get-Content C:\scripts\servers.txt) -Filter "Drivetype=3" |
Select SystemName,DeviceID,@{Name='Size(GB)';Exp={$_.Size /1gb -as [int]}} |
Export-CSV "C:\CSVReports\DiskDrives.csv"Not bad, right? It gets the job done. But in the world of IT, “done” isn’t enough. We want it done faster, smoother, and with more pizzazz. (Okay, maybe not pizzazz, but definitely faster.)
The Optimization Journey #
1. Streamlined Reading #
First, we swapped out Get-Content for a StreamReader. It’s like upgrading from a bicycle to a motorcycle when reading our server list.
2. CIM for the Win #
We ditched Get-WMIObject in favor of Get-CimInstance. It’s newer, faster, and doesn’t require you to yell “WMI” every time you use it. (Though you can if you want to. I won’t judge.)
3. Batch Processing #
We introduced batch processing, because why query one server at a time when you can query 10? It’s like carpooling, but for data.
4. Parallel Power #
By using Invoke-Command, we’re now running our queries in parallel. It’s like sending out a team of mini-mes to gather data simultaneously. Efficiency at its finest!
5. Write As You Go #
Instead of hoarding all our data and then writing it out, we’re now writing to our CSV file in batches. It’s like clearing your plate between courses at a buffet - keeps things manageable and reduces the risk of a memory “food coma”.
The Optimized Script: A Thing of Beauty #
And now, ladies and gentlemen, I present to you the optimized script in all its glory:
# Define the output file path
$outputFile = "C:\CSVReports\DiskDrives.csv"
# Remove the existing output file if it exists
if (Test-Path $outputFile) {
Remove-Item $outputFile
}
# Use a StreamReader to read the servers file
$reader = [System.IO.StreamReader]::new("C:\scripts\servers.txt")
# Process servers in batches
$batchSize = 10
$batch = @()
while ($true) {
$server = $reader.ReadLine()
if ($server -eq $null) {
# Process remaining servers in the last batch
if ($batch.Count -gt 0) {
$results = Invoke-Command -ComputerName $batch -ScriptBlock {
Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3" |
Select-Object @{Name='SystemName';Expression={$env:COMPUTERNAME}},
DeviceID,
@{Name='Size(GB)';Expression={[int]($_.Size / 1GB)}}
}
$results | Export-Csv $outputFile -Append -NoTypeInformation
}
break
}
$batch += $server
if ($batch.Count -eq $batchSize) {
$results = Invoke-Command -ComputerName $batch -ScriptBlock {
Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3" |
Select-Object @{Name='SystemName';Expression={$env:COMPUTERNAME}},
DeviceID,
@{Name='Size(GB)';Expression={[int]($_.Size / 1GB)}}
}
$results | Export-Csv $outputFile -Append -NoTypeInformation
$batch = @()
}
}
$reader.Close()
Write-Host "Disk information has been exported to $outputFile"You can also find the script, just like all the other wonderful scripts you see on this block, from my GitHub repository here.
The Takeaway #
Remember, folks, optimization isn’t just about making things faster. It’s about being smarter with our resources, reducing strain on our systems, and ultimately, making our lives (and our servers’ lives) easier.
So, the next time you’re faced with a script that works but could work better, channel your inner optimizer. Your servers (and your fellow IT pros) will thank you.
Until next time, keep scripting, keep optimizing, and may your disk spaces always be plentiful!