use File::Find::Rule ; use Sys::Hostname ; use Win32 ; use Win32::OLE ; use Win32::OLE 'in' ; use Getopt::Long ; my $NotDefaultSettings = 0 ; my $TargetFillPC = 0; my $NumWorkers = 12 ; GetOptions ('nodefault' => \$NotDefaultSettings , 'fp=i' => \$TargetFillPC , 'num_vms' => \$NumWorkers); my $InitDir = "B:\\NAS_FillUp" ; if ($NotDefaultSettings) { print "\nEnter Source Path: "; $InitDir = <> ; chomp ($InitDir) ; } my @DriveTypes = ("Unknown", "Removable", "Fixed", "Network", "CDRom", "Ram Disk"); my $FSObject = "Scripting.FileSystemObject" ; my $FS = Win32::OLE->new ($FSObject) ; my $Drives = $FS->Drives ; my $Ctr = 1; if ($NotDefaultSettings) { print "Network Drive Letter Report:\n"; foreach my $drv ( in($Drives) ) { $typ = $drv->{DriveType}; if ($typ == 3) { print $Ctr . ". " . $drv->{DriveLetter} . ":\ \n" ; } } } my $DriveToTest = "Z:" ; if ($NotDefaultSettings) { print "\nEnter Network Drive to Test (Format: Z:): " ; $DriveToTest = <> ; chomp ($DriveToTest) ; } my $DriveToTestRef = $FS->GetDrive ($DriveToTest) ; my $SizeOfDriveToTest = $DriveToTestRef->{TotalSize} / (1024.0*1024.0); my $FreeSpaceOfDriveToTest = $DriveToTestRef->{FreeSpace} / (1024.0*1024.0); ## Got Total Size of Dest FS ## Got Current Size of Dest FS ## Get Target Percentage and caclulate final size, size to fill will be final size - curr size if ($TargetFillPC == 0) { print "\nEnter target fill percentage (usually 30, 60 or 90): "; $TargetFillPC = <>; chomp ($TargetFillPC) ; } if ($NotDefaultSettings) { print "\nEnter number of concurrent VMs running this script (including this one): "; $NumWorkers = <> ; chomp ($NumWorkers) ; } my $FinalDriveSize = ($TargetFillPC * $SizeOfDriveToTest) / 100 ; my $CurrDriveSize = ($SizeOfDriveToTest - $FreeSpaceOfDriveToTest) ; my $SizeToFillThisWorker = ($FinalDriveSize - $CurrDriveSize) / $NumWorkers ; print "\n\nStarting Fill Up Process with Parameters:\n\n\tSource Folder : $InitDir\n\tDestination Drive : $DriveToTest\n\t" ; printf "Statistics for Selected Disk:\n\t\tTotal Size : %.02f MB\n\t\tFree Space : %.02f MB\n", $SizeOfDriveToTest, $FreeSpaceOfDriveToTest ; print "\tTarget Fill Up Space (Percentage / Actual) : $TargetFillPC \% / $FinalDriveSize MB\n"; print "\tNumber of Workers : $NumWorkers\n" ; if ($CurrDriveSize > $FinalDriveSize) { print "\nCurrent drive size ($CurrDriveSize MB) exceeds targeted drive size ($FinalDriveSize MB).... Exiting script!\n" ; exit (); } ## $HashOfDirectoryFileSizes ; Key = DirName ; Value = Size ## Use File::Find and File::Size , sort based on value , high to low, push key to dirarray_by_size my @ArrayOfFolders = File::Find::Rule->directory->in($InitDir) ; my %HashOfDirectorySizes = () ; foreach my $Folder (@ArrayOfFolders) { my $F = $FS->GetFolder ($Folder) ; my $FSize = $F->{Size} / (1024.0 * 1024.0); print "\nFound $Folder with Size $FSize MB" ; if ($FSize >= 1.00) { $HashOfDirectorySizes{$Folder} = $FSize ; } } my %DirSizeToFolderName = reverse %HashOfDirectorySizes ; my @DirSizesOnHand = keys %DirSizeToFolderName ; @DirSizesOnHand = sort { $b <=> $a } @DirSizesOnHand ; my $HostName = hostname ; my $CurrSize = 0 ; my $FolderCtr = 0; my @CurrTimeData ; @CurrTimeData = localtime(time); my $CurrTimeString = $CurrTimeData[2] . ":" . $CurrTimeData[1] . ":" . $CurrTimeData[0] ; print "\nCurrent Time is $CurrTimeString\n" ; print "\nPlease enter minutes past the hour to sync workers: " ; my $SyncTime = <>; chomp ($SyncTime) ; do { sleep 5 ; @CurrTimeData = localtime(time); $CurrTimeString = $CurrTimeData[2] . ":" . $CurrTimeData[1] . ":" . $CurrTimeData[0] ; } while ($CurrTimeData[1] != $SyncTime) ; print "\nStarting Worker at $CurrTimeString..........\n" ; my $TimeStr = time ; while (int($CurrSize) < int($SizeToFillThisWorker)) { my $FolderPrefix = sprintf "-%s-Folder%d", $TimeStr, $FolderCtr ++ ; my $DestFolder = $DriveToTest . "\\" . $HostName . $FolderPrefix ; my $RemainingSize = $SizeToFillThisWorker - $CurrSize ; if ($RemainingSize > 1.00) { my $DirSizeArrayIdx = 0 ; while ($DirSizesOnHand[$DirSizeArrayIdx] > $RemainingSize) { $DirSizeArrayIdx ++ ; } my $FullFolderToCopy = $DirSizeToFolderName{$DirSizesOnHand[$DirSizeArrayIdx]} ; my $SystemCmd = "robocopy /MIR \"$FullFolderToCopy\" \"$DestFolder\"" ; printf "Will Execute : $SystemCmd" ; system ($SystemCmd) ; $CurrSize += $DirSizesOnHand[$DirSizeArrayIdx] ; } else { $CurrSize += 1 ; } my $CompletionPercentage = $CurrSize * 100 / $SizeToFillThisWorker ; printf "\n\nCurrent Status on this Worker : $CompletionPercentage ($CurrSize MB / $SizeToFillThisWorker MB)\n\n" ; } @CurrTimeData = localtime(time); $CurrTimeString = $CurrTimeData[2] . ":" . $CurrTimeData[1] . ":" . $CurrTimeData[0] ; print "\nFinished Worker at $CurrTimeString..........\n" ; ## Get Start Time to sync workers ## mc_name = m/c name ## curr_size = 0 ; while (curr_size <= size_to_fill_this_worker) { ## folder-prefix = Folder%d, folder_ctr ## dest_folder = "mc_name"."-folder-prefix" # remaining_size = size_to_fill_this_worker - curr_size ; ## while (HashOfDirectoryFileSizes->{$dirarray_by_size[ctr++]} > remaining_size) ; ## robocopy /mir dirarray_by_size[ctr - 1] dest_folder ## folder_Ctr++ ## curr_size += HashOfDirectoryFileSizes->{dirarray_by_size[ctr - 1]} ## Print debug message ## } ## Get end time and show transfer characteristics