I have this one-liner:
get-WmiObject win32_logicaldisk -Computername remotecomputerand 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.
216 Answers
Much simpler solution:
Get-PSDrive C | Select-Object Used,Freeand for remote computers (needs Powershell Remoting)
Invoke-Command -ComputerName SRV2 {Get-PSDrive C} | Select-Object PSComputerName,Used,Free 5 $disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Select-Object Size,FreeSpace
$disk.Size
$disk.FreeSpaceTo extract the values only and assign them to a variable:
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Foreach-Object {$_.Size,$_.FreeSpace} 6 Just one command simple sweet and clean but this only works for local disks
Get-PSDriveYou 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.
2I 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 7 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:'").FreeSpaceAlso 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 ($),($) | write-outputOutput is: Remotecomputer C: has 252.7 GB free of 298.0 GB Total
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 }
} 2 Get-PSDrive C | Select-Object @{ E={$_.Used/1GB}; L='Used' }, @{ E={$_.Free/1GB}; L='Free' } 0 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}} -AutoSizeOutput:
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,562command-line:
wmic logicaldisk where DriveType="3" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpaceout:
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 B80A0F40command-line:
wmic logicaldisk where Caption="C:" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpaceout:
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 3 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.
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> 1 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.
On PowerShell:
"FreeSpace C: " + [math]::Round((Get-Volume -DriveLetter C).SizeRemaining / 1Gb) + " GB" I remote into the computer using Enter-PSsession pcNamethen 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 *
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 1 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.
PowerShell Fun
Get-WmiObject win32_logicaldisk -Computername <ServerName> -Credential $(get-credential) | Select DeviceID,VolumeName,FreeSpace,Size | where {$_.DeviceID -eq "C:"}