(May need to be Run As Administrator)
#
# ----------------------------------------------------------------------
# Volume and Volume Fragmentation Information
# Returns volume information. If being run as an Administrator,
# returns volume fragmentation information for each local disk.
# ----------------------------------------------------------------------
# MODIFICATION LOG
# ----------------------------------------------------------------------
# 2012-08-09 WGS Initial Creation.
# 2012-08-11 WGS The WMI Win32_Volume class is not exposed on all
# operating systems. Check for if the class is exposed.
# Added check for running as an administrator.
# Include more volume information as a separate result.
# Perform and return fragmentation information for local
# volumes only.
# ----------------------------------------------------------------------
cls
# Set-StrictMode -version 2
$IsAdmin = ([Security.Principal.WindowsPrincipal]`
[Security.Principal.WindowsIdentity]::GetCurrent()).`
IsInRole([Security.Principal.WindowsBuiltInRole]`
"Administrator")
$Volumes = Get-WMIObject Win32_Volume `
-errorAction SilentlyContinue | Sort-Object DriveLetter
if (!$Volumes)
{Write-Warning "The Win32_Volume WMI class is not exposed on this operating system.`n`nThis script cannot continue.`n "}
#elseif (([Security.Principal.WindowsPrincipal]`
# [Security.Principal.WindowsIdentity]::GetCurrent()).`
# IsInRole([Security.Principal.WindowsBuiltInRole]`
# "Administrator") -eq $False)
# {Write-Warning "You do not have Administrator rights to run this script!`n`nPlease re-run this script as an Administrator!`n "}
else
{
if ($IsAdmin -eq $False)
{Write-Warning "Running script under non-Administrator mode.
Fragmentation information not accessible.
Re-run this script as an Administrator to obtain the fragmentation information!
"}
# hash table to set what the columns in the format-table look like for volume information
$a = `
@{Expression={$_.DriveLetter};Label="Drive";width=5},`
@{Expression={$_.DriveTypeDesc};Label="Drive Type";width=17},
@{Expression={"{0:N0}" -f ($_.FileSystem)};Label="File System";width=11},
@{Expression={"{0:N0}" -f ($_.BlockSize)};Label="Block Size";width=10;align="right"},
@{Expression={"{0:N0}" -f ($_.Capacity)};Label="Capacity";width=18;align="right"},
@{Expression={"{0:N0}" -f ($_.FreeSpace)};Label="Free Space";width=18;align="right"},
@{Expression={"{0:N0}" -f ($_.FreeSpace/$_.Capacity*100)};Label="Free %";width=6;align="right"}
$b = `
@{Expression={$_.DriveLetter};Label="Drive";width=5},`
@{Expression={$_.DefragRecommended};Label="Defrag Needed";width=13},`
@{Expression={$_.FilePercentFragmentation};Label="File Fragmentation %";width=20},`
@{Expression={"{0:N0}" -f ($_.TotalFragmentedFiles)};Label="# Fragmented Files";width=18;align="right"},
@{Expression={"{0:N0}" -f ($_.ClusterSize)};Label="Volume Cluster Size";width=19;align="right"}
#This table is necessary to return data once vs. once per drive.
$ServerName = Get-WmiObject -Class Win32_ComputerSystem
$TableName = $ServerName.Caption
$Table = New-Object system.Data.DataTable "$TableName"
$col = $Table.Columns.Add("DriveLetter", [string])
$col = $Table.Columns.Add("DefragRecommended", [boolean])
$col = $Table.Columns.Add("FilePercentFragmentation", [uint32])
$col = $Table.Columns.Add("TotalFragmentedFiles", [uint64])
$col = $Table.Columns.Add("ClusterSize", [uint64])
$col = $Table.Columns.Add("BlockSize", [uint64])
$col = $Table.Columns.Add("Capacity", [uint64])
$col = $Table.Columns.Add("FreeSpace", [uint64])
$col = $Table.Columns.Add("FileSystem", [string])
$col = $Table.Columns.Add("DriveType", [uint32])
$col = $Table.Columns.Add("DriveTypeDesc", [string])
#Ensure volumes have a drive type of local disk.
foreach ($Drive in $Volumes)
{ #$Drive
#Must run DefragAnalysis() in a foreach loop for each drive.
#Add a new row to the DataTable, and populate it.
#First, add the volume information
$Row = $Table.NewRow()
$Row.DriveLetter = $Drive.DriveLetter
if ($Drive.BlockSize -ge 0)
{$Row.BlockSize = $Drive.BlockSize}
else {$Row.BlockSize = [DBNull]::Value}
if ($Drive.Capacity -ge 0)
{$Row.Capacity = $Drive.Capacity}
else {$Row.Capacity = [DBNull]::Value}
if ($Drive.FreeSpace -ge 0)
{$Row.FreeSpace = $Drive.FreeSpace}
else {$Row.FreeSpace = [DBNull]::Value}
$Row.FileSystem = $Drive.FileSystem
$Row.DriveType = $Drive.DriveType
switch ($Drive.DriveType)
{
0 {$Row.DriveTypeDesc = "Unknown"}
1 {$Row.DriveTypeDesc = "No Root Directory"}
2 {$Row.DriveTypeDesc = "Removable Disk"}
3 {$Row.DriveTypeDesc = "Local Disk"}
4 {$Row.DriveTypeDesc = "Network Drive"}
5 {$Row.DriveTypeDesc = "Compact Disk"}
6 {$Row.DriveTypeDesc = "RAM Disk"}
default {$Row.DriveTypeDesc = "Unknown"}
}
#If Admin and a local disk, get fragmentation information.
if (($IsAdmin -eq $true) -and ($Drive.DriveType -eq 3))
{
"Performing Fragmentation Analysis for Drive: {0} ({1})" -f $Drive.Caption, $Drive.DriveLetter
$Analysis = $Drive.DefragAnalysis()
$Stats = $Analysis.DefragAnalysis
$Row.DefragRecommended = $Analysis.DefragRecommended
if ($Stats.FilePercentFragmentation -ge 0)
{$Row.FilePercentFragmentation = $Stats.FilePercentFragmentation}
else {$Row.FilePercentFragmentation = [DBNull]::Value}
if ($Stats.TotalFragmentedFiles -ge 0)
{$Row.TotalFragmentedFiles = $Stats.TotalFragmentedFiles}
else {$Row.TotalFragmentedFiles = [DBNull]::Value}
if ($Stats.ClusterSize -ge 0)
{$Row.ClusterSize = $Stats.ClusterSize}
else {$Row.ClusterSize = [DBNull]::Value}
}
$Table.Rows.Add($Row)
}
#Display all of the results.
"
Volume Information (All Volumes)"
$Table | format-table $a
if ($IsAdmin -eq $True)
{"Fragmentation Information (Local Volumes)
"
$Table | Where-Object {$_.DriveType -eq 3} | format-table $b}
}


