Adding SizeOnDisk to FileInfo

The FileInfo object is great, with lots of useful information. But there is one piece of information I miss, and that is the SizeOnDisk information that we are used to from Windows Explorer. Well, let’s do something about that, shall we?

There is actually two parts to getting this “problem” solved. To calculate the size a file takes on disk, we need to know the cluster size of the disk volume. This information are available in the Win32_Volume class in WMI. Ok, great, but since this is a disk/volume-realted piece of information, I feel it doesn’t make sense to add this to FileInfo. But there is another object where it DO belong; the PSDriveInfo object.

So there is in fact two object types we need to extend. First we need to add the block size to PSDriveInfo, and then update FileInfo to use this info to calculate the size on disk value.

It’s really not much to it, but I have done the heavy lifting for you. Just copy/paste the following two functions to your PowerShell profile, and you will always have BlockSize and SizeOnDisk available when working with drives and files. (Remember to also run the functions :))


function Update-PSDriveInfoType {
<#
Update PSDriveInfo type to include BlockSize
Author: Øyvind Kallstad
#>
$typeData = Get-TypeData System.Management.Automation.PSDriveInfo
$scriptBlock = {
if ($this.Provider.ImplementingType -eq [Microsoft.PowerShell.Commands.FileSystemProvider]) {
$driveRoot = ([System.IO.DirectoryInfo] $this.Root).Name.Replace('\','\\')
(Get-WmiObject Query "SELECT BlockSize FROM Win32_Volume WHERE Name='$driveRoot'").BlockSize
}
}
$scriptProperty = New-Object System.Management.Automation.Runspaces.ScriptPropertyData 'BlockSize', $scriptBlock
if (-not($typeData.Members['BlockSize'])) {
$typeData.Members.Add('BlockSize', $scriptProperty)
}
Update-TypeData $typeData Force
}


function Update-FileInfoType {
<#
Update FileInfo type to include SizeOnDisk
Author: Øyvind Kallstad
#>
$typeData = Get-TypeData System.IO.FileInfo
$scriptBlock = {
$blockSize = $this.PSDrive.BlockSize
$size = $this.Length
[math]::Ceiling($size/$blockSize) * $blockSize
}
$scriptProperty = New-Object System.Management.Automation.Runspaces.ScriptPropertyData 'SizeOnDisk', $scriptBlock
if (-not($typeData.Members['SizeOnDisk'])) {
$typeData.Members.Add('SizeOnDisk', $scriptProperty)
}
Update-TypeData $typeData Force
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s