A couple of weeks ago someone asked me why they should upgrade to MS SQL Server 2012. I named a bunch of reasons and only remembered afterwards that the possibility to use Windows Server Core could also be a surplus. Just 2 days later this Case for Core post from Jeremiah Peschka (blog | twitter) made me realize there was a lot of work for me before I could say that running MS SQL Server 2012 on Windows Server Core. I already read the book Microsoft SQL Server 2008 Administration with Windows PowerShell and reviewed it here.So I decided to try to avoid the usage of Remote Desktop as much as possible and finally start to use PowerShell on a daily basis. One of the first things I needed to do was the restore of a database on another server. So before I could start the restore I needed to check the servers’ disk configuration and available space. So let’s see how to do this with PowerShell.
To get information about disks we use the win32_logicaldisk wmiobject and with the -computer parameter we specify our server name:

GET-WmiObject win32_logicaldisk -computer <computername>

The result looks like this:

As you can see, the requested information is there and if I only need to do this just once it’s fine but I’m going to need this information several times on different servers so let’s make the result more user friendly.
First things first, let’s just select the data I need, with a pipe I pass the input from the Get-WmiObject to the second part of my command and there I use the Select-Object to specify the object that I want:

Get-WmiObject win32_logicaldisk -computer <computername> | select-object DeviceID, VolumeName,Size,FreeSpace

This looks better:

Next step is to see the percentage free space. Using @{Name=””,Expression={}}:

Get-WmiObject win32_logicaldisk -computer <computername> | select-object DeviceID, VolumeName,Size,FreeSpace,@{Name="PCTFreeSpace";Expression={$_.FreeSpace/$_.Size*100}}

The code works but now I have to scroll again to see all the disk info:

I add a second pipe and specify that I want my result formatted as a table, I also make sure the size and free space make more sense:

Get-WmiObject win32_logicaldisk -computer <computername> | 
select-object DeviceID, VolumeName, @{Name="Size";Expression={$_.Size/1GB}},@{Name="FreeSpace";Expression={$_.FreeSpace/1GB}},
@{Name="PCTFreeSpace";Expression={
$_.FreeSpace/$_.Size*100}}|format-table

Better no?

Now you can save this script to a text file, rename the file extension to .ps1 and edit the file every time you need to query another server. Or you can use a parameter. I named my file GetDiskUsage.ps1 and started the script with param([Datatype] $Variablename):

param(
	[string] $compname )
Get-WmiObject win32_logicaldisk -computer <computername> | 
select-object DeviceID, VolumeName, @{Name="Size";Expression={$_.Size/1GB}},@{Name="FreeSpace";Expression={$_.FreeSpace/1GB}},
@{Name="PCTFreeSpace";Expression={
$_.FreeSpace/$_.Size*100}}|Sort-Object -descending PCTfreespace|format-table

Now I can execute the script with the following command:

.Getdiskusage <Computername>

Notice that I also added a Sort-Object before the format to be able to see what disk has the most available free space first:

To finish things up a use a Throw in my parameter definition to avoid an ugly error message when I execute the script without specifying a parameter value:

param(
	[string] $compname = $(Throw "Provide a Server name as first parameter") )
Get-WmiObject win32_logicaldisk -computer <computername> | 
select-object DeviceID, VolumeName, @{Name="Size";Expression={$_.Size/1GB}},@{Name="FreeSpace";Expression={$_.FreeSpace/1GB}},
@{Name="PCTFreeSpace";Expression={
$_.FreeSpace/$_.Size*100}}|Sort-Object -descending PCTfreespace|format-table

When I now execute the script without specifying a computer name:

.Getdiskusage

I see I have to specify a computer name:

I know there are alternatives to write this wmi query. This is just a way that works for me and does the trick now. Feel free to comment and/or correct me if there are better solutions.