Script - CopyTool - V 1.0.0.0
When you manage a organizations driver, software installers, operating system images and updates, as you do as a SCCM admin, you may have to move that content around to new servers or shares. The process of moving that much content can be troublesome, windows explorer can have a hard time copying large files or a large amount of items. To do this task I would use something like robocopy or copy-item from PowerShell but I would only do this 2 or 3 times a year so I would forget exactly what switches to use for the commands so I built a script that dose all that for me.
<# .SYNOPSIS This script is used to perform large copy jobs .DESCRIPTION The script provides you a GUI to enter a source and destination for your copy process. The target and destination should be folders, the script will copy the content of the source folder into the destination folder. You can type out the path to each but if you do this and try to use the browse buttons you may need to reenter a path. The script will all so accept UNC paths for both the destination and source. .PARAMETER Source Specifyies the source for the copy job .PARAMETER Destination Specifyies the destination for the copy job .NOTES Created By: Kris Gross Contact: Krisgross@sccmtst.com Twitter: @kmgamd .LINK http://www.sccmtst.com/ #> Param( $Source, $Destination ) #Generates the form Function Generate-Form { #Needed for the form to show Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing #Set the standrads of the form window $form = New-Object System.Windows.Forms.Form $form.Text = "CopyTool - V 1.0.0.0" $form.Size = New-Object System.Drawing.Size(460,320) $form.StartPosition = "CenterScreen" #sets the ok button $CopyButton = New-Object System.Windows.Forms.Button $CopyButton.Location = New-Object System.Drawing.Point(50,180) $CopyButton.Size = New-Object System.Drawing.Size(300,23) $CopyButton.Text = "Start Copy" $CopyButton.Add_Click({Click_Copy}) #sets the Browse Button for the File $FindSourceButton = New-Object System.Windows.Forms.Button $FindSourceButton.Location = New-Object System.Drawing.Point(320,70) $FindSourceButton.Size = New-Object System.Drawing.Size(75,23) $FindSourceButton.Text = "Browse" $FindSourceButton.Add_Click({Get-SourcePath}) #sets the Browse Button for the Folder $FindDestinationButton = New-Object System.Windows.Forms.Button $FindDestinationButton.Location = New-Object System.Drawing.Point(320,140) $FindDestinationButton.Size = New-Object System.Drawing.Size(75,23) $FindDestinationButton.Text = "Browse" $FindDestinationButton.Add_Click({Get-DestinationPath}) #Sets the box showing the File selected $SourceBox = New-Object System.Windows.Forms.TextBox $SourceBox.Location = New-Object System.Drawing.Point(24,80) $SourceBox.Size = New-Object System.Drawing.Size(260,22) $SourceBox.Font = 'Lucida Console' $SourceBox.Text = $Source #Sets the box showing the selected folder $DestinationBox = New-Object System.Windows.Forms.TextBox $DestinationBox.Location = New-Object System.Drawing.Point(24,140) $DestinationBox.Size = New-Object System.Drawing.Size(260,22) $DestinationBox.Font = 'Lucida Console' $DestinationBox.Text = $Destination #label for file box $SourceBoxLabel = New-Object System.Windows.Forms.Label $SourceBoxLabel.Location = New-Object System.Drawing.Point(24,60) $SourceBoxLabel.Size = New-Object System.Drawing.Size(280,13) $SourceBoxLabel.Text = "Source:" #Label for folder box $DestinationBoxLabel = New-Object System.Windows.Forms.Label $DestinationBoxLabel.Location = New-Object System.Drawing.Point(24,120) $DestinationBoxLabel.Size = New-Object System.Drawing.Size(280,13) $DestinationBoxLabel.Text = "Destination:" #Label for the form $FormLabel = New-Object System.Windows.Forms.Label $FormLabel.Location = New-Object System.Drawing.Point(24,20) $FormLabel.Size = New-Object System.Drawing.Size(280,13) $FormLabel.Text = "Use this tool to perform large copy jobs" #tells the progress of the extraction process $RunningLabel = New-Object System.Windows.Forms.Label $RunningLabel.Location = New-Object System.Drawing.Point(24,260) $RunningLabel.Size = New-Object System.Drawing.Size(320,13) $RunningLabel.Text = "Waiting For Input" $RunningLabel.Visible = $true #Create a ProgressBar $PB = New-Object System.Windows.Forms.ProgressBar $PB.Name = "PowerShellProgressBar" $PB.Size = New-Object System.Drawing.Size(380,20) $PB.Location = New-Object System.Drawing.Point(25,230) $PB.Value = 0 $PB.Style="Continuous" #add all resorces of the form $form.Controls.Add($CopyButton) $form.Controls.Add($FindSourceButton) $form.Controls.Add($FindDestinationButton) $form.Controls.Add($SourceBox) $form.Controls.Add($DestinationBoxLabel) $form.Controls.Add($SourceBoxLabel) $form.Controls.Add($DestinationBox) $form.Controls.Add($FormLabel) $form.Controls.Add($RunningLabel) $form.Controls.Add($PB) #Show the Form [void]$form.ShowDialog() } #action taken then extract is pressed function Click_Copy { $Destination = $DestinationBox.Text $Source = $SourceBox.Text $Source=$Source.tolower() $Filelist = Get-Childitem $Source -Recurse $Total = $Filelist.count $Position = 0 $RunningLabel.text = "Copying Content of $Source" ForEach ($File in $Filelist) { $Filename=$File.Fullname.tolower().replace($Source,'') $DestinationFile=($Destination+$Filename) Copy-Item $File.FullName $DestinationFile -Force IF (-not (Test-Path $DestinationFile)) {Add-Content Errors.log "$File.FullName Failed to Copy"} $Position++ $Percentage = (($Position/$Total)*100) $PB.Value = $Percentage Start-Sleep -Milliseconds 150 } If (-not (Test-Path Error.log)) { $RunningLabel.ForeColor = "Green" $RunningLabel.text = "Completed Succesfully" } else { $RunningLabel.ForeColor = "Red" $RunningLabel.text = "Completed with Errors, review Errors.log for details" } } #form used to select the source Function Get-SourcePath { [CmdletBinding()] param([string]$Description="Select Folder",[string]$RootFolder="Desktop") [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $SourceForm = New-Object System.Windows.Forms.FolderBrowserDialog $SourceForm.Rootfolder = $RootFolder $SourceForm.Description = $Description [void]$SourceForm.ShowDialog() $SourceForm.SelectedPath $Form.Dispose() $Form.Close() $Source = $SourceForm.SelectedPath Generate-Form } #form used to select the destination Function Get-DestinationPath { [CmdletBinding()] param([string]$Description="Select Folder",[string]$RootFolder="Desktop") [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $SourceForm = New-Object System.Windows.Forms.FolderBrowserDialog $SourceForm.Rootfolder = $RootFolder $SourceForm.Description = $Description [void]$SourceForm.ShowDialog() $SourceForm.SelectedPath $Form.Dispose() $Form.Close() $Destination = $SourceForm.SelectedPath Generate-Form } #used when no GUI is to be used function Start-Copy { $Source=$Source.tolower() $Filelist = Get-Childitem $Source -Recurse $Total = $Filelist.count Write-Host "Copying Content of $Source" ForEach ($File in $Filelist) { $Filename=$File.Fullname.tolower().replace($Source,'') $DestinationFile=($Destination+$Filename) Write-Host "Copying $File.FullName" Copy-Item $File.FullName $DestinationFile -Force IF (-not (Test-Path $DestinationFile)) {Add-Content Errors.log "$File.FullName Failed to Copy"} Start-Sleep -Milliseconds 150 } If (-not (Test-Path Error.log)) { Write-Host "Completed Succesfully" } else { Write-Debug "Completed with Errors, review Errors.log for details" } } #Call the Function based on paramiters IF ((!$Source) -and (!$Destination)) { Generate-Form } else { Start-Copy }