Advertisement
joedigital

ps-rename files with leading spaces

May 15th, 2025
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .SYNOPSIS
  3.     Renames files that have a leading space in their filename.
  4. .DESCRIPTION
  5.     This script searches for files within a specified directory (and optionally its subdirectories)
  6.     whose names begin with one or more space characters. It then renames these files by
  7.     removing all leading spaces.
  8.     Includes a -WhatIf parameter to preview changes without applying them.
  9. .PARAMETER Path
  10.     The directory path to search for files. If not specified, it defaults to the current directory.
  11. .PARAMETER Recurse
  12.     If specified, the script will search for files in all subdirectories of the given Path.
  13. .PARAMETER WhatIf
  14.     If specified, the script will display the operations it would perform without actually
  15.     executing them. This allows for a preview of the changes.
  16. .EXAMPLE
  17.     .\Rename-LeadingSpaceFiles.ps1 -Path "C:\MyDocuments\WorkFiles"
  18.     Description: Renames files with leading spaces directly under "C:\MyDocuments\WorkFiles".
  19.  
  20. .EXAMPLE
  21.     .\Rename-LeadingSpaceFiles.ps1 -Path "D:\Photos" -Recurse
  22.     Description: Renames files with leading spaces in "D:\Photos" and all its subfolders.
  23.  
  24. .EXAMPLE
  25.     .\Rename-LeadingSpaceFiles.ps1 -Path "C:\Temp" -Recurse -WhatIf
  26.     Description: Shows which files in "C:\Temp" and its subfolders would be renamed,
  27.                  but does not actually rename them.
  28.  
  29. .EXAMPLE
  30.     Get-ChildItem 'C:\Downloads' | .\Rename-LeadingSpaceFiles.ps1 -Recurse
  31.     Description: Gets items from C:\Downloads and pipes them to the script.
  32.                  The script will then process only the files (not directories) from the input.
  33.                  If a directory is piped, it will be processed as if -Path was used.
  34.  
  35. .OUTPUTS
  36.     None by default, unless -Verbose or -WhatIf is used.
  37.     When -WhatIf is used, it outputs messages indicating what rename operations would occur.
  38. .NOTES
  39.     Author: Gemini
  40.     Date: 2025-05-15
  41.     It's highly recommended to run the script with -WhatIf first to ensure it targets the correct files.
  42.     The script handles filenames with multiple leading spaces by removing all of them.
  43. #>
  44. [CmdletBinding(SupportsShouldProcess = $true)] # Enables -WhatIf and -Confirm
  45. param (
  46.     [Parameter(Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
  47.     [string]$Path = (Get-Location).Path, # Default to current directory
  48.  
  49.     [Parameter()]
  50.     [switch]$Recurse
  51. )
  52.  
  53. begin {
  54.     Write-Verbose "Script started."
  55.     Write-Verbose "Target Path: $Path"
  56.     Write-Verbose "Recurse: $($Recurse.IsPresent)"
  57.     $filesProcessed = 0
  58.     $filesRenamed = 0
  59. }
  60.  
  61. process {
  62.     # Determine if the input $Path is a directory or a file
  63.     # This allows the script to handle piped input from Get-ChildItem more gracefully
  64.     $itemsToProcess = @()
  65.     if (Test-Path -Path $Path -PathType Container) {
  66.         # Path is a directory, get child items (files)
  67.         $getChildItemParams = @{
  68.             Path = $Path
  69.             File = $true # Only get files
  70.         }
  71.         if ($Recurse) {
  72.             $getChildItemParams.Recurse = $true
  73.         }
  74.         try {
  75.             $itemsToProcess = Get-ChildItem @getChildItemParams -ErrorAction SilentlyContinue
  76.         }
  77.         catch {
  78.             Write-Error "Error accessing path '$Path': $($_.Exception.Message)"
  79.             return
  80.         }
  81.     }
  82.     elseif (Test-Path -Path $Path -PathType Leaf) {
  83.         # Path is a file (likely from pipeline)
  84.         $itemsToProcess = Get-Item -Path $Path -ErrorAction SilentlyContinue
  85.     }
  86.     else {
  87.         Write-Warning "Path '$Path' does not exist or is not a file/directory. Skipping."
  88.         return
  89.     }
  90.  
  91.  
  92.     foreach ($FileItem in $itemsToProcess) {
  93.         $filesProcessed++
  94.         $OriginalFullName = $FileItem.FullName
  95.         $OriginalName = $FileItem.Name
  96.         $DirectoryPath = $FileItem.DirectoryName
  97.  
  98.         # Check if the filename starts with a space
  99.         if ($OriginalName -match "^\s+.*") {
  100.             Write-Verbose "Found file with leading space(s): '$OriginalFullName'"
  101.  
  102.             # Remove leading space(s) from the filename
  103.             # The TrimStart() method removes all occurrences of specified characters from the beginning of a string.
  104.             # If no characters are specified, it removes whitespace.
  105.             $NewName = $OriginalName.TrimStart()
  106.  
  107.             # Ensure the new name is not empty or just spaces (which TrimStart would make empty)
  108.             if ([string]::IsNullOrWhiteSpace($NewName)) {
  109.                 Write-Warning "Skipping file '$OriginalFullName' as removing leading spaces would result in an empty filename."
  110.                 continue
  111.             }
  112.  
  113.             # Construct the new full path
  114.             $NewFullName = Join-Path -Path $DirectoryPath -ChildPath $NewName
  115.  
  116.             # Check if a file with the new name already exists
  117.             if (Test-Path -Path $NewFullName) {
  118.                 Write-Warning "Skipping rename of '$OriginalFullName': A file named '$NewName' already exists in '$DirectoryPath'."
  119.                 continue
  120.             }
  121.  
  122.             Write-Host "Attempting to rename '$OriginalName' to '$NewName' in directory '$DirectoryPath'"
  123.  
  124.             # Rename the file
  125.             # The $PSCmdlet.ShouldProcess method handles the -WhatIf and -Confirm parameters.
  126.             if ($PSCmdlet.ShouldProcess($OriginalFullName, "Rename to '$NewFullName'")) {
  127.                 try {
  128.                     Rename-Item -Path $OriginalFullName -NewName $NewName -ErrorAction Stop
  129.                     Write-Host "Successfully renamed '$OriginalFullName' to '$NewFullName'" -ForegroundColor Green
  130.                     $filesRenamed++
  131.                 }
  132.                 catch {
  133.                     Write-Error "Failed to rename '$OriginalFullName' to '$NewName'. Error: $($_.Exception.Message)"
  134.                 }
  135.             }
  136.         }
  137.         else {
  138.             Write-Verbose "File '$OriginalFullName' does not start with a space. Skipping."
  139.         }
  140.     }
  141. }
  142.  
  143. end {
  144.     Write-Verbose "Script finished."
  145.     Write-Host "Total files scanned: $filesProcessed"
  146.     Write-Host "Total files renamed: $filesRenamed"
  147.     if ($PSCmdlet.ShouldProcess("Summary", "Display summary of operations")) {
  148.         # This block is mainly for -WhatIf scenarios to confirm completion.
  149.         if ($filesRenamed -eq 0 -and $filesProcessed -gt 0) {
  150.             Write-Host "No files required renaming."
  151.         } elseif ($filesProcessed -eq 0) {
  152.             Write-Host "No files found to process in the specified path(s)."
  153.         }
  154.     }
  155. }
  156.  
Tags: Gemini
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement