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
}

Popular posts from this blog

SCCM Task Sequence GUI - How to set up the TS to work with a GUI

SCCM Applications vs. SCCM Packages: Understanding the Key Differences

Faster PXE boot times in SCCM 1606 and later