Get used/free space on Windows Server mount points with this Get-MountPointData cmdlet for PowerShell

From Svendsen Tech Powershell Wiki

Jump to: navigation, search

After researching the topic a bit, I decided to do what I think improves and combines the information I found about calculating the used/free space available on Windows Server mount points, and created the Get-MountPointData cmdlet. It displays information about all mount points that are listed in the Win32_MountPoint class (which includes "regular" drives - more on that later), and combines it with the information about size and used space in the Win32_Volume class, based on the device ID (formats are slightly different, so a conversion is made).

Contents






This has a few side-effects, such as filtering out the default System Reserved partition entry (introduced in Vista/2008, I think) that's listed if you only look at the Win32_Volume class and filter on something like the DriveLetter property not being set.

It uses WMI against remote computers with the -ComputerName parameter. Specify the name "localhost" for data about the local host. You can specify multiple servers separated by commas.

I also added a parameter called -IncludeRootDrives which allows you to look at regular disk drive letters on the desired servers as well, in the same way.


Output is by default sorted on free available space in percent, then descending on drive size (if the percentage is exactly the same), then by the label property and finally by caption.

I implemented it as functions, but didn't package it as a module. You can dot-source the ps1 file you download to get the functions in the currently available scope, or put it in your PowerShell profile. It is also possible to name the file Get-MountPointData.psm1 and put it in a subfolder of one of your $env:PSModulePath folders; if so, you would later import it with Import-Module.

The script is written so it's fairly easy to add other properties that you might want to list.

Download

Examples

A few examples

Showing Used/Free Space On Mount Points

Here I show the used/free space on the server file_server01's mount points, using the Get-MountPointData cmdlet.

PS C:\> . .\scripts\Get-MountPointData.ps1
PS C:\> Get-MountPointData -ComputerName file_server01 | Format-Table -AutoSize

Computer        Label       Caption            FileSystem Size (GB) Free space Percent free
--------        -----       -------            ---------- --------- ---------- ------------
file_server01   Dept0001    E:\foo\Dept0001    NTFS       250.00    37.73      15.09
file_server01   Dept0002    E:\foo\Dept0002    NTFS       500.00    83.13      16.63
file_server01   Dept0003    E:\foo\Dept0003    NTFS       350.00    73.38      20.97
file_server01   Dept0004    E:\bar\Dept0004    NTFS       150.00    50.37      33.58
file_server01   Dept0005    E:\bar\Dept0005    NTFS       150.00    56.89      37.93
file_server01   Dept0006    E:\bar\Dept0006    NTFS       300.00    124.42     41.47
file_server01   Dept0007    E:\baz\Dept0007    NTFS       100.00    45.10      45.11
file_server01   Dept0008    E:\baz\Dept0008    NTFS       70.00     31.90      45.57
file_server01   Dept0009    E:\foo\Dept0009    NTFS       300.00    157.08     52.36
file_server01   Dept0010    E:\foo\Dept0010    NTFS       200.00    109.37     54.68
file_server01   Dept0011    E:\foo\Dept0011    NTFS       300.00    191.93     63.98


Including Root Drives

Here's an example of a server without mount points, where I look only at the root drives, using the -IncludeRootDrives parameter.

PS C:\> Get-MountPointData -Comp filesrv2 -IncludeRootDrives | ft -a

Computer Label Caption FileSystem Size (GB) Free space Percent free
-------- ----- ------- ---------- --------- ---------- ------------
filesrv2       H:\                0.00      0.00
filesrv2 USER  D:\     NTFS       1,945.59  157.36     8.09
filesrv2 User3 F:\     NTFS       711.99    85.11      11.95
filesrv2 User4 G:\     NTFS       711.99    115.16     16.17
filesrv2 User2 E:\     NTFS       549.99    137.36     24.97
filesrv2       C:\     NTFS       48.83     22.24      45.54

"H:\" is an optical drive. The drives are sorted descendingly after percentage of free space.

Sorting By Drive Letter

To sort by drive letter, you can add "Sort Computer, Caption" to the pipeline before Format-Table -AutoSize. If you only target a single server, you can omit the "Computer" property and sort by caption only.

PS C:\> Get-MountPointData -Comp filesrv2 -IncludeRootDrives | Sort Computer, Caption | ft -a

Computer Label Caption FileSystem Size (GB) Free space Percent free
-------- ----- ------- ---------- --------- ---------- ------------
filesrv2       C:\     NTFS       48.83     22.24      45.54
filesrv2 USER  D:\     NTFS       1,945.59  157.36     8.09
filesrv2 User2 E:\     NTFS       549.99    137.36     24.97
filesrv2 User3 F:\     NTFS       711.99    85.11      11.95
filesrv2 User4 G:\     NTFS       711.99    115.16     16.17
filesrv2       H:\                0.00      0.00

Code

# Convert from one device ID format to another.
function Get-DeviceIDFromMP {
    
    param([Parameter(Mandatory=$true)][string] $VolumeString,
          [Parameter(Mandatory=$true)][string] $Directory)
    
    if ($VolumeString -imatch '^\s*Win32_Volume\.DeviceID="([^"]+)"\s*$') {
        # Return it in the wanted format.
        $Matches[1] -replace '\\{2}', '\'
    }
    else {
        # Return a presumably unique hashtable key if there's no match.
        "Unknown device ID for " + $Directory
    }
    
}

function Get-MountPointData {
    
    param([Parameter(Mandatory=$true)][string[]] $ComputerName,
          #[switch] $DoNotExcludeDefaults,
          [switch] $IncludeRootDrives
          )
    
    foreach ($Computer in $ComputerName) {
        
        try {
            
            # Collect mount point device IDs and populate a hashtable with IDs as keys
            $MountPointData = @{}
            Get-WmiObject Win32_MountPoint -ComputerName $Computer | 
                Where { if ($IncludeRootDrives) { $true } else { $_.Directory -NotMatch '^\s*Win32_Directory\.Name="[a-z]:\\{2}"\s*$' } } | ForEach-Object {
                    $MountPointData.(Get-DeviceIDFromMP $_.Volume $_.Directory) = $_.Directory
            }
            
            $Volumes = Get-WmiObject Win32_Volume -ComputerName $Computer | Where {
                    if ($IncludeRootDrives) { $true } else { -not $_.DriveLetter }
                } | 
                Select-Object Label, Caption, Capacity, FreeSpace, FileSystem, DeviceID, @{n='Computer';e={$Computer}}
            
        }
        
        catch {
            
            Write-Host -Fore Red "Terminating WMI error for ${Computer} (skipping): $($Error[0])"
            continue
            
        }
        
        if (-not $Volumes) {
            Write-Host -Fore Red "No mount points found on $Computer. Skipping..."
            continue
        }
        
        $Volumes | ForEach-Object {
            
            if ($MountPointData.ContainsKey($_.DeviceID)) {
                
                if ($_.Capacity) { $PercentFree = $_.FreeSpace*100/$_.Capacity }
                else { $PercentFree = 0 }
                
                $_ | Select-Object Computer, Label, Caption, FileSystem, @{n='Size (GB)';e={$_.Capacity/1GB}},
                    @{n='Free space';e={($_.FreeSpace/1GB).ToString('N')}}, @{n='Percent free';e={$PercentFree}}
                
            }
            
        } | Sort-Object -Property 'Percent free', @{Descending=$true;e={$_.'Size (GB)'}}, Label, Caption |
            Select-Object Computer, Label, Caption, FileSystem, @{n='Size (GB)';e={$_.'Size (GB)'.ToString('N')}},
                          'Free space', @{n='Percent free';e={$_.'Percent free'.ToString('N')}}
        
    }
    
}
Personal tools