Powershell – Windows 2012 R2 scripted access to freespace of physical disks

powershellstorage-spaceswindows-server-2012

Is there a way to access the freespace of the physical drives that make up a storage pool on Windows Server 2012?

I've just recently ran into a problem with running out of space, and can see the space allocated on each drive through the GUI, but can't seem to find a way to script it in Powershell (or vbscript/wmi or cmd), as I want to generate regular reports.

Best Answer

The Get-PhysicalDisk cmdlet has the info you need to calculate the free space. Specifically, it returns an object type that contains the following properties:

  • AllocatedSize (e.g. Used Space)
  • Size (e.g. Capacity)

Armed with that knowledge, we can make a basic one-liner to return the free space of all physical drives on the system (ignoring for the moment which ones are members of a virtual disk or storage pool:

Get-PhysicalDisk | Select FriendlyName,Size,@{L='Free Space';E={$_.Size-$_.AllocatedSize}}

But all of the values returned are in Bytes which isn't terribly useful on today's large disks. You probably want to format the results to either GB or TB like so:

Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}GB" -f ($_.Size/1GB)}},@{L='Free Space';E={"{0:N2}GB" -f (($_.Size-$_.AllocatedSize)/1GB)}} | Sort 'Free Space'
Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}TB" -f ($_.Size/1TB)}},@{L='Free Space';E={"{0:N2}TB" -f (($_.Size-$_.AllocatedSize)/1TB)}} | Sort 'Free Space'

So now we've got a command that will nicely list the Capacity and Free Space of all physical disks on the system. But we only want the physical disks that make up a particular storage pool. As it turns out, this is pretty easy with Get-StoragePool and powershell's native object piping:

Get-StoragePool 'MyPool' | Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}TB" -f ($_.Size/1TB)}},@{L='Free Space';E={"{0:N2}TB" -f (($_.Size-$_.AllocatedSize)/1TB)}} | Sort 'Free Space'

You query the disks associated with a virtual disk as well with Get-VirtualDisk:

Get-VirtualDisk 'MyVD' | Get-PhysicalDisk | Select FriendlyName,@{L='Capacity';E={"{0:N2}TB" -f ($_.Size/1TB)}},@{L='Free Space';E={"{0:N2}TB" -f (($_.Size-$_.AllocatedSize)/1TB)}} | Sort 'Free Space'