I don't know what files you have in your App-V folder, so I created a few files in a test folder to examine.
I found 2 issues. The first is that really small files don't occupy any space. Their data is stored in the MFT. Explorer properties show 0 bytes for size on disk.
The second issue is for files that have been compressed. You can set the explorer options to have them show in blue.
I found a StackOverflow article that demonstrated how to call GetCompressedFileSizeW. That works for compressed files, but the only way that I found to find the MFT resident files was to call fsutil and look for the number of extents.
This was tested on Win11.
# Source: https://stackoverflow.com/questions/22507523/getting-size-on-disk-for-small-files-in-powershell
add-type -type @'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.IO;
namespace Win32Functions
{
public class ExtendedFileInfo
{
public static long GetFileSizeOnDisk(string file)
{
FileInfo info = new FileInfo(file);
uint dummy, sectorsPerCluster, bytesPerSector;
int result = GetDiskFreeSpaceW(info.Directory.Root.FullName, out sectorsPerCluster, out bytesPerSector, out dummy, out dummy);
if (result == 0) throw new Win32Exception();
uint clusterSize = sectorsPerCluster * bytesPerSector;
uint hosize;
uint losize = GetCompressedFileSizeW(file, out hosize);
long size;
size = (long)hosize << 32 | losize;
return ((size + clusterSize - 1) / clusterSize) * clusterSize;
}
[DllImport("kernel32.dll")]
static extern uint GetCompressedFileSizeW([In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
[Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh);
[DllImport("kernel32.dll", SetLastError = true, PreserveSig = true)]
static extern int GetDiskFreeSpaceW([In, MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName,
out uint lpSectorsPerCluster, out uint lpBytesPerSector, out uint lpNumberOfFreeClusters,
out uint lpTotalNumberOfClusters);
}
}
'@
function Get-FolderSizEOnDisk {
param (
[Parameter(Mandatory = $true)]
[string]$path
)
$ap = (Resolve-Path $path).Path
$ite = Get-Item $ap
$volume = Get-Volume $ite.PSDrive.Name
$cSize = $volume.AllocationUnitSize
$defaultCS = 4096
$totalSizeOnDisk = 0
$filecount =0
$defaultcount = 0
$failedcount = 0
Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue | ForEach-Object {
try {
$size = $_.Length
if($null -ne $size -and $size -gt 0)
{
# $cl = [math]::Ceiling($size / $cSize)
# $SizeOnDisk = $cl * $cSize
$SizeOnDisk = [Win32Functions.ExtendedFileInfo]::GetFileSizeOnDisk( $_.FullName)
if ($size -lt 1024) { # really small files can be stored in the MFT
$fsu = fsutil file queryExtents "$($_.FullName)"
if ($fsu.contains("No extents")) {
$SizeOnDisk = 0 # data stored in MFT
}
}
$totalSizeOnDisk += $SizeOnDisk
$filecount++
"{0} - {1} - {2}" -f $size, $SizeOnDisk, $_.Name
}
else {
$totalSizeOnDisk += $defaultCS
$defaultcount++
}
} catch {
$failedcount++
}
}
$folderCount = (Get-ChildItem -Path $path -Recurse -Directory -ErrorAction SilentlyContinue).Count
[PSCustomObject]@{
Folder =$ap
Files = $filecount
defaultLength_Zero = $defaultcount
FailedFiles = $failedcount
Folders = $folderCount
SizeOnDisk = $totalSizeOnDisk
SizeOnDiskKB =[math]::Round($totalSizeOnDisk / 1KB, 2)
SizeOnDiskGB =[math]::Round($totalSizeOnDisk / 1GB, 2)
SizeOnDiskMB =[math]::Round($totalSizeOnDisk / 1MB, 2)
}
}
Get-FolderSizEOnDisk "C:\Temp\store"