Powershell Renaming Tool

Aug 25, 2025

About

This script has developed as a result of one of my work tasks where we need to scan files to PDF, rename then uplaod them onto a shared drive. In this instance the PDF files are for repairs and maintenance items towards a specific machine or unit.

The naming storage convention is not standardized and can vary since groups around the country are using the shared drive. The directories acan look as follows.

\Excavators\EX510
\Excavators\MB\EX510

The solution that I came up with was to start with standardizing the naming of files. Starting with the equipment name first then date then a brief summary of what the document is for example, EX510 2025-08-05 service

My script allows me to script to automate naming and copying of files from my local machine to the remote server while maintaining local copies. In this instance of the script I found it faster to search the drive in parallel rather than sequencially. This is due largely to the speed of the network share. The scipt allows me to preview one file at a time from the list of files in my unsorted folder. A promt is given for each file for a new file name. A name is given using the before mentioned naming convention. The equipment name is then extracted from the new name, then searched for in the list directories that was pulled earlier. Any items not found go to a default folder for manual matching. The preivew is closed, a copy with revised name is then sent to the server and the local copy is moved to the completed folder.

This strategy has saved me tens of minutes of copying and moving of files.

The Scripts

My script is as follows and uses two parts

Get Directories Async

[CmdletBinding()]
param (
    [Parameter()]
    [Int32]
    $ThrottleLimit = 8
)

$directories = (Get-ChildItem -Directory "Z:\Operations\Projects Maintenance").FullName
$results = [System.Collections.Concurrent.ConcurrentBag[string]]::new()
$throttleLimit = 8

$directories | Foreach-Object -Parallel {

    $dirs = Get-ChildItem -Directory $_
    $r = $Using:results

    foreach ($dir in $dirs) {
        $r.Add($dir)
    }

} -ThrottleLimit $throttleLimit

$directories += $results
return $directories

Renaming

function ClosePDF {
	$acrobat = New-Object -ComObject "AcroExch.App"
	$avDoc = $acrobat.GetActiveDoc()
	$avDoc.Close(0)
}

function WriteDashSeparator {
	Write-Host "-----------------------------------------------------------------"
}

function WriteDoubleDashSeparator {
	Write-Host "================================================================="
}

function WriteHelp {
	WriteDoubleDashSeparator
	Write-Host "The following commands are available:"
	Write-Host "n, next 	leave blank to continue to next"
	Write-Host "end,  exit 	exits the application"
	WriteDashSeparator
}

function WriteCurrentPDF {
	WriteDashSeparator
	Write-Host "Currently on $currentPDF of $pdfCount 	--help to get list of commands"
	Write-Host "Working File: "  $pdfOldName.Name
}

$pfdFiles = Get-ChildItem -Path ".\01_Unsorted" -Filter "*.pdf"
$pdfCount = $pfdFiles.Count

if ( $pfdFiles.Count -eq 0) {
	return
}

Start-Job -ScriptBlock { & "C:\Users\jchura\07_Scripts\GetDirectoriesAsync.ps1" -ThrottleLimit 8 } -Name GetMaintenanceData

$loadingMessage = "Loading"
$i = 0

Clear-Host

#Poll the job and update the console
[System.Console]::CursorVisible = $false
while ((get-job -name GetMaintenanceData).State -eq "Running") {

	switch ($i) {
		0 { $loadingMessage = "Loading   "; $i += 1; break }
		1 { $loadingMessage = "Loading.  ";	$i += 1; break }
		2 { $loadingMessage = "Loading.. ";	$i += 1; break }
		3 { $loadingMessage = "Loading..."; $i = 0; break }
		Default { $loadingMessage = "Loading..." }
	}

	Write-Host "`r$loadingMessage" -NoNewline
	Start-Sleep -Milliseconds 600
}

$equipmentDirectory = Receive-Job -name GetMaintenanceData
get-job -name GetMaintenanceData | Remove-Job

[System.Console]::CursorVisible = $true

for ($i = 0; $i -lt $pfdFiles.Count; $i++) {

	$pdfOldName = $pfdFiles[$i]
	Invoke-Item $pdfOldName.FullName

	$currentPDF = $i + 1
	WriteCurrentPDF
	$userInput = Read-Host 'Rename'

	ClosePDF

	if ($userInput -eq "--help") {
		WriteHelp
		$i--
		continue
	}

	if ($userInput -eq "" -or $userInput -eq "n" -or $userInput -eq "next") {
		continue
	}

	if ($userInput -eq 'end' -or $userInput -eq 'exit') {
		break
	}

	$unitNumber = $userInput.ToString().Substring(0, $userInput.ToString().IndexOf(" "))

	$destinationRemote = ""
	foreach ($dir in $equipmentDirectory) {
		if ($dir.FullName -like "*$unitNumber*") {
			$destinationRemote = $dir.FullName
			break
		}
	}

	if ($destinationRemote -eq "") {
		$destinationRemote = "Z:\Operations\Projects Maintenance\_MBToSort\$unitNumber"
		mkdir $destinationRemote | Out-Null
		$equipmentDirectory += $destinationRemote
	}

	$newName = "$userInput.pdf"

	$testPath = Test-Path "$destinationRemote\$newName"
	if ($testPath -eq $true) {
		Write-Host "File already exists can not copy. Please use a different name" -ForegroundColor Red
		$i--
		continue
	}

	Copy-Item "$pdfOldName" "$destinationRemote\$newName"
	Move-Item "$pdfOldName" ".\02_Sorted\$newName"
	Write-Host "File Moved to: $destinationRemote"
}

WriteDoubleDashSeparator
Read-Host 'Done'