Display Disk Size and FreeSpace in GB - powershell

Is there one line of code that will display free-size and disk-space of your logical disk in gb instead of mb? I tried doing some research but I couldn't find one liner, I did give this an attempt which was to divide it by 1GB, but that didn't work, how can I accomplish this?
gwmi win32_logicaldisk | Format-Table DeviceId, MediaType,Size,FreeSpace /1GB

Try calculated properties. I would also add [math]::Round() to shorten the values:
gwmi win32_logicaldisk | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
n stands for name and e for expression. You could use the full names too, but it's a waste of space if you're writing multiple calculated Properties.

When performing any arithmetical calculation, it should be put in { }.
gwmi win32_logicaldisk | Format-Table DeviceId, MediaType,Size, {$_.FreeSpace /1GB}
You can read more on syntax from Microsoft Powershell Library

I'd like to provide an alternate/updated answer. (As of Powershell 5 at least, probably version 3.)
Just use Get-Volume
https://learn.microsoft.com/en-us/powershell/module/storage/get-volume
Example:
> get-volume
DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining Size
----------- ------------ -------------- --------- ------------ ----------------- ------------- ----
FAT32 Fixed Healthy OK 451 MB 496 MB
C OSDISK NTFS Fixed Healthy OK 65.23 GB 474.3 GB
X Transfer_Shuttle NTFS Fixed Healthy OK 37.65 GB 48.68 GB

I have same issue and I want get KB,MB,GB,TB,PB on Server with Windows Server 2008 to 2016,
then I google many information to build a function:
function ConvertDoubleToBytes([double]$srcDouble){
if([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 0){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " Bytes")
} elseif ([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 1){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " KB")
} elseif ([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 2){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " MB")
} elseif ([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 3){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " GB")
} elseif ([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 4){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " TB")
} elseif ([Math]::Floor([Math]::Log($srcDouble,1024)) -eq 5){
$resn = ([Math]::Ceiling($srcDouble/([math]::pow(1024,([Math]::Floor([Math]::Log($srcDouble,1024)))))).ToString() + " PB")
}
return $resn
}
And I use it:
Get-WmiObject -query "Select * from win32_logicaldisk " | Select-Object DeviceID,#{n="FreeSpace";e={ConvertDoubleToBytes($([double]::Parse($_.FreeSpace)))}},#{n="Size";e={ConvertDoubleToBytes($([double]::Parse($_.Size)))}},#{n="Useage Percent";e={$([Math]::Ceiling((1-$($([double]::Parse($_.FreeSpace))/$([double]::Parse($_.Size))))*100)).ToString() + " %"}}
Will print like this:
DeviceID FreeSpace Size Useage Percent
-------- --------- ---- --------------
C: 36 GB 100 GB 65 %
D: 294 GB 600 GB 52 %
E:
F: 279 GB 600 GB 54 %
G:
H: 500 GB 500 GB 1 %

This works great.
$disks = get-wmiobject Win32_LogicalDisk -computername $computer -Filter "DriveType = 3"
foreach ($disk in $disks) {
$letter = $disk.deviceID
$volumename = $disk.volumename
$totalspace = [math]::round($disk.size / 1GB, 2)
$freespace = [math]::round($disk.freespace / 1GB, 2)
$usedspace = [math]::round(($disk.size - $disk.freespace) / 1GB, 2)
$disk | Select-Object #{n = "Computer Name"; e = { $computer } }, #{n = "Disk Letter"; e = { $letter } }, #{n = "Volume Name"; e = { $volumename } }, #{n = "Total Space"; e = { ($totalspace).tostring() + " GB" } }, #{n = "Free Space"; e = { ($freespace).tostring() + " GB" } }, #{n = "Used Space"; e = { ($usedspace).tostring() + " GB" } } | FT
}

Related

condition in powershell - disk usage

I made a powershell script that displays the disk size and free space in GB and percent.
How to make a condition here, so that after reaching 51%, a message is displayed that there is not enough space?
$props = #(
'DriveLetter'
#{
Name = 'SizeRemaining'
Expression = { "{0:N2} GB" -f ($_.SizeRemaining/ 1Gb) }
}
#{
Name = 'Size'
Expression = { "{0:N2} GB" -f ($_.Size / 1Gb) }
}
#{
Name = '% Free'
Expression = { "{0:P}" -f ($_.SizeRemaining / $_.Size) }
}
)
Get-Volume -DriveLetter C | Select-Object $props
if ( $_.SizeRemaining -lt 50 )
{
Write-Host "warning"
}
else {
Write-Host ("ok")
}
You could just add another property to your output with the warning message in it. For example, add a Status property like this:
$props = #(
'DriveLetter',
#{
Name = 'SizeRemaining'
Expression = { "{0:N2} GB" -f ($_.SizeRemaining/ 1Gb) }
},
#{
Name = 'Size'
Expression = { "{0:N2} GB" -f ($_.Size / 1Gb) }
},
#{
Name = '% Free'
Expression = { "{0:P}" -f ($_.SizeRemaining / $_.Size) }
},
#{
Name = 'Status'
Expression = { if(($_.SizeRemaining / $_.Size) -lt 0.5){"Low"}else{"OK"} }
}
)
So, you can just do this to see all the information at once:
Get-Volume -DriveLetter C | Select-Object $props | Format-Table -AutoSize
Which gives output like this:
DriveLetter SizeRemaining Size % Free Status
----------- ------------- ---- ------ ------
C 121.33 GB 464.14 GB 26.14% Warning
As it's just another property, you can access/manipulate it like any other property. For example, if you had lots of volumes on the system, you could just show the one with low space like this:
Get-Volume |
Select-Object $props |
Where-Object Status -eq 'Warning' |
Format-Table -AutoSize

calculate free disk space percentage powershell

I am trying to get the free percentage like present in Disk Management
$Diskmgmt = Get-Volume | select DriveLetter,FileSystemLabel,FileSystem,DriveType,HealthStatus,OperationalStatus,SizeRemaining,Size
foreach($dsk in $Diskmgmt)
{
$dl = $dsk.DriveLetter
$fsl = $dsk.FileSystemLabel
$fs = $dsk.FileSystem
$dt = $dsk.DriveType
$hs = $dsk.HealthStatus
$os = $dsk.OperationalStatus
$sizer = [math]::round($dsk.SizeRemaining /1Gb, 2)
$siz = [math]::round($dsk.Size /1Gb, 2)
$PercentFree = [Math]::Round(($sizer / $siz) * 100, 2)
but the calculation coming like below
Capacity Free Space %Free
154.82 GB 200 GB 77 %
0 GB 0 GB 77 %
1.96 GB 6 GB 33 %
0.15 GB 0.49 GB 31 %
52.32 GB 99.51 GB 53 %
11.19 GB 11.23 GB 100 %
9.95 GB 10 GB 99 %
Please let me know if I am doing it correctly.
I'm guessing you're looking for something like this:
$props = #(
'DriveLetter'
'FileSystemLabel'
'FileSystem'
'DriveType'
'HealthStatus'
'OperationalStatus'
#{
Name = 'SizeRemaining'
Expression = { "{0:N3} Gb" -f ($_.SizeRemaining/ 1Gb) }
}
#{
Name = 'Size'
Expression = { "{0:N3} Gb" -f ($_.Size / 1Gb) }
}
#{
Name = '% Free'
Expression = { "{0:P}" -f ($_.SizeRemaining / $_.Size) }
}
)
Get-Volume -DriveLetter C, D | Select-Object $props | Format-Table
As an example this is how it looks on my laptop for Drives C and D:
DriveLetter FileSystemLabel FileSystem DriveType HealthStatus OperationalStatus SizeRemaining Size % Free
----------- --------------- ---------- --------- ------------ ----------------- ------------- ---- ------
D NTFS Fixed Healthy OK 748.731 Gb 931.512 Gb 80.38%
C NTFS Fixed Healthy OK 170.959 Gb 236.764 Gb 72.21%
Using get-psdrive and the 'p' format specifier:
get-psdrive c | % { $_.free/($_.used + $_.free) } | % tostring p
9.24%

Combine `Get-Disk` info and `LogicalDisk` info in PowerShell (but with formatted output)

This is a question about an answer for this Combine `Get-Disk` info and `LogicalDisk` info in PowerShell?
Here is the answer which I've tried to change to get the output formatted how I want it:
https://stackoverflow.com/a/31092004/8262102
It needs to work for multiple drives like the code below only in the desired format.
This is the code with all the details on what my attempts are to do so:
$info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | ForEach-Object {
$disk = $_
$partitions = "ASSOCIATORS OF " + "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
Get-WmiObject -Query $partitions | ForEach-Object {
$partition = $_
$drives = "ASSOCIATORS OF " + "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + "WHERE AssocClass = Win32_LogicalDiskToPartition"
Get-WmiObject -Query $drives | ForEach-Object {
[PSCustomObject][Ordered]#{
Disk = $disk.DeviceID
DiskModel = $disk.Model
Partition = $partition.Name
RawSize = '{0:d} GB' -f [int]($partition.Size/1GB)
DriveLetter = $_.DeviceID
VolumeName = $_.VolumeName
Size = '{0:d} GB' -f [int]($_.Size/1GB)
FreeSpace = '{0:d} GB' -f [int]($_.FreeSpace/1GB)
}
}
}
}
# Here's my attempt at formatting the output of the code above.
# 1. This trims the dead whitespace from the output.
$info_diskdrive_basic = ($info_diskdrive_basic | Out-String) -replace '^\s+|\s+$', ('')
# 2. I then separate the DiskModel, RawSize, DriveLetter, VolumeName, FreeSpace with the regexp below so this becomes:
# Disk Model, Raw Size, Drive Letter, Volume Name, Free Space
$info_diskdrive_basic = ($info_diskdrive_basic) -replace '(?-i)(?=\B[A-Z][a-z])', (' ')
# 3. Here I then format the string to how I want:
$info_diskdrive_basic = ($info_diskdrive_basic) -replace '(.+?)(\s+):\s*(?!\S)', ($id2 + '$1:$2 ')
$info_diskdrive_basic
The output should look like this:
I want to format the properties and the values like so: Properties: >spaces< value where the value is over to the right and aligned along the left of them
# Disk: \\.\PHYSICALDRIVE0
# Disk Model: Crucial_CT512MX100SSD1
# Partition: Disk #0, Partition #2
# Raw Size: 476 GB
# Drive Letter: C:
# Volume Name:
# Size: 476 GB
# Free Space: 306 GB
But my output ends up like this: (Notice how the text is not aligned)
# Disk: \\.\PHYSICALDRIVE0
# Disk Model: Crucial_CT512MX100SSD1
# Partition: Disk #0, Partition #2
# Raw Size: 476 GB
# Drive Letter: C:
# Volume Name:
# Size: 476 GB
# Free Space: 306 GB
To output the info as you apparently need, we need to know the maximum line length (which in your example is 79 characters) and work our way from that.
$maxLineLength = 79 # counted from the longest line in your example
$maxValueLength = 0 # a counter to keep track of the largest value length in characters
$info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | ForEach-Object {
$disk = $_
$partitions = "ASSOCIATORS OF " + "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
Get-WmiObject -Query $partitions | ForEach-Object {
$partition = $_
$drives = "ASSOCIATORS OF " + "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + "WHERE AssocClass = Win32_LogicalDiskToPartition"
Get-WmiObject -Query $drives | ForEach-Object {
$obj = [PSCustomObject]#{
'Disk' = $disk.DeviceID
'Disk Model' = $disk.Model
'Partition' = $partition.Name
'Raw Size' = '{0:d} GB' -f [int]($partition.Size/1GB)
'Drive Letter' = $_.DeviceID
'Volume Name' = $_.VolumeName
'Size' = '{0:d} GB' -f [int]($_.Size/1GB)
'Free Space' = '{0:d} GB' -f [int]($_.FreeSpace/1GB)
}
# get the maximum length for all values
$len = ($obj.PsObject.Properties.Value.ToString().Trim() | Measure-Object -Property Length -Maximum).Maximum
$maxValueLength = [Math]::Max($maxValueLength, $len)
# output the object to be collected in $info_diskdrive_basic
$obj
}
}
}
# sort the returned array of objects on the DriveLetter property and loop through
$result = $info_diskdrive_basic | Sort-Object DriveLetter | ForEach-Object {
# loop through all the properties and calculate the padding needed for the output
$_.PsObject.Properties | ForEach-Object {
$label = '# {0}:' -f $_.Name.Trim()
$padding = $maxLineLength - $maxValueLength - $label.Length
# output a formatted line
"{0}{1,-$padding}{2}" -f $label, '', $_.Value.ToString().Trim()
}
# add a separator line between the disks
''
}
# output the result on screen
$result
# write to disk
$result | Set-Content -Path 'X:\theResult.txt'
# format for HTML mail:
'<pre>{0}</pre>' -f ($result -join '<br>')
Example output:
# Disk: \\.\PHYSICALDRIVE1
# Disk Model: Samsung SSD 750 EVO 250GB
# Partition: Disk #1, Partition #0
# Raw Size: 232 GB
# Drive Letter: C:
# Volume Name: System
# Size: 232 GB
# Free Space: 160 GB
# Disk: \\.\PHYSICALDRIVE2
# Disk Model: WDC WD7501AALS-00J7B0
# Partition: Disk #2, Partition #0
# Raw Size: 699 GB
# Drive Letter: D:
# Volume Name: Data
# Size: 699 GB
# Free Space: 385 GB
P.S. with creating [PsCustomObject], there is no need to add [Ordered]
Using your posted code as is, 'stringify' your properties
For example:
($info_diskdrive_basic = Get-WmiObject Win32_DiskDrive |
ForEach-Object {
$disk = $_
$partitions = "ASSOCIATORS OF " +
"{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " +
"WHERE AssocClass = Win32_DiskDriveToDiskPartition"
Get-WmiObject -Query $partitions |
ForEach-Object {
$partition = $_
$drives = "ASSOCIATORS OF " +
"{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " +
"WHERE AssocClass = Win32_LogicalDiskToPartition"
Get-WmiObject -Query $drives |
ForEach-Object {
[PSCustomObject][Ordered]#{
Disk = "$($disk.DeviceID)"
DiskModel = "$($disk.Model)"
Partition = "$($partition.Name)"
RawSize = "$('{0:d} GB' -f [int]($partition.Size/1GB))"
DriveLetter = "$($_.DeviceID)"
VolumeName = "$($_.VolumeName)"
Size = "$('{0:d} GB' -f [int]($_.Size/1GB))"
FreeSpace = "$('{0:d} GB' -f [int]($_.FreeSpace/1GB))"
}
}
}
})
# Results
<#
Disk : \\.\PHYSICALDRIVE0
DiskModel : Samsung SSD 950 PRO 512GB
Partition : Disk #0, Partition #0
RawSize : 477 GB
DriveLetter : D:
VolumeName : Data
Size : 477 GB
FreeSpace : 364 GB
...
#>
Point of note:
I am using PowerShell variable squeezing to assign the results to the variable and output to the screen at the same time.
Update
As for this...
"I want to format the properties and the values like so: Properties: >spaces< value"
$Spacer = ("`t")*8
($info_diskdrive_basic = Get-WmiObject Win32_DiskDrive |
ForEach-Object {
$disk = $_
$partitions = "ASSOCIATORS OF " +
"{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " +
"WHERE AssocClass = Win32_DiskDriveToDiskPartition"
Get-WmiObject -Query $partitions |
ForEach-Object {
$partition = $_
$drives = "ASSOCIATORS OF " +
"{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " +
"WHERE AssocClass = Win32_LogicalDiskToPartition"
Get-WmiObject -Query $drives |
ForEach-Object {
[PSCustomObject][Ordered]#{
Disk = "$Spacer$($disk.DeviceID)"
DiskModel = "$Spacer$($disk.Model)"
Partition = "$Spacer$($partition.Name)"
RawSize = "$Spacer$('{0:d} GB' -f [int]($partition.Size/1GB))"
DriveLetter = "$Spacer$($PSItem.DeviceID)"
VolumeName = "$Spacer$($PSItem.VolumeName)"
Size = "$Spacer$('{0:d} GB' -f [int]($PSItem.Size/1GB))"
FreeSpace = "$Spacer$('{0:d} GB' -f [int]($PSItem.FreeSpace/1GB))"
}
}
}
})
# Results
<#
Disk : \\.\PHYSICALDRIVE0
DiskModel : Samsung SSD 950 PRO 512GB
Partition : Disk #0, Partition #0
RawSize : 477 GB
DriveLetter : D:
VolumeName : Data
Size : 477 GB
FreeSpace : 364 GB
...
#>

Retrieving disk capacity with powershell

I made this code to count disk capacity, but when i run it with only the SSD in my laptop i get 0GB. after I insert USB/external space it count the ssd + the USB.
$disk = Get-WmiObject Win32_DiskDrive
$capacity = 0;
for($i = 0;$i -lt $disk.Count; $i++){
$capacity = $capacity + [math]::round(($disk[$i].Size/1GB),2)
}
Write-Host $capacity "GB"
This works fine -> $disk.Size
Why does it not take the first [0] in my for loop?
I cannot answer why your for loop is failing without observing your environment, but there is almost never a use-case for it. You should instead opt for a foreach loop:
$capacity = foreach ($disk in Get-WmiObject -Class Win32_DiskDrive)
{
[Math]::Round(($disk.Size / 1GB), 2)
}
"$(($capacity | Measure-Object -Sum).Sum)GB"
Assuming Windows 10 since you didn't mention OS and the CMDLETS in Windows 10 are so much better. *See at the bottom for a Windows 7 version.
For disk information, I prefer using Get-PhysicalDisk, like this for example:
$DiskInfo = foreach ($disk in Get-PhysicalDisk) {
[string]$name = $disk.FriendlyName
[string]$type = $disk.MediaType
[int]$capacity = $disk.size / 1GB
[pscustomobject]#{
"Type"=$type;
"Name"=$name;
"Capacity (GB)"=$capacity;
}
}
$DiskInfo
In my environement where I have one SSD and one mechanical HDD, it will return:
Name Type Capacity (GB)
---- ---- -------------
SAMSUNG MZ7TY256HDHP-000L7 SSD 238
ST500LX025-1U717D HDD 466
If you wanted information for JUST the SSD for example, you could do this :
$DiskInfo = foreach ($disk in Get-PhysicalDisk | Where-Object {$_.MediaType -eq "SSD"} ) {
[string]$name = $disk.FriendlyName
[string]$type = $disk.MediaType
[int]$capacity = $disk.size / 1GB
[pscustomobject]#{
"Type"=$type;
"Name"=$name;
"Capacity (GB)"=$capacity;
}
}
$DiskInfo
Which returns only the SSD:
Type Name Capacity (GB)
---- ---- -------------
SSD SAMSUNG MZ7TY256HDHP-000L7 238
Explanation: Foreach disk connected, store name, media type and capacity in variables. *Divide byte capacity by 1GB to get a better number to look at.
Still in the Foreach, create a custom object at every iteration containing the 3 variables.
All put together, you can then output your variable DiskInfo which contains all the objects.
If on Windows 7, media type isn't available so you can't use it. Instead you can do:
$DiskInfo = foreach ($disk in Get-WmiObject -Class Win32_DiskDrive) {
[string]$name = $disk.model
[int]$capacity = $disk.size / 1GB
[pscustomobject]#{
"Name"=$name;
"Capacity (GB)"=$capacity;
}
}
$DiskInfo
Which will return something like:
Name Capacity (GB)
---- -------------
SAMSUNG MZ7TY256HDHP-000L7 238
ST500LX025-1U717D 466

I want to add Used space column in my powershell script?

I want to make some changes to below script .
try{
$space = Get-WmiObject Win32_logicaldisk `
| Format-Table DeviceID,`
#{Name="Size(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb))}}, `
#{Name="Free Space(GB)";Expression={[decimal]("{0:N0}" -f($_.freespace/1gb))}}, `
#{Name="Free (%)";Expression={"{0,6:P0}" -f(($_.freespace/1gb) / ($_.size/1gb))}} `
-AutoSize
}
catch
{
echo "Exception Occurred. Please try again on $servername"
}
echo "The total space on $servername are given below:"
echo $space
I want to add a column which shows used space without any changes to output format.
output is below:
The total space on are given below:
DeviceID Size(GB) Free Space(GB) Free (%)
-------- -------- -------------- --------
A: 0 0
C: 60 41 69 %
D: 100 78 78 %
E: 200 190 95 %
G: 0 0
You can extend the table as follows
try
{
$space = Get-WmiObject Win32_logicaldisk | Format-Table DeviceID,
#{Name="Size(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb))}},
#{Name="Free Space(GB)";Expression={[decimal]("{0:N0}" -f($_.freespace/1gb))}},
#{Name="Free (%)";Expression={"{0,6:P0}" -f(($_.freespace/1gb) / ($_.size/1gb))}},
#{Name="Used Space(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb - $_.freespace/1gb))}},
#{Name="Used Space (%)";Expression={"{0,6:P0}" -f(($_.size/1gb - $_.freespace/1gb) / ($_.size/1gb))}}
-AutoSize
}
catch
{
echo "Exception Occurred. Please try again on $servername"
}
echo "The total space on $servername are given below:"
echo $space
I found the answer myself,refer to below code:
$servername = hostname
#checking for disk space
try{
$space = Get-WmiObject Win32_logicaldisk `
| Format-Table DeviceID,`
#{Name="Size(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb))}}, `
#{Name="Free Space(GB)";Expression={[decimal]("{0:N0}" -f($_.freespace/1gb))}}, `
#{Name="Used Space(GB)";Expression={[decimal]("{0:N0}" -f(($_.size/1gb) - ($_.freespace/1gb)))}}, `
#{Name="Free (%)";Expression={"{0,6:P0}" -f(($_.freespace/1gb) / ($_.size/1gb))}} `
-AutoSize
}
catch
{
echo "Exception Occurred. Please try again on $servername"
}
echo "The total space on $servername are given below:"
echo $space
The desired result required was :
The total space on sw02014 are given below:
DeviceID Size(GB) Free Space(GB) Used Space(GB) Free (%)
-------- -------- -------------- -------------- --------
A: 0 0 0
C: 60 41 18 69 %
D: 100 78 22 78 %
E: 200 190 10 95 %
G: 0 0 0