Skip to content

Instantly share code, notes, and snippets.

@h8rt3rmin8r
Created February 9, 2026 00:48
Show Gist options
  • Select an option

  • Save h8rt3rmin8r/8adf4d08ce9ddd87547810813d360461 to your computer and use it in GitHub Desktop.

Select an option

Save h8rt3rmin8r/8adf4d08ce9ddd87547810813d360461 to your computer and use it in GitHub Desktop.
Rename screenshot files to a standardized naming convention
<#
.SYNOPSIS
Rename screenshot files to a standardized naming convention.
.DESCRIPTION
Rename screenshot files in a target directory to a standardized naming
convention. The script searches for screenshot files matching one or more of
the following patterns:
*<String>.<Extension>
*.<VideoExtension>.<Extension>
*.<VideoExtension><String>.<Extension>
Matching files are renamed to the following format:
*.<VideoExtension><ScreenshotSubstitutionString>.<Extension>
If no video file extension is detected in the screenshot filename, the
VideoExtensionFallback value is used instead.
For example, with default parameter values:
Input: movie_s.jpg -> Output: movie.mp4_screen.jpg
Input: movie.mkv.jpg -> Output: movie.mkv_screen.jpg
Input: movie.mkv_s.jpg -> Output: movie.mkv_screen.jpg
Input: movie.avi_s.jpg -> Output: movie.avi_screen.jpg
.PARAMETER Directory
The target directory containing the screenshot files to be renamed.
If not provided, the current working directory is used.
.PARAMETER String
The substring present in screenshot filenames that identifies them as
screenshots. This substring is replaced by ScreenshotSubstitutionString
during renaming.
Alias: s, substr, substring
Default: _s
.PARAMETER Verbosity
If set to $true, additional information will be printed to the console
during script execution.
Alias: v
Default: $true
.PARAMETER Extension
The file extension of all screenshot files to be renamed.
Alias: e
Default: jpg
.PARAMETER VideoExtensions
An array of video file extensions to consider when detecting video file
associations in screenshot filenames.
Alias: ve, videoext
Default: @('avi', 'mkv', 'mp4', 'webm', 'wmv')
.PARAMETER VideoExtensionFallback
The fallback video file extension to use when no matching video file
extension is found in a screenshot filename.
Default: mp4
.PARAMETER Help
Display the detailed help text for this script.
Alias: h
.EXAMPLE
.\Rename-Screenshots.ps1
Rename all screenshot files in the current directory using default settings.
.EXAMPLE
.\Rename-Screenshots.ps1 -Directory "C:\Videos\Screenshots"
Rename all screenshot files in the specified directory.
.EXAMPLE
.\Rename-Screenshots.ps1 -String "_thumb" -Extension "png"
Rename screenshot files that use a custom substring and file extension.
.EXAMPLE
.\Rename-Screenshots.ps1 -Directory "D:\Media" -VideoExtensions @('mp4','mkv') -Verbosity $false
Rename screenshots in D:\Media, considering only mp4 and mkv video
extensions, with console output suppressed.
#>
[CmdletBinding(SupportsShouldProcess=$false,ConfirmImpact='None',DefaultParameterSetName='Default')]
Param(
# The target directory containing the screenshot files to be renamed
[Parameter(Mandatory=$false,ParameterSetName='Default')]
[System.String]$Directory,
# Screenshot substring
[Parameter(Mandatory=$false,ParameterSetName='Default')]
[Alias("s","substr","substring")]
[System.String]$String = '_s',
# Script verbosity flag
[Parameter(Mandatory=$false,ParameterSetName='Default')]
[Parameter(Mandatory=$false,ParameterSetName='HelpText')]
[Alias('v')]
[System.Boolean]$Verbosity = $true,
# The file extension of all screenshot files to be renamed
[Parameter(Mandatory=$false,ParameterSetName='Default')]
[Alias("e")]
[System.String]$Extension = 'jpg',
# Video file extensions to consider when renaming screenshots
[Parameter(Mandatory=$false, ParameterSetName='Default')]
[Alias("ve","videoext")]
[System.Array]$VideoExtensions = @('avi', 'mkv', 'mp4', 'webm', 'wmv'),
# Fallback video file extension to use when no matching video file extension is found in screenshot file names
[System.String]$VideoExtensionFallback = 'mp4',
# A switch parameter to display the script help text
[Parameter(Mandatory=$true,ParameterSetName='HelpText')]
[Alias("h")]
[Switch]$Help
)
#______________________________________________________________________________
## Declare Functions
function ValidateIsDirectory {
<#
.SYNOPSIS
Test if a string is a valid directory reference
.DESCRIPTION
Test if a string is a valid directory reference.
Outputs are exactly "true" or "false".
.PARAMETER String
The string to be tested.
Alias: d,dir,directory,s,i,in,input,inputstring
.PARAMETER Verbosity
If set to $true, additional information will be printed to the console.
Alias: v
Default: $false
.EXAMPLE
ValidateIsDirectory -String "C:\bin\pslib"
#>
Param(
[Alias("d","dir","directory","s","i","in","input","inputstring")]
[System.String]$String,
[Alias("v")]
[System.Boolean]$Verbosity = $Verbosity
)
$thisSubFunction = "{0}" -f $MyInvocation.MyCommand
if (-Not($thisFunction)) {$thisFunction = $thisSubFunction} else {$thisFunction = -join("$thisFunction",":","$thisSubFunction")}
$StringTest = -join("x", "$String")
$StringTestLength = $StringTest.Length
$output = $null
if ($StringTestLength -eq 1) {
Vbs -Caller "$thisFunction" -Status e -Message "No input detected" -Verbosity $Verbosity
$output = $false
} elseif ($StringTestLength -gt 260) {
Vbs -Caller "$thisFunction" -Status e -Message "Input string is too long" -Verbosity $Verbosity
$output = $false
} else {
$output = (Test-Path -LiteralPath "$String" -PathType Container)
Vbs -Caller "$thisFunction" -Status i -Message "Validation of input ($String): $output" -Verbosity $Verbosity
}
return $output
}
function ValidateIsFile {
<#
.SYNOPSIS
Test if a string is a valid file reference
.DESCRIPTION
Test if a string is a valid file reference.
Outputs are exactly "true" or "false".
.PARAMETER String
The string to be tested.
Alias: f,file,s,i,in,input,inputstring
.PARAMETER Verbosity
If set to $true, additional information will be printed to the console.
Alias: v
Default: $false
.EXAMPLE
ValidateIsFile -String "C:\bin\pslib\main.ps1"
#>
Param(
[Alias("f","fil","s","i","in","input","inputstring")]
[System.String]
$String,
[Alias("v")]
[System.Boolean]
$Verbosity = $Verbosity
)
$thisSubFunction = "{0}" -f $MyInvocation.MyCommand
if (-Not($thisFunction)) {$thisFunction = $thisSubFunction} else {$thisFunction = -join("$thisFunction",":","$thisSubFunction")}
$StringTest = -join("x", "$String")
$StringTestLength = $StringTest.Length
$output = $null
if ($StringTestLength -eq 1) {
Vbs -Caller "$thisFunction" -Status e -Message "No input detected" -Verbosity $Verbosity
$output = $false
} elseif ($StringTestLength -gt 260) {
Vbs -Caller "$thisFunction" -Status e -Message "Input string is too long" -Verbosity $Verbosity
$output = $false
} else {
$output = (Test-Path -LiteralPath "$String" -PathType Leaf)
Vbs -Caller "$thisFunction" -Status i -Message "Validation of input ($String): $output" -Verbosity $Verbosity
}
return $output
}
function Vbs {
<#
.SYNOPSIS
Print structured and colorized verbosity and write formatted log messages
.DESCRIPTION
Print structured and colorized verbosity and write formatted log messages.
This function is designed to be used as a logging function for other library
functions and scripts. Care has been taken to ensure the portability of this
function so it can be easily implemented in other scripts and functions
unrelated to this library.
To-Do:
- Add a parameter to allow the inclusion of a process ID
- Add more granular control over the verbosity of the output
.PARAMETER Message
The message to be printed to the console and written to the log file.
.PARAMETER Caller
The name of the calling function or script. If the function is a sub-
function, then the name of the parent function should be included.
Syntax: "<Script>:<Function>:<Sub-Function>"
.PARAMETER Status
The status of the message
Allowed Values: INFO (i), ERROR (e), WARNING (w), DEBUG (d)
Default: INFO (i)
.PARAMETER LogDir
The directory in which the log file will be written. Normally this shouldn't
be changed.
Default: C:\bin\pslib\logs
.PARAMETER LibName
The name of the library or script that is calling this function. This is
used to identify the source of the log message. Normally this shouldn't be
changed.
Default: pslib
.PARAMETER VbsSessionID
The unique identifier for the current session. This is used to identify the
session in which the log message was generated. Normally this shouldn't be
changed.
Default: $LibSessionID
.PARAMETER Verbosity
If set to $true, the message will be printed to the console and written to
the log file. If set to $false, the message will be written to the log file
only.
Default: $true
.EXAMPLE
Vbs -Caller "$thisFunction" -Status info -Message "This is a test" -Verbosity $true
#>
Param(
[System.String]$Message,
[System.String]$Caller,
[System.String]$Status,
[Alias("LogDirectory")]
[System.String]$LogDir = "C:\bin\pslib\logs",
[Alias("LibraryName")]
[System.String]$LibName = "pslib",
[System.String]$VbsSessionID = $LibSessionID,
[Alias("v")]
[System.Boolean]$Verbosity = $Verbosity
)
function VbsFunctionStackTotalDepth {
# Calculate the total depth of the updated function stack
# Each non-numbered function is counted as 1 and each numbered function is
# counted as the number in the numeric suffix.
Param(
[System.String]$CurrentStack
)
# Trim whitespace and colon characters from the end of the stack string
$CurrentStack = $CurrentStack -replace "[:\s]+$", ""
# Split the current stack into an array
$CurrentStackArray = $CurrentStack -split ':'
# Initialize a variable to hold the total depth of the stack
$TotalDepth = [int]0
foreach ($function in $CurrentStackArray) {
if ($function -match '\d+') {
# If a numeric suffix is found, then increment the total depth by the numeric suffix
$TotalDepth += [int]$matches[0]
} else {
# If no numeric suffix is found, then increment the total depth by 1
$TotalDepth += [int]1
}
}
return $TotalDepth
}
function VbsLogPath {
# Derive the path to the current log file based on the current date
Param(
[System.String]$LogDir = "$LogDir"
)
$LogName = (Get-Date -UFormat "%Y_%m")
$LogFile = -join("$LogName", ".log")
$LogPath = -join("$LogDir", '\', "$LogFile")
return $LogPath
}
function VbsLogRealityCheck {
# Check if the log directory and log file exist. If they don't, then create them.
Param(
[System.String]$LogPath,
[System.String]$LogDir = "$LogDir"
)
$DCheck = (Test-Path -LiteralPath "$LogDir" -PathType Container)
$FCheck = (Test-Path -LiteralPath "$LogPath" -PathType Leaf)
if ($DCheck -eq $false) {New-Item -ItemType Directory -Path "$LogDir" -Force > $null}
if ($FCheck -eq $false) {New-Item -ItemType File -Path "$LogPath" -Force > $null}
return
}
function VbsLogWrite {
# Write the input string to the log file
Param(
[System.String]$LogPath,
[System.String]$InputString
)
Add-Content -Path "$LogPath" -Value "$InputString"
return
}
function VbsUpdateFunctionStack {
param (
[System.String]$CurrentStack,
[System.String]$NewFunction
)
function VbsUpdateFunctionStackExtractNumber {
# This sub-function discovers existing numeric suffixes in function names and returns only those
# values which are meaningful to assist in incrementing the current cycle count as needed.
Param(
[System.String]$String = $null
)
if ($String -match '\d+') {
$TempNumber = [int]$matches[0]
if ($TempNumber -lt 2) {
# If the numeric suffix is less than 2, then return 0
return [int]0
} else {
# If the numeric suffix is 2 or greater, subtract 1 and return the result
return [int]$TempNumber - [int]1
}
} else {
# If no numeric suffix is found, then return [int]0
return [int]0
}
}
# Split the current stack into an array
$stackArray = $CurrentStack -split ':'
# Initialize a new array to hold the updated stack
$newStackArray = @()
# Initialize variables to hold the previous function (starts out empty) and the count (starts at 1)
$previousFunction = ""
$count = [int]1
foreach ($function in $stackArray) {
$CycleIncrement = [int]1
$NumericSuffix = [int](VbsUpdateFunctionStackExtractNumber -String "$function")
# Check if the current function is the same as the previous function
if ($function -match "^$previousFunction(\(\d+\))?$") {
# The current function is the same as the previous function and may contain a numeric suffix
# Add the CycleIncrement to the NumericSuffix and add that result to $count
[int]$LastCount = [int]$count
[int]$CycleCount = [int]$NumericSuffix + [int]$CycleIncrement
[int]$count = [int]$CycleCount + [int]$LastCount
# Update the last function in the updated stack with the new count
$newStackArray[-1] = "$previousFunction($count)"
} else {
# The current function is different from the previous function
# Add the numeric suffix of the current function to [int]1 (if a numeric suffix exists) and reset the count to the result
$count = $NumericSuffix + $CycleIncrement
# Add the current function to the updated stack
$newStackArray += $function
}
$previousFunction = $function -replace "\(\d+\)$", ""
}
# Check if the new function is the same as the last function in the updated stack
if ($newStackArray[-1] -match "^$NewFunction(\(\d+\))?$") {
# The new function is the same as the last function in the updated stack and may contain a numeric suffix
if ($newStackArray[-1] -match "\((\d+)\)$") {
# If it does, increment the count and add the numeric suffix to $count
$count = [int]$matches[1] + 1
$newStackArray[-1] = "$NewFunction($count)"
} else {
# If it doesn't, add the function to the stack with a numeric suffix of 2
$newStackArray[-1] = "$NewFunction(2)"
}
} else {
# If the new function is not the same as the last function in the updated stack, add it to the stack
$newStackArray += $NewFunction
}
# Join the updated stack array back into a string
return ($newStackArray -join ':')
}
# Create the timestamp field
$epochStart = Get-Date 01.01.1970
$tA = $([DateTimeOffset]::Now.ToUnixTimeMilliseconds())
$tAmsStamp = ($epochStart + ([System.TimeSpan]::frommilliseconds($tA))).ToLocalTime()
$tB = $tAmsStamp.ToString("yyyy-MM-dd HH:mm:ss.fffzzz")
$t = -join("$tA", "|", "$tB", "|")
$tV = -join("$tB", " ")
# Create the ID field
$x = -join("$VbsSessionID", "|")
$xV = -join("$VbsSessionID", " ")
# Create the status field
if (-Not($Status)) {$Status = "X"}
$s = $Status.toUpper()
if ($s -eq "X" -or $s -eq "U" -or $s -eq "UNKNOWN") {
$s = "[INFO][UNKNOWN]"
$sV = "[ UNKNOWN ] "
$sColor = "DarkGray"
} elseif ($s -eq "I" -or $s -eq "INF" -or $s -eq "INFO") {
$s = "[INFO]"
$sV = "[ INFO ] "
$sColor = "Gray"
} elseif ($s -eq "E" -or $s -eq "ERR" -or $s -eq "ERROR") {
$s = "[ERROR]"
$sV = "[ ERROR ] "
$sColor = "DarkRed"
} elseif ($s -eq "C" -or $s -eq "CRIT" -or $s -eq "CRITICAL") {
$s = "[ERROR][CRITICAL]"
$sV = "[ CRITICAL ] "
$sColor = "Magenta"
} elseif ($s -eq "W" -or $s -eq "WARN" -or $s -eq "WARNING") {
$s = "[WARN]"
$sV = "[ WARNING ] "
$sColor = "DarkYellow"
} elseif ($s -eq "D" -or $s -eq "DEB" -or $s -eq "DEBUG") {
$s = "[DEBUG]"
$sV = "[ DEBUG ] "
$sColor = "DarkCyan"
} elseif ($s -eq "S" -or $s -eq "SUCCESS" -or $s -eq "OK" -or $s -eq "DONE" -or $s -eq "COMPLETE" -or $s -eq "G" -or $s -eq "GOOD") {
$s = "[INFO][SUCCESS]"
$sV = "[ SUCCESS ] "
$sColor = "DarkGreen"
} else {
$s = "[INFO]"
$sV = "[ INFO ] "
$sColor = "DarkGray"
}
# Create the caller field
$c = "$Caller"
$cTest = -join("x", "$c")
if ("$cTest" -eq "x" -or $c -eq "$LibName") {
## The caller is empty or is $LibName
$cUpdate = $LibName
$c = -join("$LibName",":")
} else {
## The caller isn't empty and isn't "$LibName".
## Before doing anything ...
## Make sure $c doesn't end with ":"
if ($c -match ":$") {
$c = $c -replace ":$", ""
}
## Make sure $c doesn't begin with "$LibName(" and end with ")"
$MatchString = -join("^","$LibName", "\(")
if ($c -match "$MatchString" -and $c -match "\)$") {
# Simply remove the "$LibName(" and ")" from the caller and continue processing as normal
$c = $c -replace "$MatchString", "" -replace "\)$", ""
}
## We need to know if it is a single caller or a sub-function (parse for ':')
$cSplit = $c -split ':'
## Even if the caller contains no ':' characters, the final element of the split array will be the caller
$cLatest = $cSplit[-1]
## Take action based on the number of elements in the split array
if ($cSplit.Length -gt 1) {
### The caller is a sub-function. We need to update the stack
### To do this we must remove the final string from the stack (the current caller)
### but avoid removing any duplicates of the current caller which might exist in the stack
$cOthers = $cSplit[0..($cSplit.Length - 2)] -join ':'
### Now we can update the stack using the function: VbsUpdateFunctionStack
$cUpdate = (VbsUpdateFunctionStack -CurrentStack "$cOthers" -NewFunction "$cLatest")
$c = -join("$LibName", '(', "$cUpdate", '):')
} else {
### The caller is a single function so we don't need to update the stack
$cUpdate = $c
$c = -join("$LibName", '(', "$Caller", '):')
}
}
$cDepth = (VbsFunctionStackTotalDepth -CurrentStack "$cUpdate")
$c = -join("$c", " ")
$cV = -join("$LibName",'(',"$cDepth",')',': ')
# Create the message field
$m = "$Message"
$mTest = -join("x", "$m")
if ("$mTest" -eq "x") {$m = '...'}
$mV = "$m"
# Create verbose and silent versions of the final output string
$o = -join("$t","$x","$s","$c","$m")
$oV = -join("$tV","$xV","$sV","$cV","$mV")
# Derive the absolute path to the current log file and make sure it exists and then send outputs as needed
$l = (VbsLogPath -LogDir "$LogDir")
VbsLogRealityCheck -LogPath "$l" -LogDir "$LogDir"
if ($Verbosity -eq $false) {
# Write to the log only (no output to host)
VbsLogWrite -LogPath "$l" -InputString "$o"
} else {
# Write to the log AND print to the host
VbsLogWrite -LogPath "$l" -InputString "$o"
Write-Host "$oV" -ForegroundColor $sColor
}
return
}
#______________________________________________________________________________
## Declare Variables and Arrays
$Sep = [IO.Path]::DirectorySeparatorChar
$SessionToken = $([DateTimeOffset]::Now.ToUnixTimeMilliseconds())
$LibSessionID = [System.GUID]::NewGuid().ToString().Replace('-','')
$HereNow = ($PWD | Select-Object -Expand Path) -join '`n'
$ThisScriptPath = $MyInvocation.MyCommand.Path
$ThisScriptName = $MyInvocation.MyCommand.Name
$ThisScript = $ThisScriptPath | Split-Path -Leaf
$thisFunction = "{0}" -f $MyInvocation.MyCommand
$ScreenshotSubstitutionString = '_screen'
#______________________________________________________________________________
## Execute Operations
# Catch help text requests
if (($Help) -or ($PSCmdlet.ParameterSetName -eq 'HelpText')) {
Get-Help $ThisScriptPath -Detailed
exit
}
# If $Directory is not provided, use the current directory
if ((-Not($Directory)) -or ($Directory -eq "")) {
$Directory = $HereNow
}
# If $Directory does not exist, print an error message and exit
if (-Not(ValidateIsDirectory -String "$Directory" -Verbosity $true)) {
Vbs -Caller "$thisFunction" -Status e -Message "The provided directory does not exist: $Directory" -Verbosity $Verbosity
exit
}
# Build search patterns for screenshot files
$SearchPatterns = @()
# Pattern 1: *<String>.<Extension> (e.g., *_s.jpg)
$SearchPatterns += -join("*", "$String", ".", "$Extension")
foreach ($ve in $VideoExtensions) {
# Pattern 2: *.<VideoExtension>.<Extension> (e.g., *.mkv.jpg)
$SearchPatterns += -join("*", ".", "$ve", ".", "$Extension")
# Pattern 3: *.<VideoExtension><String>.<Extension> (e.g., *.mkv_s.jpg)
$SearchPatterns += -join("*", ".", "$ve", "$String", ".", "$Extension")
}
# Remove duplicate patterns
$SearchPatterns = $SearchPatterns | Select-Object -Unique
Vbs -Caller "$thisFunction" -Status i -Message "Search patterns: $($SearchPatterns -join ', ')" -Verbosity $Verbosity
Vbs -Caller "$thisFunction" -Status i -Message "Searching directory: $Directory" -Verbosity $Verbosity
# Collect all matching files
$ScreenshotFiles = @()
foreach ($pattern in $SearchPatterns) {
$PatternMatches = Get-ChildItem -LiteralPath "$Directory" -Filter "$pattern" -File -ErrorAction SilentlyContinue
if ($PatternMatches) {
$ScreenshotFiles += $PatternMatches
}
}
# Remove duplicates (a file might match multiple patterns)
$ScreenshotFiles = $ScreenshotFiles | Sort-Object -Property FullName -Unique
if ($ScreenshotFiles.Count -eq 0) {
Vbs -Caller "$thisFunction" -Status w -Message "No screenshot files found matching the search patterns" -Verbosity $Verbosity
exit
}
Vbs -Caller "$thisFunction" -Status i -Message "Found $($ScreenshotFiles.Count) screenshot file(s) to process" -Verbosity $Verbosity
# Process each screenshot file
$RenameCount = 0
$SkipCount = 0
$ErrorCount = 0
foreach ($file in $ScreenshotFiles) {
$OriginalName = $file.Name
# Remove the screenshot file extension from the filename for parsing
$WorkingName = $OriginalName -replace ([regex]::Escape(".$Extension") + '$'), ''
# Attempt to detect a video extension and extract the base name
$DetectedVideoExtension = $null
$BaseName = $null
foreach ($ve in $VideoExtensions) {
$PatternWithString = [regex]::Escape(".$ve") + [regex]::Escape("$String") + '$'
$PatternWithoutString = [regex]::Escape(".$ve") + '$'
if ($WorkingName -match $PatternWithString) {
# Matched Pattern 3: base.videoext<String> (e.g., movie.mkv_s)
$DetectedVideoExtension = $ve
$BaseName = $WorkingName -replace $PatternWithString, ''
break
} elseif ($WorkingName -match $PatternWithoutString) {
# Matched Pattern 2: base.videoext (e.g., movie.mkv)
$DetectedVideoExtension = $ve
$BaseName = $WorkingName -replace $PatternWithoutString, ''
break
}
}
if (-not $DetectedVideoExtension) {
# No video extension detected; check for Pattern 1: base<String> (e.g., movie_s)
$StringPattern = [regex]::Escape("$String") + '$'
if ($WorkingName -match $StringPattern) {
$BaseName = $WorkingName -replace $StringPattern, ''
$DetectedVideoExtension = $VideoExtensionFallback
} else {
# Filename does not match any expected pattern
Vbs -Caller "$thisFunction" -Status w -Message "Could not parse filename pattern: $OriginalName" -Verbosity $Verbosity
$SkipCount++
continue
}
}
# Construct the new filename: base.videoext_screen.ext
$NewName = -join("$BaseName", ".", "$DetectedVideoExtension", "$ScreenshotSubstitutionString", ".", "$Extension")
# Skip if the name is already correct
if ($NewName -eq $OriginalName) {
Vbs -Caller "$thisFunction" -Status w -Message "Skipping (already renamed): $OriginalName" -Verbosity $Verbosity
$SkipCount++
continue
}
# Skip if a file with the target name already exists
$NewPath = Join-Path -Path "$Directory" -ChildPath "$NewName"
if (Test-Path -LiteralPath "$NewPath") {
Vbs -Caller "$thisFunction" -Status w -Message "Skipping (target exists): $OriginalName -> $NewName" -Verbosity $Verbosity
$SkipCount++
continue
}
# Rename the file
try {
Rename-Item -LiteralPath $file.FullName -NewName "$NewName" -ErrorAction Stop
Vbs -Caller "$thisFunction" -Status s -Message "Renamed: $OriginalName -> $NewName" -Verbosity $Verbosity
$RenameCount++
} catch {
Vbs -Caller "$thisFunction" -Status e -Message "Failed to rename: $OriginalName -> $NewName ($_)" -Verbosity $Verbosity
$ErrorCount++
}
}
# Print summary
Vbs -Caller "$thisFunction" -Status i -Message "Processing complete. Renamed: $RenameCount, Skipped: $SkipCount, Errors: $ErrorCount" -Verbosity $Verbosity
#______________________________________________________________________________
## End of script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment