Author Posts

February 12, 2016 at 6:39 am

Been reading through Ed Wilson's new book, Step by Step. Some really cool stuff in there and inspired me to have a play !
Created a small function to obtain the local C: drive freespace and drive size, then format the data into a custom object adding a percent used tab.

Am i on the right lines ?

Function Get-DriveInfo { #Runs only for local device

#Get drive information from WMI
$FreeSpace = (get-wmiobject win32_logicaldisk).where{($PSItem.DeviceID -eq 'C:')} | select Freespace,Size

#Create Object to Display Results
$DriveInfo = [pscustomobject]@{
    Freespace = "{0}","GB" -f [math]::truncate($freespace.freespace / 1GB)
    DiskSize = "{0}","GB" -f [math]::truncate($freespace.size / 1GB) 
    PercentUsed = "{0:P}" -f ($freespace.Freespace / $freespace.Size)
    }

#Display 
$DriveInfo | ft -AutoSize

}#End of Function

The results are displayed like so,

PS C:\Windows\system32> Get-DriveInfo

Freespace DiskSize PercentUsed
——— ——– ———–
48 GB 237 GB 20.25%

Be good to get some feedback, thanks !

February 12, 2016 at 7:18 am

Nice, but the function only get the C:\drive, how about if I have a d:\drive. Use parameters and advanced functions. Nice script.

February 12, 2016 at 7:26 am

Thanks Wifredo, i'll make it a bit more dynamic.

February 12, 2016 at 7:34 am

My only suggestion would be to filter with Get-WmiObject rather than using where-object to filter. This is always good practice, the mantra being 'filter left and format right'.

February 12, 2016 at 7:48 am

I'd make these changes:

function Get-DriveInfo {

$freespace = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceId = 'C:'" |
Select-Object Freespace, Size

$props = [ordered]@{
'Freespace(GB)' = [math]::Round($freespace.freespace / 1GB, 2)
'DiskSize(GB)' = [math]::Round($freespace.size / 1GB, 2)
PercentUsed = [math]::Round(($freespace.Freespace / $freespace.Size) * 100, 2)
}

New-Object -TypeName PSObject -Property $props
}

Use the CIM cmdlet rather than WMI cmdlet. Use the -Filter parameter rather than Where (already mentioned above)

Change the properties so that you're outputting numbers rather than strings – put the units into the property name rather than as part of the value

Output the object. You can always use Format-Table outside the function is need be. PowerShell 5 does a reasonable job of formatting table data automatically

February 12, 2016 at 8:13 am

Great stuff, thanks Richard and Peter.
Richard, any reason why you didn't use [PSCUSTOMOBJECT] ?

February 12, 2016 at 12:19 pm

I've added advanced function to it...


function Get-DriveInfo {

    [CmdletBinding()]
    param (
        [ValidateScript({
            If ($_ -match "^[A-Za-z]\:+$") {
                $True
            }
            else {
                Throw "$_ is either not a valid drive or it is not written as 'C:'."
            }
        })]
        [string]$Drive
    )

$freespace = Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceId = '$Drive'" |
 Select-Object Freespace, Size

$props = [ordered]@{
 'Freespace(GB)' = [math]::Round($freespace.freespace / 1GB, 2)
 'DiskSize(GB)' = [math]::Round($freespace.size / 1GB, 2)
 Percentfree = [math]::Round(($freespace.Freespace / $freespace.Size) * 100, 2)
 }

New-Object -TypeName PSObject -Property $props
 }

February 13, 2016 at 12:16 am

Hi Graham,

how about setting "C:" as default value for the Drive parameter?

[string]$Drive="C:"

By doing so, you still have the convenience of your first draft, but also the flexibility of your last version.

Michael

February 13, 2016 at 3:49 am

Nice idea Micheal, thanks !