# listBigFilesAndFolders-v0.01.ps1
# Set variables
$parentDirectory="C:\"
$depth=4
$topX=10
$excludeDirectories="C:\Windows","C:\Program Files","C:\Program Files (x86)"
$clusterSizeOfNetworkShare=8192
# Sanitize
if($depth -le 1){$depth=1}
################################## Excuting Program as an Administrator ####################################
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "Black"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess);
# Exit from the current, unelevated, process
exit
}
Write-Host -NoNewLine "Running as Administrator..."
function addSystemPrivilege{
param(
[String[]]$privileges=@("SeBackupPrivilege","SeRestorePrivilege")
)
function includeSystemPrivileges{
$win32api = @'
using System;
using System.Runtime.InteropServices;
namespace SystemPrivilege.Win32API
{
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public UInt32 LowPart;
public Int32 HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public UInt32 Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public LUID Luid;
public UInt32 Attributes;
}
public class Privileges
{
public const UInt32 DELETE = 0x00010000;
public const UInt32 READ_CONTROL = 0x00020000;
public const UInt32 WRITE_DAC = 0x00040000;
public const UInt32 WRITE_OWNER = 0x00080000;
public const UInt32 SYNCHRONIZE = 0x00100000;
public const UInt32 STANDARD_RIGHTS_ALL = (
READ_CONTROL |
WRITE_OWNER |
WRITE_DAC |
DELETE |
SYNCHRONIZE
);
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000u;
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000u;
public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001u;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002u;
public const UInt32 SE_PRIVILEGE_REMOVED = 0x00000004u;
public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000u;
public const UInt32 TOKEN_QUERY = 0x00000008;
public const UInt32 TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x00000001u;
public const UInt32 TOKEN_DUPLICATE = 0x00000002u;
public const UInt32 TOKEN_IMPERSONATE = 0x00000004u;
public const UInt32 TOKEN_QUERY_SOURCE = 0x00000010u;
public const UInt32 TOKEN_ADJUST_GROUPS = 0x00000040u;
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x00000080u;
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x00000100u;
public const UInt32 TOKEN_READ = (
STANDARD_RIGHTS_READ |
TOKEN_QUERY
);
public const UInt32 TOKEN_ALL_ACCESS = (
STANDARD_RIGHTS_REQUIRED |
TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE |
TOKEN_IMPERSONATE |
TOKEN_QUERY |
TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID
);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr GetCurrentThread();
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, UInt32 BufferLengthInBytes, IntPtr PreviousStateNull, IntPtr ReturnLengthInBytesNull);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool OpenThreadToken(IntPtr ThreadHandle, UInt32 DesiredAccess, bool OpenAsSelf, out IntPtr TokenHandle);
[DllImport("ntdll.dll", EntryPoint = "RtlAdjustPrivilege")]
public static extern int RtlAdjustPrivilege(
UInt32 Privilege,
bool Enable,
bool CurrentThread,
ref bool Enabled
);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
//
//
private static LUID LookupPrivilege(string privilegeName)
{
LUID privilegeValue = new LUID();
bool res = LookupPrivilegeValue(null, privilegeName, out privilegeValue);
if (!res)
{
throw new Exception("Error: LookupPrivilegeValue()");
}
return privilegeValue;
}
//
//
public static void AdjustPrivilege(string privilegeName, bool enable)
{
IntPtr accessToken = IntPtr.Zero;
bool res = false;
try
{
LUID privilegeValue = LookupPrivilege(privilegeName);
res = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, false, out accessToken);
if (!res)
{
res = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out accessToken);
if (!res)
{
throw new Exception("Error: OpenProcessToken()");
}
}
TOKEN_PRIVILEGES tokenPrivileges = new TOKEN_PRIVILEGES();
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Luid = privilegeValue;
if (enable)
{
tokenPrivileges.Attributes = SE_PRIVILEGE_ENABLED;
}
else
{
tokenPrivileges.Attributes = 0;
}
res = AdjustTokenPrivileges(accessToken, false, ref tokenPrivileges, (uint)System.Runtime.InteropServices.Marshal.SizeOf(tokenPrivileges), IntPtr.Zero, IntPtr.Zero);
if (!res)
{
throw new Exception("Error: AdjustTokenPrivileges()");
}
}
finally
{
if (accessToken != IntPtr.Zero)
{
CloseHandle(accessToken);
accessToken = IntPtr.Zero;
}
}
}
}
}
'@
if ([object]::Equals(('SystemPrivilege.Win32API.Privileges' -as [type]), $null)) {
Add-Type -TypeDefinition $win32api
}
}
includeSystemPrivileges;
$privileges|%{[SystemPrivilege.Win32API.Privileges]::AdjustPrivilege($_, $true)}
# Validation
whoami /priv|?{$_ -match "SeBackupPrivilege|SeRestorePrivilege"}
}
addSystemPrivilege;
################################## Excuting Program as an Administrator ####################################
function listDirectories{
param($parentDirectory,$depth,$excludes)
$directories=(dir $parentDirectory| Where {$_.PSIsContainer -eq $True}).FullName | ?{$excludeDirectories -notcontains $_};
$result=$directories;
for ($i=1;$i -lt $depth; $i++){
$directories=$directories|%{if($_ -ne $null){(dir $_| Where {$_.PSIsContainer -eq $True}).FullName}};
$result+=$directories;
}
function removeParents{
param($inputData)
$objectLength=$inputData.length;
$castedArrayList=[System.Collections.ArrayList]$inputData;
for ($i=0;$i -lt $objectLength; $i++){
$currentItem=$castedArrayList[$i];
$nextItem=$castedArrayList[$i+1];
$nextItemSplice=if($nextItem.length -ge $currentItem.length){try{$nextItem.Substring(0,$currentItem.length)}catch{}}
if($currentItem -like $nextItemSplice){
#write-host "Removing $inputData[$i]...";
$castedArrayList.RemoveAt($i);
#$inputData=[Array]$castedArrayList; #reverse the casting and reassign to original Array
$objectLength--;
$i--;
}
}
$outputData=[Array]$castedArrayList; #reverse the casting and reassign to original Array
return $outputData
}
#$result=removeParents -inputData $($result|sort)
return $result;
}
# Discover directories
$directories=listDirectories -parentDirectory $parentDirectory -depth $depth -excludes $excludeDirectories
#$driveLetterAndBlockSize=Get-CimInstance -ClassName Win32_Volume|Select-Object DriveLetter,BlockSize|?{$_.DriveLetter -ne $null -and $_.BlockSize -ne $null}
function getSizeOnDisk{
param (
[string]$path='.',
$clusterSizeOfNetworkShare=4096
)
# snippet to obtain size (not size on disk)
# ((gci –force $path –Recurse -ErrorAction SilentlyContinue| measure Length -s).sum) / 1G
# GCI $dir -Recurse | Group-Object -Property Directory | % {New-Object psobject -Property @{Name =$_.Name;Size = ($_.Group | ? {!($_.PSIsContainer)} | Measure-Object Length -Sum).Sum}} | Sort-Object -Property size -Descending
<# deprecated
$typeSource = @"
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;
}
}
}
}
"@
try{Add-Type -TypeDefinition $typeSource -ErrorAction SilentlyContinue}catch{}
$dir="C:\temp"
[Win32Functions.ExtendedFileInfo]::GetFileSizeOnDisk( $dir )
$totalSize=0;
#$count=0;
$driveLetter=(Get-Item $path).PSDrive.Root
$clusterSize=(Get-WmiObject -Class Win32_Volume | Where-Object {$_.Name -eq $driveLetter}).BlockSize
if(!($clusterSize)){$clusterSize=$clusterSizeOfNetworkShare}
Get-ChildItem $path -Recurse -Force -ErrorAction SilentlyContinue| where { !$_.PSisContainer }|`
% {
$size = $(try{[Win32.Disk]::GetSizeOnDisk([string]$_.FullName)}catch{})
#$AFZ=[MidpointRounding]::AwayFromZero
#$roundedSize=[math]::Round($size/$ClusterSize+0.5,$AFZ)*$ClusterSize
if ($size){
if ($size -gt $clusterSize){$roundedSize=[math]::ceiling($size/$clusterSize)*$clusterSize}
if ($size -le $clusterSize){$roundedSize=$clusterSize;}
}else{
$roundedSize=0;
}
$count+=1;
#"$count`. $($_.FullName): $size vs $roundedSize"
$totalSize+=$roundedSize;
}
#>
# this part is obtained from https://stackoverflow.com/questions/22507523/getting-size-on-disk-for-small-files-in-powershell
$typeSource = @'
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);
}
}
'@
try{Add-Type -TypeDefinition $typeSource -ErrorAction SilentlyContinue}catch{}
$totalSize=0;
$files=Get-ChildItem $path -Recurse -Force -ErrorAction SilentlyContinue| where { !$_.PSisContainer }|select fullname
foreach ($file in $files){
$size=[Win32Functions.ExtendedFileInfo]::GetFileSizeOnDisk('$file');
$totalSize+=$size;
}
return $totalSize
}
# List top 10 files in all folders
function getLargestFiles{
param($folders,$limit)
$topFiles=$folders|%{get-childitem $_ -recurse}| ?{!$_.PSisContainer}|sort -Property Length -Descending | select-object -first $limit|select FullName,Length
return $topFiles
}
#$top10Files=getLargestFiles -folders $directories -limit $topX
function getFolderSizes{
param($folders)
function getFolderSize{
param($folder)
return (gci –force $folder –Recurse -ErrorAction SilentlyContinue| measure Length -s).sum
}
$folderAndSizes=$folders|select @{Name="Path";Expression={$_}},
@{Name="SizeOnDiskGb";Expression={[math]::round((getFolderSize $_)/1GB,2)}}`
|sort -Property SizeOnDiskGb -Descending
return $folderAndSizes;
}
# Find largest folder
# This code is currently unoptimized: needed to rewrite with roll-up size summarization between children and parent directories
$x=10
$topXFolders=getFolderSizes -folders $directories|select-object -first $x|Format-Table -AutoSize
write-host $topXFolders;
<# List 10 biggest files in the biggest folder
$topXFiles=get-childitem $parentDirectory -recurse | ?{!$_.PSisContainer}|sort -Property Length -Descending | select-object -first $x|`
select @{Name="Path";Expression={$_.FullName}},
@{Name="SizeOnDiskGb";Expression={[math]::round($_.Length/1GB,2)}}`
|Format-Table -AutoSize
write-host $topXFiles;
#>
function getTopFiles($directory,$x=10){
$files=Invoke-Expression -Command:"cmd.exe /C dir '$directory' /S /B /W /A:-D"|`
select-object @{name="FileName";expression={$_}},@{name="FileSize";e={(gi $_).Length}}
$topXFiles=$files| Sort-Object FileSize -Descending |select-object -first $x|Format-Table -AutoSize
return $topXFiles
}
getTopFiles $parentDirectory
Categories: