Posted on 10th February 2017

If you right click a file or folder in windows and look at it properties you will find there are two size properties - Size and Size on Disk. Size is the actual size of the file in bytes and Size on disk is the disk space required to store that file. The two sizes can be the same in some cases or it could be hugely different especially if its a sparse file or if its a compressed file that is stored in a volume that supports compression.

To get the size of a file in PowerShell you just have to run the Get-Item command

PS C:\Users\> Get-Item export.sql Directory: C:\Users Mode LastWriteTime Length Name ---- ------------- ------ ---- -a--- 23/01/2017 15:25 177331 export.sql

There isn't any single command or cmdlets that gives you the size on disk of a file, however we could achieve this with .Net Platform Invoke (P/Invoke) feature and the PowerShell Add-Type cmdlet.

First you create a .NET class that finds the actual size on disk of a file. Inside this class you will use the Win32 function GetCompressedFileSizeW to which returns the size in bytes used to store a file.

The Add-Type cmdlet is used to add the class to your PowerShell session. Finally get each file from the specfied directory and call the function in .Net class you created with full file name as paramater.

Here is the full script:

Script: Get-FileSizeOnDisk.ps1

<# .SYNOPSIS Powershell script to get file size and size on disk of all files in a directory. .DESCRIPTION This PowerShell script gets file size and size on disk in bytes of all files in a directory. .PARAMETER <path> Directory path of the files to check. If this parameter is not specified the default value is current directory. .NOTES Version: 1.0 Author: Open Tech Guides Creation Date: 06-Feb-2017 .LINK www.opentechguides.com .EXAMPLE Get-FileSizeOnDisk c:\myfolder #> param ( [string]$path='.' ) $source = @" using System; using System.Runtime.InteropServices; using System.ComponentModel; using System.IO; namespace Win32 { public class Disk { [DllImport("kernel32.dll")] static extern uint GetCompressedFileSizeW([In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName, [Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh); public static ulong GetSizeOnDisk(string filename) { uint HighOrderSize; uint LowOrderSize; ulong size; FileInfo file = new FileInfo(filename); LowOrderSize = GetCompressedFileSizeW(file.FullName, out HighOrderSize); if (HighOrderSize == 0 && LowOrderSize == 0xffffffff) { throw new Win32Exception(Marshal.GetLastWin32Error()); } else { size = ((ulong)HighOrderSize << 32) + LowOrderSize; return size; } } } } "@ Add-Type -TypeDefinition $source $result = @() Get-ChildItem $path | Where-Object { ! $_.PSIsContainer} | Foreach-Object { $size = [Win32.Disk]::GetSizeOnDisk($_.FullName) $obj = New-Object PSObject Add-Member -InputObject $obj -MemberType NoteProperty -Name "File Name" -Value $_.Name Add-Member -InputObject $obj -MemberType NoteProperty -Name "Size" -Value $_.Length Add-Member -InputObject $obj -MemberType NoteProperty -Name "Size on Disk" -Value $size $result += $obj } write-output $result

Sample output

PS C:\> Get-FileSizeOnDisk.ps1 C:\Users File Name Size Size on Disk --------- ---- ------------ export.sql 177331 45056 PS C:\>