Monday, February 11, 2013

Get-DiskSizeInfo function

As some of you might have heard, the 2013 Powershell Scripting Games are approaching. As a warm up session, the Powershell community has prepared a Winter test which I failed to subscribe for. I have nevertheless decided to test myself against the first task, whose description is here:

"Winter Scripting Games 2013 - Practice Event #1

Sizing up the Disks

You have been asked to create a Windows PowerShell advanced function named Get-DiskSizeInfo. It must accept one or more computer names, and use WMI or CIM to query each computer. For each computer, it must display the percentage of free space, drive letter, total size in gigabytes, and free space in gigabytes. If a specified computer cannot be contacted, the function must log the computer name to C:\Errors.txt and display no error message.

Minimum Requirements:

Optional Criteria:

  • Display optional verbose output showing the computer name being contacted"
Here's the script I came up with. It is a pretty simple one, but knowledge of all main Powershell principles is required, i.e. parameterized functions, WMI queries, composite formatting, expressions and error handling. The behavior of my script can vary depending on the Powershell version you are using to execute it. In particular it is compatible with Powershell V2, but works better with Powershell V3, where some of the bugs of test-connection have been fixed.

Concerning test-connection, I decided to set the 'erroraction' parameter to 'stop' because my try() catch() construct was unable to detect the exception on unreachable hosts.
function Get-DiskSizeInfo{
<#
.DESCRIPTION
Check disk total size in GB, free space in GB and percent free space

.PARAMETER Computername
Specify computer name(s)

.EXAMPLE
Get-DiskSizeInfo

Get local drives free space

.EXAMPLE
Get-DiskSizeInfo -ComputerName computer1,computer2

Get remote computer[s] drive space

.EXAMPLE
get-DiskSizeInfo -verbose

Shows verbose output. The verbose switch is available since we use the [CmdletBinding()]
#>

[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$True)]
[string[]]$ComputerName = $env:COMPUTERNAME
)
foreach($Comp in $ComputerName)
{
try{
Write-Verbose -Message "ComputerName: $Comp - Testing connection..."   
Test-Connection $comp -ErrorAction stop | Out-Null
Write-Verbose -Message "ComputerName: $Comp - Connection successfull. Proceeding"   
$conn_OK = $True
}
catch{
Write-Verbose -Message "ComputerName: $Comp - Connection failed. Exiting."
add-content C:\Errors.txt $Computername
$conn_OK = $False
}
if($conn_OK)
{
Write-Verbose -Message "ComputerName: $Comp - Getting drive information..."
Get-WmiObject -Class Win32_volume -ComputerName $Comp |
ft DriveLetter,
@{Label="PercentFree";Expression= {"{0:p}" -f ($_.freespace / $_.capacity)}},
@{Label="Total size in GB";Expression= {"{0:N2}" -f ($_.capacity/1gb)}},
@{Label="Free space in GB";Expression= {"{0:N2}" -f ($_.freespace/1gb)}}
Write-Verbose -Message "ComputerName: $Comp - Ended retrieving drive information"
Write-Host " " #Add an empty line
}
}
}
get-DiskSizeInfo
If you have problems understanding this script, do not hesitate to contact me and I'll be glad to answer. Just keep in mind that this is my solution to the proposed problem and might not be as good as other's. Keep an eye in particular on the Scripting Guy's blog and on Powershell.org.

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...