Binary Nature where the analog and digital bits of nature connect

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Thursday, 8 April 2010

PowerShell version of the df command

Posted on 12:09 by Unknown
I use the df command quite a bit with Unix-like operating systems and desired for a similar solution while working in Windows PowerShell. The df utility displays statistics about the amount of free disk space on the specified filesystem. I created a PowerShell function that encapsulates the core functionality of the command for the Windows platform.

Just for reference, this is example output from the df command on Linux:

$ df -ahT
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vg_rt-lv_root
ext4 37G 1.1G 35G 3% /
proc proc 0 0 0 - /proc
sysfs sysfs 0 0 0 - /sys
devpts devpts 0 0 0 - /dev/pts
tmpfs tmpfs 495M 0 495M 0% /dev/shm
/dev/sda1 ext4 485M 52M 408M 12% /boot
none binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc

Basically, in a nutshell, the PowerShell function queries the removable disk, local disk, network, CD/DVD, and ram disk drive types and creates a custom PowerShell object for output. In addition to the default output of the "raw" PS object, I also implemented a -Format option for "human friendly" output.

001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
function Get-DiskFree{ [CmdletBinding()] param ( [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [Alias('hostname')] [Alias('cn')] [string[]]$ComputerName = $env:COMPUTERNAME, [Parameter(Position=1, Mandatory=$false)] [Alias('runas')] [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter(Position=2)] [switch]$Format ) BEGIN { function Format-HumanReadable { param ($size) switch ($size) { {$_ -ge 1PB}{"{0:#.#'P'}" -f ($size / 1PB); break} {$_ -ge 1TB}{"{0:#.#'T'}" -f ($size / 1TB); break} {$_ -ge 1GB}{"{0:#.#'G'}" -f ($size / 1GB); break} {$_ -ge 1MB}{"{0:#.#'M'}" -f ($size / 1MB); break} {$_ -ge 1KB}{"{0:#'K'}" -f ($size / 1KB); break} default {"{0}" -f ($size) + "B"} } } $wmiq = 'SELECT * FROM Win32_LogicalDisk WHERE Size != Null AND DriveType >= 2' } PROCESS { foreach ($computer in $ComputerName) { try { if ($computer -eq $env:COMPUTERNAME) { $disks = Get-WmiObject -Query $wmiq ` -ComputerName $computer -ErrorAction Stop } else { $disks = Get-WmiObject -Query $wmiq ` -ComputerName $computer -Credential $Credential ` -ErrorAction Stop } if ($Format) { # Create array for $disk objects and then populate $diskarray = @() $disks | ForEach-Object { $diskarray += $_ } $diskarray | Select-Object @{n='Name';e={$_.SystemName}}, @{n='Vol';e={$_.DeviceID}}, @{n='Size';e={Format-HumanReadable $_.Size}}, @{n='Used';e={Format-HumanReadable ` (($_.Size)-($_.FreeSpace))}}, @{n='Avail';e={Format-HumanReadable $_.FreeSpace}}, @{n='Use%';e={[int](((($_.Size)-($_.FreeSpace))` /($_.Size) * 100))}}, @{n='FS';e={$_.FileSystem}}, @{n='Type';e={$_.Description}} } else { foreach ($disk in $disks) { $diskprops = @{'Volume'=$disk.DeviceID; 'Size'=$disk.Size; 'Used'=($disk.Size - $disk.FreeSpace); 'Available'=$disk.FreeSpace; 'FileSystem'=$disk.FileSystem; 'Type'=$disk.Description 'Computer'=$disk.SystemName;} # Create custom PS object and apply type $diskobj = New-Object -TypeName PSObject ` -Property $diskprops $diskobj.PSObject.TypeNames.Insert(0,'BinaryNature.DiskFree') Write-Output $diskobj } } } catch { # Check for common DCOM errors and display "friendly" output switch ($_) { { $_.Exception.ErrorCode -eq 0x800706ba } ` { $err = 'Unavailable (Host Offline or Firewall)'; break; } { $_.CategoryInfo.Reason -eq 'UnauthorizedAccessException' } ` { $err = 'Access denied (Check User Permissions)'; break; } default { $err = $_.Exception.Message } } Write-Warning "$computer - $err" } } } END {} }

Usage
The function can be utilized for a variety of use cases. The following are just a few examples:

# Default Output
By default, the function will return PS "disk" objects. From this specific output, you will notice three separate objects are returned from the local computer named DC01 with the numeric values in bytes.

PS> Get-DiskFree

FileSystem : NTFS
Type : Local Fixed Disk
Used : 13246943232
Volume : C:
Available : 29595770880
Computer : DC01
Size : 42842714112

FileSystem : CDFS
Type : CD-ROM Disc
Used : 623890432
Volume : D:
Available : 0
Computer : DC01
Size : 623890432

FileSystem : NTFS
Type : Network Connection
Used : 16416772096
Volume : Z:
Available : 26425942016
Computer : DC01
Size : 42842714112

# Output with the Format Option
In this example, We're performing a query against a couple of remote servers. Instead of having the function return separate PowerShell "disk" objects for each remote computer, we prefer to have the collection output in a structured table format with human-readable numbers. This would be similar to the *nix df command output with the -h option.

Note: The -Format option should only be enabled when no further numeric operations will need to be performed on the Available, Size, and Used properties. The option converts these values to the string data type.


PS> $cred = Get-Credential -Credential 'example\administrator'
PS> 'db01','sp01' | Get-DiskFree -Credential $cred -Format | ft -GroupBy Name -auto

Name: DB01

Name Vol Size Used Avail Use% FS Type
---- --- ---- ---- ----- ---- -- ----
DB01 C: 39.9G 15.6G 24.3G 39 NTFS Local Fixed Disk
DB01 D: 4.1G 4.1G 0B 100 CDFS CD-ROM Disc

Name: SP01

Name Vol Size Used Avail Use% FS Type
---- --- ---- ---- ----- ---- -- ----
SP01 C: 39.9G 20G 19.9G 50 NTFS Local Fixed Disk
SP01 D: 722.8M 722.8M 0B 100 UDF CD-ROM Disc

# Low Disk Space
What if we just need a list of Windows servers in the Active Directory domain which have disk space below 20% for their C: volume?

PS> Import-Module ActiveDirectory
PS> $servers = Get-ADComputer -Filter { OperatingSystem -like '*win*server*' } | Select-Object -ExpandProperty Name
PS> Get-DiskFree -cn $servers | Where-Object { ($_.Volume -eq 'C:') -and ($_.Available / $_.Size) -lt .20 } | Select-Object Computer

Computer
--------
FS01
FS03

# Out-GridView
And in this example, we will filter on the local hard drives of four select servers and have the output displayed in an interactive table.

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Get-DiskFree -Credential $cred -cn $servers -Format | ? { $_.Type -like '*fixed*' } | select * -ExcludeProperty Type | Out-GridView -Title 'Windows Servers Storage Statistics'

# Output to CSV
PowerShell also gives us the ability to output to a comma-separated values (CSV) file type. This example is similar to the previous except we will also sort the disks by the percentage of usage. We've also decided to narrow the set of properties to name, volume, total size, and the percentage of the drive space currently being used.

PS> $cred = Get-Credential 'example\administrator'
PS> $servers = 'dc01','db01','exch01','sp01'
PS> Get-DiskFree -Credential $cred -cn $servers -Format | ? { $_.Type -like '*fixed*' } | sort 'Use%' -Descending | select -Property Name,Vol,Size,'Use%' | Export-Csv -Path $HOME\Documents\windows_servers_storage_stats.csv -NoTypeInformation

Read More
Posted in PowerShell, Windows | No comments
Newer Posts Older Posts Home
Subscribe to: Comments (Atom)

Popular Posts

  • Cisco ASA SSL VPN with Active Directory
    There is little doubt the bring-your-own-device (BYOD) strategy is becoming a popular method to access company resources. As technical prof...
  • PowerShell Function for Windows System Memory Statistics
    Memory is one of the four primary hardware resources an operating system manages. The other three are cpu, disk, and network. Analysis of sy...
  • Integrate VMware Fusion with GNS3 on your Mac
    At long last, we can finally integrate VMware Fusion with GNS3. VMware Workstation for Windows and Linux has had this capability for quite s...
  • Configure Inter-VLAN routing on a Cisco L3 Catalyst Switch
    I recently had to configure inter-VLAN routing at a client's site. I don't have to perform this task on a regular basis, so I figur...
  • SSL VPN configuration on Cisco ASA with AnyConnect VPN client
    This post will describe how to setup a Cisco Adaptive Security Appliance (ASA) device to perform remote access SSL VPN with the stand-alone ...
  • Enable sudo for RHEL and CentOS
    Sudo is an arguably safer alternative to logging in (or using the su command) to the root account. Sudo allows you to partition and delegat...
  • Get Exchange Server Version and Update Info with PowerShell
    I prefer not to "reinvent the wheel", so I spent quite a bit of time searching the web for available code that would perform the t...
  • Cisco Security Device Manager on the Mac
    Cisco Router and Security Device Manager (SDM) is a Web-based device-management tool that enables you to deploy and manage the services on a...
  • Install Request Tracker 4 on Ubuntu Server
    The CentOS6/RT4 blog post has generated terrific feedback, so I figure an Ubuntu (and Debian) distribution port is essential. The core com...
  • Install Request Tracker 4
    The argument could be made Request Tracker is the de facto standard when it comes to issue tracking systems. Maybe the only drawback of RT ...

Categories

  • AD
  • Apache
  • AWS
  • Cisco
  • Exchange
  • FFmpeg
  • GNS3
  • Linux
  • Mac
  • MariaDB
  • MySQL
  • PowerShell
  • RT
  • Security
  • SSH
  • VMware
  • Windows
  • Zenoss

Blog Archive

  • ►  2013 (8)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2012 (3)
    • ►  December (1)
    • ►  November (1)
    • ►  April (1)
  • ►  2011 (3)
    • ►  June (1)
    • ►  May (2)
  • ▼  2010 (8)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (1)
    • ▼  April (1)
      • PowerShell version of the df command
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2009 (3)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
Powered by Blogger.

About Me

Unknown
View my complete profile