Playing around with Powershell again, and wrote a nifty little script to copy and separate files in a folder, limiting each new folder based on a user set size.
It requests input and output folders, size of output folders, and size type (ie. KB, MB, GB). Then copies from the input folder into the output folder, creating output folder if needed, and separating by numeric sub-folders. Before copying the objects are sorted by length(size) as it creates less total output folders, or should depending on your input. This sorting is entirely optional and could be removed if you wish.
We ran into a simple enough, issue initially when calculating total data to copy. We were checking if the division of moved size to total wanted equaled the initial number given for total size. This caused the total amount copied to be, wanted copied size times initial size number, resulting in quite an issue. Some debugging and head smacking fixed the issue by comparing to a total of 1. Enjoy the script and feel free to modify as needed!
Usage: CopyAndSeparate .\InputFolder .\OutputFolder 5 GB - Copies from .\InputFolder, moves to .\OutputFolder created sub-folders to place files in every 5gb or so.
CopyAndSeparate.ps1
# Spenser Reinhardt
# 7-27-2012
# Modified 8-7-2012
# CopyandSeparate.ps1
# Finds files in a directory and separates them into new folders, creating a new folder each time a given folder size limit is reached
# Released under GPLv3 Licensing
Param (
[parameter(Mandatory=$true)][string]$InputFolder,
[parameter(Mandatory=$true)][string]$OutputFolder,
[parameter(Mandatory=$true)][int]$FolderSize,
[parameter(Mandatory=$true)][string]$SizeType
)
#### Variables #####
$LoopCount = 0 #initializes loopcount for use later
[double]$LoopSize = 0 #initializes loopsize for use with loop lower on created as double to hold gb sized values
$LoopOutput = "" #initializes loopoutput for use with loop later on
$SizeDiv = "$FolderSize$SizeType"
#### Functions #####
Function NewFLCopy {
Param ($FullName, [string]$Output)
Write-host "Output: $Output`nFullName: $FullName"
Try {
New-Item -Path $Output -ItemType Directory # Creates new folder
}
Catch {
Write-Error -message "Could not create $Output for destination files.`nStoping here." -RecommendedAction "stop"
}
Try {
Copy-Item "$FullName" -Destination $Output
}
Catch {
Write-Error -message "Could not copy file $FullName.`nStoping here." -RecommendedAction "stop"
}
} # ends function
Function JustCopy {
Param ($FullName, [string]$Output)
Write-host "Output: $Output`nFullName: $FullName"
Try {
Copy-Item "$FullName" -Destination $Output
}
Catch {
Write-Error -message "Could not copy file $FullName.`nStoping here." -RecommendedAction "stop"
}
}
#### Logic ####
# tests if $input folder both exists and is only a folder not file
If ($(Test-Path $InputFolder -pathtype container) -eq $false) {
Write-Error -message "Input folder is not a valid folder, please specify an existing folder and not individual files." -RecommendedAction "Stop"
exit 1
}
# tests if $output folder exists
If ($(Test-Path $OutputFolder -pathtype container) -eq $false) {
Write-Host Creating output folder: $Outputfolder
Try {
New-Item -Path $OutputFolder -ItemType Directory
}
Catch {
Write-Error -message "Could not create $OutputFolder for destination files" -RecommendedAction "stop"
}
}
Else {Write-Host Appears that the output folder already exists at: $OutputFolder`n Using this directory}
#tests sizetype for being valid
If (($SizeType -ne "B") -and ($SizeType -ne "KB") -and ($SizeType -ne "MB") -and ($SizeType -ne "GB") -and ($SizeType -ne "TB")) {
Write-Error -message "Size type is incorrect, needs to be KB, MB, or GB.`nPlease try again" -RecommendedAction "Stop"
exit 2
}
# If bytes, we don't need to add a modifier to sizediv to get the correct size, otherwise above it has already been concatenated correctly for other modifiers
If (($SizeType -eq "b") -or ($SizeType -eq "B")) {
$SizeDiv = $FolderSize
}
Get-ChildItem $InputFolder | sort Length | ForEach-Object {
#checks if loopsize equals zero, indicating a new folder should be created for output and change of location to move files
If ($LoopSize -eq 0) {
$LoopSize = $_.Length # sets loopsize equal to first file of this folder
$LoopOutput = "$OutputFolder\$LoopCount\" # sets name for new output folder
Write-host "LoopOutput: $LoopOutput`nFullName: $_.FullName"
NewFLCopy $_.FullName $LoopOutput
} # ends if
#checks if adding file will be less than or equal to alloted size and if so proceeds
ElseIf ((($LoopSize + $_.Length)/$SizeDiv) -le 1) {
$LoopSize = $_.Length + $LoopSize
Write-host "LoopOutput: $LoopOutput`nFullName: "$_.FullName
JustCopy $_.FullName $LoopOutput
} # ends elseif
#checking for adding current file would be greater than alloted space, if so resets for next itteration while copying current file into that new dir
ElseIf ((($LoopSize + $_.Length)/$SizeDiv) -gt 1) {
$LoopSize = $_.Length #resets loopsize
$LoopCount++ # incriments loopcount
$LoopOutput = "$OutputFolder\$LoopCount\" # sets name for new output folder
Write-host "LoopOutput: $LoopOutput`nFullName: "$_.FullName
NewFLCopy $_.FullName $LoopOutput
} # ends elseif
} # ends foreach loop
CopyAndSeparate.psm1
# Spenser Reinhardt
# 7-27-2012
# Modified 8-7-2012
# CopyandSeparate.ps1
# Finds files in a directory and separates them into new folders, creating a new folder each time a given folder size limit is reached
# Released under GPLv3 Licensing
Param (
[parameter(Mandatory=$true)][string]$InputFolder,
[parameter(Mandatory=$true)][string]$OutputFolder,
[parameter(Mandatory=$true)][int]$FolderSize,
[parameter(Mandatory=$true)][string]$SizeType
)
#### Variables #####
$LoopCount = 0 #initializes loopcount for use later
[double]$LoopSize = 0 #initializes loopsize for use with loop lower on created as double to hold gb sized values
$LoopOutput = "" #initializes loopoutput for use with loop later on
$SizeDiv = "$FolderSize$SizeType"
#### Functions #####
Function NewFLCopy {
Param ($FullName, [string]$Output)
Write-host "Output: $Output`nFullName: $FullName"
Try {
New-Item -Path $Output -ItemType Directory # Creates new folder
}
Catch {
Write-Error -message "Could not create $Output for destination files.`nStoping here." -RecommendedAction "stop"
}
Try {
Copy-Item "$FullName" -Destination $Output
}
Catch {
Write-Error -message "Could not copy file $FullName.`nStoping here." -RecommendedAction "stop"
}
} # ends function
Function JustCopy {
Param ($FullName, [string]$Output)
Write-host "Output: $Output`nFullName: $FullName"
Try {
Copy-Item "$FullName" -Destination $Output
}
Catch {
Write-Error -message "Could not copy file $FullName.`nStoping here." -RecommendedAction "stop"
}
}
Function CopyAndSeparate {
# tests if $input folder both exists and is only a folder not file
If ($(Test-Path $InputFolder -pathtype container) -eq $false) {
Write-Error -message "Input folder is not a valid folder, please specify an existing folder and not individual files." -RecommendedAction "Stop"
exit 1
}
# tests if $output folder exists
If ($(Test-Path $OutputFolder -pathtype container) -eq $false) {
Write-Host Creating output folder: $Outputfolder
Try {
New-Item -Path $OutputFolder -ItemType Directory
}
Catch {
Write-Error -message "Could not create $OutputFolder for destination files" -RecommendedAction "stop"
}
}
Else {Write-Host Appears that the output folder already exists at: $OutputFolder`n Using this directory}
#tests sizetype for being valid
If (($SizeType -ne "B") -and ($SizeType -ne "KB") -and ($SizeType -ne "MB") -and ($SizeType -ne "GB") -and ($SizeType -ne "TB")) {
Write-Error -message "Size type is incorrect, needs to be KB, MB, or GB.`nPlease try again" -RecommendedAction "Stop"
exit 2
}
# If bytes, we don't need to add a modifier to sizediv to get the correct size, otherwise above it has already been concatenated correctly for other modifiers
If (($SizeType -eq "b") -or ($SizeType -eq "B")) {
$SizeDiv = $FolderSize
}
Get-ChildItem $InputFolder | sort Length | ForEach-Object {
#checks if loopsize equals zero, indicating a new folder should be created for output and change of location to move files
If ($LoopSize -eq 0) {
$LoopSize = $_.Length # sets loopsize equal to first file of this folder
$LoopOutput = "$OutputFolder\$LoopCount\" # sets name for new output folder
Write-host "LoopOutput: $LoopOutput`nFullName: $_.FullName"
NewFLCopy $_.FullName $LoopOutput
} # ends if
#checks if adding file will be less than or equal to alloted size and if so proceeds
ElseIf ((($LoopSize + $_.Length)/$SizeDiv) -le 1) {
$LoopSize = $_.Length + $LoopSize
Write-host "LoopOutput: $LoopOutput`nFullName: "$_.FullName
JustCopy $_.FullName $LoopOutput
} # ends elseif
#checking for adding current file would be greater than alloted space, if so resets for next itteration while copying current file into that new dir
ElseIf ((($LoopSize + $_.Length)/$SizeDiv) -gt 1) {
$LoopSize = $_.Length #resets loopsize
$LoopCount++ # incriments loopcount
$LoopOutput = "$OutputFolder\$LoopCount\" # sets name for new output folder
Write-host "LoopOutput: $LoopOutput`nFullName: "$_.FullName
NewFLCopy $_.FullName $LoopOutput
} # ends elseif
} # ends foreach loop
} # ends function
Aug 24, 2012
Subscribe to:
Posts (Atom)