Reputation: 7228
I am trying to create a Function to return the amount of free drive space in MB. The function takes the path name as a parameter and must cope with mount points. My drives are set up like this:
So I want to do something like:
function Get-FreeSpace {
param (
$path
);
# iterate through and find the volume, detect if in a mount point and return free space
#
return [int]$freeSpace;
}
I have looked at using this array as a starting point in my function, but I am getting stuck.
$vols = Get-WMIObject Win32_Volume -filter "DriveType=3" -computer $computerName | Select Caption,DriveLetter,Label,@{Name="DiskSize(GB)";Expression={[decimal]("{0:N1}" -f($_.capacity/1gb))}},@{Name="PercentFree(%)";Expression={"{0:P2}" -f(($_.freespace/1mb)/($_.capacity/1mb))}}
$vols
is returning a System.Array
of PSCustomObject
types. So if I pass the function the following paths:
G:\Data\My\Test\Path
G:\Data
It will find the free space of the G:\Data
mount point.
If I pass it G:\Some\Other\Path
, it will return the free space of the G:\
drive. I want to use it like so: $freeSpace = Get-FreeSpace "G:\Some\Other\Path"
I would be grateful for any help.
Upvotes: 4
Views: 5693
Reputation: 200273
Try this:
function Get-FreeSpace {
Param(
$path
);
if ($path[-1] -ne '\') { $path += '\' }
$filter = "DriveType=3 And Name='$($path -replace '\\', '\\')'"
$free = Get-WmiObject Win32_Volume -Filter $filter |
Select-Object -Expand FreeSpace
return ($free / (1024*1024))
}
You need to double the backslashes in $path
, because they must be escaped for WMI queries. For that (confusing as it may seem) you have to replace '\\'
with '\\'
, because the first occurrence is a regular expression where the backslash must be escaped, whereas the second occurrence is a string literal with a double backslash.
Update:
To match a partial path you could use the -like
operator:
function Get-FreeSpace {
Param(
$path
);
$free = Get-WmiObject Win32_Volume -Filter "DriveType=3" |
Where-Object { $path -like "$($_.Name)*" } |
Sort-Object Name -Desc |
Select-Object -First 1 FreeSpace |
ForEach-Object { $_.FreeSpace / (1024*1024) }
return ([int]$free)
}
The Where-Object
clause selects all mount points with a partial path matching $path
, and the subsequent Sort-Object | Select-Object
selects the one with the longest match.
Upvotes: 4
Reputation: 1362
A simpler variant:
function Get-FreeSpace {
param ([string]$path);
$space = (Get-Volume -FilePath $path).SizeRemaining;
return [int64]($space / (1024 * 1024)); # this would otherwise be a float
}
Get-Volume -FilePath
retrieves the volume associated with the provided path; from that volume, we extract SizeRemaining
and divide out 1MB. The cast to int64 is because the operation would otherwise return float.
Upvotes: 3