Disk & Directory size

Contents



Disk space usage

A quick "One Linner" to get your partitions allocated size and available free space.

Get-WmiObject Win32_logicaldisk -Filter "Drivetype=3" | Format-Table DeviceId, Size, FreeSpace -auto



From the image above we can see that it can be a challenge to interpret the results so the next "One Linner" albeit a long one will produce a cleaner output.

Get-WmiObject Win32_logicaldisk -Filter "Drivetype=3" | Format-Table DeviceId, @{Name="Size(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb))}}, @{Name="Free Space(GB)";Expression={[decimal]("{0:N0}" -f($_.freespace/1gb))}}, @{Name="Free (%)";Expression={"{0,6:P0}" -f(($_.freespace/1gb) / ($_.size/1gb))}} -auto




Folder Size (Recursive)

Listing folder and sub-folder size on a Linux platform is not a difficult thing to do but on a Windows platform through the command line is another story. With windows core on the stage this script has helped me out a few times.

The script will spit out the size used by the folder you define and all its sub-folders. You can run this on a root directory although it can take some time depending on the amount of data on the partition.

You can run the script just by calling it (make sure you define the $Path one the first line to suit your needs) as shown below:

PS D:\Scripts\Powershell> .\Get-DirSizeRecursive.ps1

Or you can define the "-Path" when you run the script as below:

PS D:\Scripts\Powershell> .\Get-DirSizeRecursive.ps1 -Path d:\

You can also call on remote drives as shown on the next image:

PS D:\Scripts\Powershell> .\Get-DirSizeRecursive.ps1 -Path \\srv03\d$

My weapon of choice though is to feed the output to a file and then process it with excel:

PS D:\Scripts\Powershell> .\Get-DirSizeRecursive.ps1 -Path "C:\Program Files" > result.txt
So I got some "RED"!!!
Not to worry. This is due to an empty folder (or in my case 2 empty folders as there are 2 errors on the screenshot). Since the folder is empty the Measure-Object property -length cannot return a value.
The errors seen here will not get fed to the output file as shown below:


Note: I have used "*" as the delimiter so don´t forget when using excel or change it as you see fit in the actual script.
It´s defined in 2 places: Line 45 & 51

Download Script Get-DirSizeRecursive.ps1
<#
.SYNOPSIS
    Gets directories and their subfolders size .

.PARAMETER Path
    Top directory from where the script will start.

.EXAMPLE
    PS C:\> Get-DirSizeRecursive -Path "C:\Program Files\ATI"
    C:\Program Files\ATI * 26.18 MB
    C:\Program Files\ATI\CIM * 26.18 MB
    C:\Program Files\ATI\CIM\Bin64 * 22.71 MB
    C:\Program Files\ATI\CIM\Config * 3.30 MB
    C:\Program Files\ATI\CIM\Images * 0.16 MB
    C:\Program Files\ATI\CIM\Reports * 0.02 MB

    This example list the size for the folder "C:\Program Files\ATI" and its sub-folders .

.EXAMPLE
    PS C:\> Get-DirSizeRecursive -Path \\srv03\d$
    \\srv03\d$ * 17,835.32 MB
    \\srv03\d$\Hyper-V * 14,205.56 MB
    \\srv03\d$\Laptop * 3,629.77 MB
    \\srv03\d$\Hyper-V\VMconf * 14,205.56 MB
    \\srv03\d$\Hyper-V\VMconf\Snapshots * 1,542.63 MB
    \\srv03\d$\Hyper-V\VMconf\Virtual Machines * 12,662.93 MB
    \\srv03\d$\Hyper-V\VMconf\Snapshots\9A4E9DE0-17E7-473C-A9DD-B8395D748334 * 1,542.56 MB
    \\srv03\d$\Hyper-V\VMconf\Virtual Machines\346CB44A-E7E5-4CD9-8F54-3DC430076C1A * 0.00 MB
 
    This example lists the used space for disk D and its folders on a remote server called SRV03.
 
.EXAMPLE
    Get-DirSizeRecursive -Path \\srv03\d$ > D:\Scripts\Logs\SRV03_Disk_D.log
 
    This example is identical to the above although output is pipped to a file at D:\Scripts\Logs\SRV03_Disk_D.log.
#>

Param (
[Alias("P","Path")]
[string[]]$Path = "D:\"
)


$PFolder = (Get-ChildItem $Path -recurse | Measure-Object -property length -sum) 
"$Path * " + "{0:N2}" -f ($PFolder.sum / 1MB) + " MB" 
$subfolders = (Get-ChildItem $Path -recurse | Where-Object {$_.PSIsContainer -eq $True} ) 
$subfolders | % {
$RealPath = (Convert-Path -Path $_.PSPath)
    $RealPath | % {
    $Subs = (Get-ChildItem $RealPath -recurse | Measure-Object -property length -sum) 
    "$RealPath * " + "{0:N2}" -f ($Subs.sum / 1MB) + " MB" 
    }
}

This script is also available as a module



File Version

Have you ever needed to check the version number of a file on a bulk load of computers? Have a read here as this excellent article covers the issue at hand.

A while back I needed a script that would check a fist full of servers for the build number of a specific executable. With a bit of googleing I put the following script together.


<#
.SYNOPSIS
    Get file version by combining 4 properties from the VersionInfo object 
    to obtain the accurate version of the file.

.Prerequisites
    This script relies on Admin Shares being enabled including for local machine.

    Must either provide a file with hostnames and set path at $hostslist or 
    provide hostnames using switch "-ComputerName" when running the script.

    If switch "-ComputerName" is provided $hostslist is ignored.

    Must Provide full UNC to file "c$\Windows\Regedit.exe" by using switch "-FilePath" 
    or will be prompted for path.

.PARAMETER Path
    Type full UNC to the file .

.EXAMPLE
    PS D:\> .\Get-FileVersion.ps1

    This example will prompt you for the unc path to the file.

.EXAMPLE
    PS D:\> .\Get-FileVersion.ps1 -FilePath C$\Windows\regedit.exe
 
    This example will obtain the file version for c:\Windows\regedit.exe.

.EXAMPLE
    PS D:\> .\Get-FileVersion.ps1 -ComputerName LAP, SQL01 -FilePath C$\Windows\regedit.exe

    This example will obtain the file version for c:\Windows\regedit.exe from 2 hosts (LAP & SQL01)
#>

Param (
[string[]]$computerName = "",
[string[]]$FilePath = ""
)

$scriptfunction = "GetFileVersion"
$hostslist = "D:\Scripts\ServerList.txt"
$logpath = "D:\Scripts\logs\"
$logfile = "$logpath $scriptfunction -$(get-date -format `"dd-MM-yyyy_hhmmtt`").txt"

if (!$FilePath)
{
Add-Type -AssemblyName Microsoft.VisualBasic
$FilePath = [Microsoft.VisualBasic.Interaction]::InputBox("Enter Path and FileName", "File Path")
}

function log($logfunction)
 {
  write-host $logfunction -foregroundcolor yellow
  $logfunction | out-file -Filepath $logfile -append
 }
log $FilePath
if (!$computerName){$computerName = Get-Content $hostslist}
$computerName | % {
$PingTest = (Test-Connection $_ -Count 1 -ea 0 -Quiet)
If ($PingTest -eq "True")
    {$VersionInfo = (Get-Item \\$_\$FilePath).VersionInfo
    $FileVersion = ("{0}.{1}.{2}.{3}" -f 
    $VersionInfo.FileMajorPart, 
    $VersionInfo.FileMinorPart, 
    $VersionInfo.FileBuildPart, 
    $VersionInfo.FilePrivatePart)
log "$_ - $FileVersion"
    }
}

Download script Get-FileVersion.ps1
 Download script Get-FileVersion.ps1

This script is also available as a module
 Download module Get-FileVersion.psm1