150

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.

Thomas BDX
  • 2,632
  • 2
  • 27
  • 31
culter
  • 5,487
  • 15
  • 54
  • 66

17 Answers17

164

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
Thomas BDX
  • 2,632
  • 2
  • 27
  • 31
Null Pointers etc.
  • 2,124
  • 2
  • 14
  • 20
158
$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}
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • 21
    simply adding $disk.Size / 1GB makes the result more readable also. – ricky89 Jul 22 '15 at 08:51
  • 11
    If you want to round the display to only show whole numbers, use `[Math]::Round($Disk.Freespace / 1GB)` – user4317867 Sep 24 '16 at 19:50
  • in powershell why does `1mb` return a value of `1048576` and not `1000000` ???? – oldboy Jan 01 '20 at 04:56
  • 1
    @oldboy because it uses powers of 2: 2^20 vs. 10^6. It should indeed be written `1MiB` (with proper case) but is usually shown in lower case, without th "i". See [Mebibyte](https://en.wikipedia.org/wiki/Mebibyte). – Matthieu Mar 03 '20 at 12:09
  • @oldboy why mb, this time is long over, we are 000 further regarding memory. – Timo Nov 22 '20 at 19:27
  • I get an error "Get-WmiObject : The RPC server is unavailable." – James Dec 09 '20 at 14:03
74

Just one command simple sweet and clean but this only works for local disks

Get-PSDrive

enter image description here

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.

Community
  • 1
  • 1
grepit
  • 21,260
  • 6
  • 105
  • 81
  • 2
    To get only filesystem drives: `Get-PSDrive | ? { $_.Provider.Name -eq 'FileSystem' }` – zett42 Feb 26 '21 at 10:10
  • Is there any way to give this command with authentication credentials ? Say for example Enter-PSSession -Computername 10.167.162.61 --user --password ? – rinilnath Apr 19 '22 at 06:06
19

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
mweisel
  • 317
  • 2
  • 4
13

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
    } 
}
Warren Stevens
  • 1,047
  • 12
  • 12
11

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

Greg Bray
  • 14,929
  • 12
  • 80
  • 104
  • 1
    See also http://stackoverflow.com/questions/11026687/server-management-need-script-to-monitor-free-space-on-server and http://stackoverflow.com/questions/56715/best-way-to-query-disk-space-on-remote-server – Greg Bray Sep 17 '12 at 21:21
  • @BillGreer Don't know offhand but I've often found WMI calls slower than PS. You can yourself test with Measure-Command but make sure to run it a bunch of times and average the results. – duct_tape_coder Apr 25 '19 at 18:06
8
Get-PSDrive C | Select-Object @{ E={$_.Used/1GB}; L='Used' }, @{ E={$_.Free/1GB}; L='Free' }
Cy Rossignol
  • 16,216
  • 4
  • 57
  • 83
leorzz
  • 419
  • 3
  • 7
7

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
STTR
  • 139
  • 2
  • 2
  • 2
    This is ridiculous. – Alexander Trauzzi Feb 21 '18 at 15:40
  • why @AlexanderTrauzzi? – Kiquenet Apr 22 '19 at 15:36
  • 1
    `wmic logicaldisk get size` doesnt account for reserved space tho... in powershell `get-volume` returns the practical total size (i.e. minus reserved space), but then when i try `get-volume | format-list size` it says the total size plus the reserved space... how do i get the total size minus reserved space for each drive with powershell??? – oldboy Jan 01 '20 at 04:03
6

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.

Ilya Finkelsheyn
  • 2,851
  • 11
  • 20
3
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> 
quux
  • 660
  • 1
  • 10
  • 22
  • 1
    Nathan, I rolled back your edit. This shows the output given, which is valuable to those selecting an answer for its results. It's one line to copy & paste. – quux May 08 '15 at 01:46
3

On PowerShell:

"FreeSpace C:  " + [math]::Round((Get-Volume -DriveLetter C).SizeRemaining / 1Gb) + " GB"
lynx_74
  • 1,633
  • 18
  • 12
  • Nice because it passes filters down to source. I prefer efficiency (and simplicity, use built-in filter). – yzorg Apr 04 '23 at 15:42
2

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.

enter image description here

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.

Himanshu Chauhan
  • 812
  • 9
  • 11
0

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 *

Michael Dark
  • 149
  • 1
  • 5
0

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kaj Bonfils
  • 416
  • 4
  • 10
0

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.

Darkseal
  • 9,205
  • 8
  • 78
  • 111
0

PowerShell Fun

Get-WmiObject win32_logicaldisk -Computername <ServerName> -Credential $(get-credential) | Select DeviceID,VolumeName,FreeSpace,Size | where {$_.DeviceID -eq "C:"}
GhostWolf
  • 35
  • 1
  • 8
0

"FreeSpace C: {0:n3} GB" -f ((Get-Volume -DriveLetter C).SizeRemaining / 1Gb)

yzorg
  • 4,224
  • 3
  • 39
  • 57
  • @lynx_74 answer but format instead of calling `[Math]::Round()`, .NET built-in format string `n3`, or like `{0:0.000}`. `{0:n0}` would round like lynx, but I prefer seeing more precision. – yzorg Apr 04 '23 at 15:36
  • `-f` is "format operator" in PowerShell – yzorg Apr 04 '23 at 15:36