How to get disk capacity and free space of remote computer
PowershellScriptingPowershell 2.0Powershell Problem Overview
I have this one-liner:
get-WmiObject win32_logicaldisk -Computername remotecomputer
and the output is this:
DeviceID : A:
DriveType : 2
ProviderName :
FreeSpace :
Size :
VolumeName :
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 20116508672
Size : 42842714112
VolumeName :
DeviceID : D:
DriveType : 5
ProviderName :
FreeSpace :
Size :
VolumeName :
How do I get Freespace
and Size
of DeviceID
C:
? I need to extract just these two values with no other informations. I have tried it with Select
cmdlet, but with no effect.
Edit: I need to extract the numerical values only and store them in variables.
Powershell Solutions
Solution 1 - Powershell
Much simpler solution:
Get-PSDrive C | Select-Object Used,Free
and for remote computers (needs Powershell Remoting
)
Invoke-Command -ComputerName SRV2 {Get-PSDrive C} | Select-Object PSComputerName,Used,Free
Solution 2 - Powershell
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Select-Object Size,FreeSpace
$disk.Size
$disk.FreeSpace
To extract the values only and assign them to a variable:
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Foreach-Object {$_.Size,$_.FreeSpace}
Solution 3 - Powershell
Just one command simple sweet and clean but this only works for local disks
Get-PSDrive
You could still use this command on a remote server by doing a Enter-PSSession -Computername ServerName and then run the Get-PSDrive it will pull the data as if you ran it from the server.
Solution 4 - Powershell
I created a PowerShell advanced function (script cmdlet) a while back that allows you to query multiple computers.
The code for the function is a little over 100 lines long, so you can find it here: PowerShell version of the df command
Check out the Usage section for examples. The following usage example queries a set of remote computers (input from the PowerShell pipeline) and displays the output in a table format with numeric values in human-readable form:
PS> $cred = Get-Credential -Credential 'example\administrator'
PS> 'db01','dc01','sp01' | Get-DiskFree -Credential $cred -Format | Format-Table -GroupBy Name -AutoSize
Name: DB01
Name Vol Size Used Avail Use% FS Type
---- --- ---- ---- ----- ---- -- ----
DB01 C: 39.9G 15.6G 24.3G 39 NTFS Local Fixed Disk
DB01 D: 4.1G 4.1G 0B 100 CDFS CD-ROM Disc
Name: DC01
Name Vol Size Used Avail Use% FS Type
---- --- ---- ---- ----- ---- -- ----
DC01 C: 39.9G 16.9G 23G 42 NTFS Local Fixed Disk
DC01 D: 3.3G 3.3G 0B 100 CDFS CD-ROM Disc
DC01 Z: 59.7G 16.3G 43.4G 27 NTFS Network Connection
Name: SP01
Name Vol Size Used Avail Use% FS Type
---- --- ---- ---- ----- ---- -- ----
SP01 C: 39.9G 20G 19.9G 50 NTFS Local Fixed Disk
SP01 D: 722.8M 722.8M 0B 100 UDF CD-ROM Disc
Solution 5 - Powershell
Another way is casting a string to a WMI object:
$size = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'").Size
$free = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'").FreeSpace
Also you can divide the results by 1GB or 1MB if you want different units:
$disk = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'")
"Remotecomputer C: has {0:#.0} GB free of {1:#.0} GB Total" -f ($disk.FreeSpace/1GB),($disk.Size/1GB) | write-output
Output is: Remotecomputer C: has 252.7 GB free of 298.0 GB Total
Solution 6 - Powershell
There are two issues I encountered with the other suggestions
- 1) Drive mappings are not supported if you run the powershell under task scheduler
- 2) You may get Access is denied errors errors trying to used "get-WmiObject" on remote computers (depending on your infrastructure setup, of course)
The alternative that doesn't suffer from these issues is to use GetDiskFreeSpaceEx with a UNC path:
function getDiskSpaceInfoUNC($p_UNCpath, $p_unit = 1tb, $p_format = '{0:N1}')
{
# unit, one of --> 1kb, 1mb, 1gb, 1tb, 1pb
$l_typeDefinition = @'
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
out ulong lpFreeBytesAvailable,
out ulong lpTotalNumberOfBytes,
out ulong lpTotalNumberOfFreeBytes);
'@
$l_type = Add-Type -MemberDefinition $l_typeDefinition -Name Win32Utils -Namespace GetDiskFreeSpaceEx -PassThru
$freeBytesAvailable = New-Object System.UInt64 # differs from totalNumberOfFreeBytes when per-user disk quotas are in place
$totalNumberOfBytes = New-Object System.UInt64
$totalNumberOfFreeBytes = New-Object System.UInt64
$l_result = $l_type::GetDiskFreeSpaceEx($p_UNCpath,([ref]$freeBytesAvailable),([ref]$totalNumberOfBytes),([ref]$totalNumberOfFreeBytes))
$totalBytes = if($l_result) { $totalNumberOfBytes /$p_unit } else { '' }
$totalFreeBytes = if($l_result) { $totalNumberOfFreeBytes/$p_unit } else { '' }
New-Object PSObject -Property @{
Success = $l_result
Path = $p_UNCpath
Total = $p_format -f $totalBytes
Free = $p_format -f $totalFreeBytes
}
}
Solution 7 - Powershell
Get-PSDrive C | Select-Object @{ E={$_.Used/1GB}; L='Used' }, @{ E={$_.Free/1GB}; L='Free' }
Solution 8 - Powershell
Command-line:
powershell gwmi Win32_LogicalDisk -ComputerName remotecomputer -Filter "DriveType=3" ^|
select Name, FileSystem,FreeSpace,BlockSize,Size ^| % {$_.BlockSize=
(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_}
^| Format-Table Name, @{n='FS';e={$_.FileSystem}},@{n='Free, Gb';e={'{0:N2}'-f
$_.FreeSpace}}, @{n='Free,%';e={'{0:N2}'-f $_.BlockSize}},@{n='Capacity ,Gb';e={'{0:N3}'
-f $_.Size}} -AutoSize
Output:
Name FS Free, Gb Free,% Capacity ,Gb
---- -- -------- ------ ------------
C: NTFS 16,64 3,57 465,752
D: NTFS 43,63 9,37 465,759
I: NTFS 437,59 94,02 465,418
N: NTFS 5,59 0,40 1 397,263
O: NTFS 8,55 0,96 886,453
P: NTFS 5,72 0,59 976,562
command-line:
wmic logicaldisk where DriveType="3" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpace
out:
Caption FileSystem FreeSpace Size VolumeName VolumeSerialNumber
C: NTFS 17864343552 500096991232 S01 EC641C36
D: NTFS 46842589184 500104687616 VM1 CAF2C258
I: NTFS 469853536256 499738734592 V8 6267CDCC
N: NTFS 5998840832 1500299264512 Vm-1500 003169D1
O: NTFS 9182349312 951821143552 DT01 A8FC194C
P: NTFS 6147043840 1048575144448 DT02 B80A0F40
command-line:
wmic logicaldisk where Caption="C:" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpace
out:
Caption FileSystem FreeSpace Size VolumeName VolumeSerialNumber
C: NTFS 17864327168 500096991232 S01 EC641C36
command-line:
dir C:\ /A:DS | find "free"
out:
4 Dir(s) 17 864 318 976 bytes free
dir C:\ /A:DS /-C | find "free"
out:
4 Dir(s) 17864318976 bytes free
Solution 9 - Powershell
Just found Get-Volume command, which returns SizeRemaining
, so something like (Get-Volume -DriveLetter C).SizeRemaining / (1e+9)
can be used to see remained Gb for disk C. Seems works faster than Get-WmiObject Win32_LogicalDisk
.
Solution 10 - Powershell
PS> Get-CimInstance -ComputerName bobPC win32_logicaldisk | where caption -eq "C:" | foreach-object {write " $($_.caption) $('{0:N2}' -f ($_.Size/1gb)) GB total, $('{0:N2}' -f ($_.FreeSpace/1gb)) GB free "}
C: 117.99 GB total, 16.72 GB free
PS>
Solution 11 - Powershell
I know of psExec tools which you can download from here
There comes a psinfo.exe from the tools package. The basic usage is in the following manner in powershell/cmd.
However you could have a lot of options with it
Usage: psinfo [[\computer[,computer[,..] | @file [-u user [-p psswd]]] [-h] [-s] [-d] [-c [-t delimiter]] [filter]
\computer Perform the command on the remote computer or computers specified. If you omit the computer name the command runs on the local system, and if you specify a wildcard (\*), the command runs on all computers in the current domain.
@file Run the command on each computer listed in the text file specified.
-u Specifies optional user name for login to remote computer.
-p Specifies optional password for user name. If you omit this you will be prompted to enter a hidden password.
-h Show list of installed hotfixes.
-s Show list of installed applications.
-d Show disk volume information.
-c Print in CSV format.
-t The default delimiter for the -c option is a comma, but can be overriden with the specified character.
filter Psinfo will only show data for the field matching the filter. e.g. "psinfo service" lists only the service pack field.
Solution 12 - Powershell
On PowerShell:
"FreeSpace C: " + [math]::Round((Get-Volume -DriveLetter C).SizeRemaining / 1Gb) + " GB"
Solution 13 - Powershell
I remote into the computer using Enter-PSsession pcName then I type Get-PSDrive
That will list all drives and space used and remaining. If you need to see all the info formated, pipe it to FL like this: **Get-PSdrive | FL ***
Solution 14 - Powershell
I created this simple function to help me. This makes my calls a lot easier to read that having inline an Get-WmiObject, Where-Object statements, etc.
function GetDiskSizeInfo($drive) {
$diskReport = Get-WmiObject Win32_logicaldisk
$drive = $diskReport | Where-Object { $_.DeviceID -eq $drive}
$result = @{
Size = $drive.Size
FreeSpace = $drive.Freespace
}
return $result
}
$diskspace = GetDiskSizeInfo "C:"
write-host $diskspace.FreeSpace " " $diskspace.Size
Solution 15 - Powershell
In case you want to check multiple drive letters and/or filter between local and network drives, you can use PowerShell to take advantage of the Win32_LogicalDisk WMI class. Here's a quick example:
$localVolumes = Get-WMIObject win32_volume;
foreach ($vol in $localVolumes) {
if ($vol.DriveLetter -ne $null ) {
$d = $vol.DriveLetter[0];
if ($vol.DriveType -eq 3) {
Write-Host ("Drive " + $d + " is a Local Drive");
}
elseif ($vol.DriveType -eq 4) {
Write-Host ("Drive" + $d + " is a Network Drive");
}
else {
// ... and so on
}
$drive = Get-PSDrive $d;
Write-Host ("Used space on drive " + $d + ": " + $drive.Used + " bytes. `r`n");
Write-Host ("Free space on drive " + $d + ": " + $drive.Free + " bytes. `r`n");
}
}
I used the above technique to create a Powershell script that checks all drives and send an e-mail alert whenever they go below a user-defined quota. You can get it from this post on my blog.
Solution 16 - Powershell
PowerShell Fun
Get-WmiObject win32_logicaldisk -Computername <ServerName> -Credential $(get-credential) | Select DeviceID,VolumeName,FreeSpace,Size | where {$_.DeviceID -eq "C:"}