Skip to main content

Use PowerShell to see how much file space on the hard drive is unusable because of the block size.

Modern hard drives are divided into blocks.  These blocks can be of various sizes.  512K, 1024K.  The issue that can develop is that once a block contains the data of a file, the unused portion of that block cannot store an other data.  So for example, if you save a 768K file onto a hard drive containing 512K blocks, your file will consume 1024K.  256K will be unusable space.  This script will show you how much space is being wasted.

 

This script is a quick demo based on a question that popped up in class.  Utilizing FRSM quotas, I set a folder with a hard quota of 6KB.  I then copied a file of 2KB into the folder.  When I copied the same file in again, Windows stated that I exceeded my quota.  Well, logically 2 KB + 2 KB = 4 KB.  My quota was 6 KB.

Upon further analysis, we discovered that the file size was actually a few kilobytes larger than 2.5 K.  That means that on my hard drive with block sizes of 512K, we were using 6 blocks or 3 KB.  The second file fit the limit and we received an error.

 

This script is designed to be dot sourced into the shell environment of PowerShell.

  

<#
.SYNOPSIS
Returns the amount of space that is unused in the files blocks.

.DESCRIPTION
Returns the amount of space that is not available to be
used on the hard drive due to the blocki size on the hard drives.
If a file only uses part of a block, the rest of the block cannot
be used for another file.

.PARAMETER Recurse
Performs a recursive search using the current location
in the file system as the root.

.EXAMPLE
Get-WastedSpace -Recurse

Returns the wasted space on the hard drive based on the
current location in the file system as the root of the search.
#>

function Get-WastedDriveSpace
{
Param
(
[
Switch]$Recurse
)

# Get the Disk Partition information
$DiskPartition = Get-WmiObject Win32_DiskPArtition |
Select-Object -Property BlockSize

# Get the logical disk information
$LogicalDisk = Get-WmiObject Win32_LogicalDIsk |
Select-object -Property Name

If ($Recurse)
{
$Files = Get-ChildItem -Recurse |
Select-Object -Property length, PSDrive

}
Else
{
$Files = Get-ChildItem |
Select-Object -Property length, PSDrive
}


$DriveObj = @()
$Counter = 0
forEach ($Disk in $LogicalDisk)
{
$DriveInfo = New-Object PSObject
$DriveInfo | Add-Member NoteProperty -Name Name -Value ($Disk.Name).Replace(":","")
$DriveInfo | Add-Member NoteProperty -Name BlockSize $DiskPartition[$Counter].BlockSize
$DriveInfo | Add-Member NoteProperty -Name TotalFileSize -Value 0
$DriveInfo | Add-Member NoteProperty -Name TotalBlocksUsed -Value 0
$DriveInfo | Add-Member NoteProperty -Name SizeOfBlocks -value 0
$DriveInfo | Add-Member NoteProperty -Name WastedSpaceMB -Value 0

$DriveObj += $DriveInfo
$Counter++

}
# End: for Each ($File in $Files)

ForEach ($File in $Files)
{

ForEach ($Drive in $DriveObj)
{

If ($File.PSDrive -like $Drive.Name)
{
$Drive.TotalFileSize += $File.Length
$Drive.TotalBlocksUsed += [int]($File.Length/$Drive.BlockSize)
$Drive.SizeOfBlocks += ($Drive.TotalBlocksUsed * $Drive.BlockSize)


}
}
# End: ForEach ($Drive in $DriveObj)

}
# End: ForEach ($File in $Files)

# Calculate the Wasted Space.
ForEach ($Drive in $DriveObj)
{
$Drive.WastedSpaceMB = ($Drive.SizeOfBlocks - $Drive.TotalFileSize) / 1mb

}
# End: ForEach ($Drive in $DriveObj)

# Write the object to the pipline
Write-Output $DriveObj
}
# End: Get-WastedDriveSpace

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.