Getting the Free Disk Space of Remote Computers Revisited
April 18th, 2017 by Charlie Russel and tagged Calculated Column, Comment-Based Help, Disk Free Space, ErrorAction, Format-Table, Formatting output, Pipeline, PowerShell, Process{}, WMI
Several years ago, I wrote a fairly simplistic script to get the free disk space of remote computers. It wasn’t all that sophisticated, but it got the job that I needed done, so I shared it here on my blog, since I thought others might find it useful. Which, based on the number of hits here, and the comments, they did. However, based on some of those comments, it had a problem for some users.
The problem was that I used Write-Host in it. That was fine for me, because I only used it to write to my screen. But it’s a bad practice to be using Write-Host unless you really need to manipulate screen colours. The reason it’s a bad practice is that it prevents any sort of redirection! This meant that those users who wanted to capture the result of the script in a file were horked, because Write-Host will ALWAYS write to ( … wait for it… )
The Host. You can’t redirect it. The fix, of course, is easy — use Write-Object instead, which is what I should have done in the first place.
While I was in the process of making that change, I thought it would be nice to add in a basic Get-Help page for it, which was trivial. But then it occurred to me that I really should let it handle pipeline input, allowing me to use other PowerShell commands to select the group of machines I wanted the free disk space on, and then pipe that result directly to Get-myFreeSpace.
Seemed like a good idea, but it turned out I had to almost completely rewrite the script to use the Begin{}/Process{}/End{} syntax. Accepting pipeline input is not as simple as just saying you do in the Parameter statement, you need to actually process that input. The result is the new, improved version of Get-myFreeSpace.ps1 shown below. (If you care about how I got to this script in the first place, do check out the original post, here. There’s some useful information there about the whole process. )
<# .Synopsis Gets the disk utilization of one or more computers .Description Get-myFreeSpace queries an array of remote computers and returns a nicely formatted display of their current disk utilization and free space. The output can be redirected to a file or other output option using standard redirection. .Example Get-myFreeSpace Gets the disk utilization and free space of all drives on the local host. .Example Get-myFreeSpace -ComputerName Server1,Server2 Gets the disk utilization and free space of all drives on the Server1 and Server2 .Example (Get-VM -Name "*server*" | Where State -eq 'Running' ).Name | Get-myFreeSpace PS C:\>(Get-VM -Name "*server*" | Where-Object {$_.State -eq 'Running').Name | Get-myFreeSpace Gets a list of running VMs with Server in their name, and passes it to Get-myFreeSpace to process for their current disk utilization. The first version of this example uses PowerShell v5 syntax, while the second version uses the older syntax that works on earlier versions. .Parameter ComputerName An array of computer names from which you want the disk utilization .Inputs [string[]] .Notes Author: Charlie Russel Copyright: 2017 by Charlie Russel : Permission to use is granted but attribution is appreciated Initial: 26 Nov, 2014 (cpr) ModHist: 29 Sep, 2016 -- Changed default to array of localhost (cpr) : 18 Apr, 2017 -- Changed to use Write-Output,accept Pipeline,added man page, (cpr) : #> [CmdletBinding()] Param( [Parameter(Mandatory=$False,Position=0,` ValueFromPipeline=$True,` ValueFromPipelineByPropertyName=$True,` ValueFromRemainingArguments=$True)] [alias("Name","Computer")] [string[]] $ComputerName = @("localhost") ) Begin { if ($Input) { $ComputerName = @($Input) } Write-Output "" # Save ErrorActionPreference so we can reset it when we're done $eap = $ErrorActionPreference } Process { $ErrorActionPreference = 'SilentlyContinue' ForEach ( $Computer in $ComputerName ) { Write-Output "Disk Utilization for Computer $Computer is: " Get-WmiObject -ComputerName $Computer -Class Win32_Volume ` | Format-Table -auto ` @{Label="Drive";` Expression={$_.DriveLetter};` Align="Right"},` @{Label="Free(GB)";` Expression={"{0:N0}" -f ($_.FreeSpace/1GB)};` Align="Right"},` @{Label="% Free";` Expression={"{0:P0}" -f ($_.FreeSpace / $_.Capacity)};` Align="Right"},` @{Label="Size(GB)";` Expression={"{0:N0}" -f ($_.Capacity / 1GB)};` Align="Right"},` @{Label="Volume Label";` Expression={$_.Label};` Width=25} } #EndForEach } #EndProcessBlock End { # Reset ErrorActionPreference to original value $ErrorActionPreference = $eap }
And there you have it. A new and improved version of one of the most popular scripts I’ve ever posted here. You can use it to get the disk utilization on your current machine, or any list of remote computers to which you have the rights to run WMI against.
I hope you find this script useful, and I’d love to hear comments, suggestions for improvements, or bug reports as appropriate. As always, if you use this script as the basis for your own work, please respect my copyright and provide appropriate attribution.
Posted in Annoyances, Network Administration, PowerShell, Windows Server, WMI | 4 Comments »