2

#PSTip Get the size of a file on disk

Note: This tip requires PowerShell 2.0 or above.

In an earlier post, I wrote about compressing / uncompressing files using WMI. Towards the end of that article, the image showed the difference in file size on disk before and after the compression. So, how can we retrieve that value using PowerShell? Let us look at Get-Item and WMI to see if we can retrieve the file size on disk.

compress

In both cases above, we see that the file size is not the actual compressed size on the disk.

So, to retrieve the file size on disk, we need to use a low-level Win32 function called GetCompressedFileSize. There are at least two ways of using this in PowerShell – P/Invoke and .NET Interop Services. Since PowerShell 2.0 and above include the Add-Type cmdlet, let us see how we can use that and .NET interop services to achieve what we want.

add-type -type  @'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Disk
{
    public class SizeInfo
    {
        [DllImport("kernel32.dll", SetLastError=true, EntryPoint="GetCompressedFileSize")]
        static extern uint GetCompressedFileSizeAPI(string lpFileName, out uint lpFileSizeHigh);

        public static ulong GetCompressedFlieSize(string FileName,bool SizeInMB)
        {
            uint HighOrder;
            uint LowOrder;
            LowOrder = GetCompressedFileSizeAPI(FileName, out HighOrder);
            int error = Marshal.GetLastWin32Error();
            if (HighOrder == 0 && LowOrder == 0xFFFFFFFF && error != 0)
                throw new Win32Exception(error);
            else
                if (SizeInMB)
                    return ((((ulong)HighOrder << 32) + LowOrder)/1024)/1024;
                else
                    return ((ulong)HighOrder << 32) + LowOrder;
        }
    }
}
'@

The above snippet will create the Disk.SizeInfo namespace in the current PowerShell session. We can use this namespace to retrieve the file size on disk.

[Disk.SizeInfo]::GetCompressedFlieSize( "C:\scripts\test.vhd",$false)
[Disk.SizeInfo]::GetCompressedFlieSize( "C:\scripts\test.vhd",$true)

If the second parameter is set to $true, the value of the file size will be returned in megabytes.

Filed in: Columns, Tips and Tricks Tags: ,

2 Responses to "#PSTip Get the size of a file on disk"

Leave a Reply

Submit Comment

© 2016 PowerShell Magazine. All rights reserved. XHTML / CSS Valid.
Proudly designed by Theme Junkie.
%d bloggers like this: