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:\>