I like to collect images for my desktop background, the problem is sometimes the image names don't represent what the image is. I decided to write a script that reads a text file that contains the source of the images to be renamed, and the base name. The script renames the images using the base name and increment counter and moves it to a portable drive.
Picture Database:
Pictures\Landscape,landscape
Pictures\Batman,batman
Script:
$picture_database_location = "$PSScriptRoot\pictures_database.txt"
$filter_ext = "jpg"
$rootDestination = "R:"
function determineIfFileorDirectoryExists
{ Param([string]$fileordirectory)
<#
Determine if a File or Directory Exists. If the file or directory doesn't exists,
it will throw an exception.
Args:
string: $fileordirectory - the variable that contains the file or directory
we're going to Test.
Returns:
None
#>
$fileordirectoryExists = Test-Path $fileordirectory
if($fileordirectoryExists -eq $false){
throw [System.IO.DirectoryNotFoundException] "Not Found: $fileordirectory"
}
}
function determineargumentCount
{ Param([string[]]$arraytoverify)
<#
Determines if the array length is correct. If not, it will throw and display the elements in the array.
Args:
string[]: $arraytoverify - the array to check for length.
Return:
None
#>
if ($arraytoverify.Length -ne 2){
throw "Argument count incorrect. # of Parameters: $arraytoverify.Length. `nProvided Parameters: $arraytoverify"
}
}
try{
# Before renaming any images we need to verify that the source location and destination exist.
determineIfFileorDirectoryExists -fileordirectory "$picture_database_location"
determineIfFileorDirectoryExists -fileordirectory "$rootDestination"
$picture_database = Get-Content $picture_database_location
ForEach ($image in $picture_database){
# Construct an array based on the split string
# $imagaeArray is constructed as follows:
# $imageArray[0]: The directory that contains the images to rename
# $imageArray[1]: The base name to rename the images
$imageArray = $image.Split(",")
determineargumentCount -arraytoverify $imageArray
# Construct the Source path with USERPROFILE environment variable and the first element in the array (the directory that contains our pictures)
$imagePath = Join-Path $env:USERPROFILE -ChildPath $imageArray[0]
determineIfFileorDirectoryExists -fileordirectory "$imagePath"
Set-Location -Path "$imagePath"
# Filter images by type and bulid a list with all the image names
$fileList = (Get-ChildItem $imagePath -Filter "*.jpg").Name
if($fileList.Length -gt 0){
# Construct a string representing the desination path
$DestinationPath = Join-Path $rootDestination -ChildPath $imageArray[0]
$doesDirectoryExist = Test-Path $DestinationPath
if($doesDirectoryExist -eq $false){
# - ErrorAction Stop - stops the script if the action take fails.
md "$DestinationPath" -ErrorAction Stop
determineIfFileorDirectoryExists -fileordirectory "$DestinationPath"
}
# Get the number of pictures in the destionation and set the counter.
[int]$fileCounter = (Get-ChildItem $DestinationPath -Filter "*.jpg").Length
ForEach ($imagetoRename in $fileList){
$fileCounter++
$renamed_file = "{0}_{1}.{2}" -f $imageArray[1],$fileCounter,$filter_ext
$imageDestination = Join-Path $DestinationPath -ChildPath $renamed_file
Write-Output "Image : {0} will be renamed to {1}" -f $imagetoRename, $imageDestination
Move-Item -Path "$imagetoRename" -Destination "$imageDestination"
}
}
}
Set-Location $PSScriptRoot
}
catch [System.IO.DirectoryNotFoundException]
{
Write-Output $PSItem.Exception.Message
}
catch [System.IO.IOException]
{
Write-Output $PSItem.Exception.Message
}
catch{
Write-Output $PSItem.Exception.Message
}
finally{
exit
}
Suppose there were two images in each of the source folders, it will rename them like this:
landscape_1.jpg
landscape_2.jpg
batman_1.jpg
batman_2.jpg
Areas of Concern:
- I use the variable
$imageArray
but I'm thinking simple classes might make it more readable instead of a bulky comment. - I'm aware a nested
for
loop isn't good for performance, but I'm unsure how to rewrite the code.
if(test-path $path)
and negated beingif(!(test-path $path))
because it returns a bool \$\endgroup\$ – Veskah Jul 25 '18 at 0:22