common/tools/findPhysicalDrive.pl
changeset 891 6c56420d1006
parent 858 f9fc2a3f8f70
child 924 a5ed0e6ca679
--- a/common/tools/findPhysicalDrive.pl	Wed Feb 03 14:46:17 2010 +0000
+++ b/common/tools/findPhysicalDrive.pl	Mon Feb 08 14:50:19 2010 +0000
@@ -12,23 +12,64 @@
 # Contributors:
 #
 # Description:
-# Find and output the drive letter mapped to the physical volume with the
-# largest amount of free space
-# 
+# Search physical drives to find either:
+#  * The one with the largest amount of free space
+#  * The one with the greatest capacity
+#  * The list of all such drives
 
 use strict;
 
+use Getopt::Long;
+
+# Read option arguments
+my $option;
+my $ok = GetOptions(
+	'capacity' => \$option->{capacity},
+	'space' => \$option->{space},
+	'all' => \$option->{all},
+	'help|?' => \$option->{help},
+);
+
+if (defined $option->{help})
+{
+	usage();
+	exit;
+}
+
+if (!$ok || @ARGV || 1 != scalar grep { defined $option->{$_} } keys %$option)
+{
+	warn "Exactly one option must be supplied to indicate the required output\n$ok\n@ARGV\n";
+	usage();
+	exit(1);
+}
+
 # Use Windows command to list physical volumes on the machine
 # (No substed drives, or mapped network drives)
-my @drives = map {chomp;$_} `echo list volume | diskpart`;
+my @details = map {chomp;$_} `echo list volume | diskpart`;
 
-my %drives;
-for my $driveLine (@drives)
+my @drives;
+my %space;
+my %capacity;
+for my $driveLine (@details)
 {
 	# If this line of output is actually about a healthy HD volume...
-	if ($driveLine =~ m{^\s+Volume \d+\s+([A-Z]).*?(Partition|RAID-5)\s+\d+ [A-Z]+\s+Healthy} )
+	if ($driveLine =~ m{^\s+Volume \d+\s+([A-Z]).*?(Partition|RAID-5)\s+(\d+) ([A-Z]+)\s+Healthy} )
 	{
-		my $letter = $1;
+		my ($letter, $capacityValue, $capacityUnit) = ($1, $3, $4);
+		
+		my %multiplier = (
+			MB => 1000000,
+			GB => 1000000000,
+			TB => 1000000000000,
+		);
+
+		if (not exists $multiplier{$capacityUnit})
+		{
+			warn "Don't know how to interpret $capacityValue $capacityUnit\n";
+			next;
+		}
+		$capacityValue *= $multiplier{$capacityUnit};
+
 		# Ignore the system drive
 		next if ($driveLine =~ m{System\s*$});
 
@@ -38,14 +79,45 @@
 		my $bytesFree = $bytesFree[-1];
 
 		# Record info for this volume
-		$drives{$letter} = $bytesFree;
+		push @drives, $letter;
+		$space{$bytesFree} = $letter;
+		$capacity{$capacityValue} = $letter;
 	}
 }
 
-die "Unable to find any suitable drives at all\n" unless %drives;
+die "Unable to find any suitable drives at all\n" unless %space;
 
-# Switch keys and values
-%drives = reverse %drives;
-# Sort by space to find the volume with the largest amount of space and print out the corresponding letter
-print "$drives{(reverse sort keys %drives)[0]}:\n";
+if ($option->{all})
+{
+	print join ",", map { "$_:" } @drives;
+	print "\n";
+	exit;
+}
+elsif ($option->{capacity})
+{
+	# Sort by capacity to find the largest volume and print out the corresponding letter
+	print "$capacity{(reverse sort keys %capacity)[0]}:\n";
+}
+elsif ($option->{space})
+{
+	# Sort by space to find the volume with the largest amount of space and print out the corresponding letter
+	print "$space{(reverse sort keys %space)[0]}:\n";
+}
 
+exit;
+
+sub usage
+{
+	$0 =~ m{[\\/]([^\\/]*)$};
+	print <<EOT;
+
+Usage: $1 -all | -capacity | -space | -help
+
+  -all          Outputs all physical drives in the system (separated by ',').
+  -capacity     Outputs physical drive of greatest capacity in the system.
+  -space        Outputs physical drive with greatest free space in the system.
+  -help         Outputs this help message.
+
+EOT
+}
+