# Script to find and remove 8.3 shortnames from files and folders. # # Requirements: # -This script must be run under an account with local admin rights on the local file server. # -8.3 SHORTNAMES MUST BE DISABLED ON THE FILE SERVER PRIOR TO RUNNING THIS SCRIPT. (fsutil.exe behavior set disable8dot3 1) # -PowerShell v5.1 is required (https://docs.microsoft.com/en-us/powershell/wmf/5.1/install-configure) # # Usage: # .\StripLocal83Shortnames.ps1 -Path -LogPath # -PrintToScreen -ReportOnly # # Log files # \strip8.3.log # \strip8.3_error.log # \strip8.3_skip.log # # Version: 005 # Authors: Martin Sauter and Matt Marsala # param ( [Parameter(Mandatory = $true)] [String] $Path, [Parameter(Mandatory = $false)] [String] $LogPath = "C:\log", [Parameter(Mandatory = $false)] [Switch] $PrintToScreen, [Parameter(Mandatory = $false)] [Switch] $ReportOnly ) # Load external libraries... [System.Reflection.Assembly]::LoadWithPartialName(“System.Diagnostics”) if ($LogPath.EndsWith("\\")) { #Do nothing } else { $LogPath += "\\" } Get-ChildItem -Path $LogPath -Include *.log -File -Recurse | foreach { $_.Delete()} $LogFile = $LogPath + "strip8.3.log" $ERRLogFile = $LogPath + "strip8.3_error.log" $SkipLogFile = $LogPath + "strip8.3_skip.log" $global:LogFilecnt = 0 $global:ERRLogFilecnt = 0 $global:SkipLogFilecnt = 0 # Setup logging $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" New-Item $LogFile -type file -force New-Item $ERRLogFile -type file -force New-Item $SkipLogFile -type file -force $Log = $DateStamp + ": " + "StripLocal83Shortnames v005 starting..." $Log >> $LogFile $Log >> $ERRLogFile $Log >> $SkipLogFile $Log = "PowerShell Version is " + $PSVersionTable.PSVersion $Log >> $LogFile $Error.Clear() $sw = New-Object System.Diagnostics.Stopwatch $sw.Start() function write_log { if ((Get-Item $LogFile).length -gt 100mb) { $LogFilenew = $LogFile + $global:LogFilecnt Rename-Item -LiteralPath $LogFile -NewName $LogFilenew -Force New-Item $LogFile -type file -force $global:LogFilecnt++ $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $LogFile }else{ $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $LogFile } if ($PrintToScreen -eq $true){ Write-Host $Log } } function write_error_log { if ((Get-Item $ERRLogFile).length -gt 100mb) { $ERRLogFilenew = $ERRLogFile + $global:ERRLogFilecnt Rename-Item -LiteralPath $ERRLogFile -NewName $ERRLogFilenew -Force New-Item $ERRLogFile -type file -force $global:ERRLogFilecnt++ $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $ERRLogFile }else{ $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $ERRLogFile } if ($PrintToScreen -eq $true){ Write-Host $Log } } function write_skip_log { if ((Get-Item $SkipLogFile).length -gt 100mb) { $SkipLogFilenew = $SkipLogFile + $global:SkipLogFilecnt Rename-Item -LiteralPath $SkipLogFile -NewName $SkipLogFilenew -Force $global:SkipLogFilecnt++ New-Item $SkipLogFile -type file -force $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $SkipLogFile }else{ $DateStamp = get-date -uformat "%d.%m.%Y@%H:%M:%S" $Log = $DateStamp + ": " + $Log_Message $Log >> $SkipLogFile } if ($PrintToScreen -eq $true) { Write-Host $Log } } if (($PSVersionTable.PSVersion.Major -ge 5) -and ($PSVersionTable.PSVersion.Minor -ge 1)) { $Log_Message= "The correct version of PowerShell is available. Continuing..." write_log } else { $Log_Message = "This script requires PowerShell v5.1 or later. Exiting..." write_log [Environment]::Exit(1) } #Needed to check on short names.. $fso = New-Object -ComObject Scripting.FileSystemObject if ($Path.StartsWith("\\?\")) { $WorkingPath = $Path } else { $WorkingPath = "\\?\" + $Path } $Log_Message = "Path to scan is [$WorkingPath]" write_log try{ Get-ChildItem -LiteralPath $WorkingPath -Recurse -Force -ErrorAction 'SilentlyContinue' | ForEach-Object { if (Test-Path -LiteralPath $_.FullName -PathType Container) { # Folder $workdir = $_.FullName $path = $_.Name + "_1" $new_name = $_.FullName + "_1" $fso = New-Object -ComObject Scripting.FileSystemObject try { $test = select-string -pattern ~ -InputObjec $fso.getfolder($workdir).ShortName } catch { $Log_Message = "Exception for Directory [$workdir] : $_" write_error_log } if ($test){ if ($ReportOnly) { $Log_Message = "REPORT ONLY - Found Directoy: [$workdir] with a short name " + $test.Line write_log } else { $Log_Message = "Working on Directoy: [$workdir] as it has short name " + $test.Line write_log try { Rename-Item -LiteralPath $_.FullName -NewName $path -Force -ErrorAction 'Stop' #-WhatIf Rename-Item -LiteralPath $new_name -NewName $_.Name -Force -ErrorAction 'Stop' #-WhatIf } catch { $Log_Message = "Exception for Directory [$workdir] : $_" write_error_log } } } else { $Log_Message = "Skip Directory as no short name found for [$workdir]" write_skip_log } } elseif (Test-Path -LiteralPath $_.FullName -PathType Leaf) { # File if ($Error){ $Log_Message = $Error[0].Exception write_error_log $Error.Clear() } $workfile = $_.FullName $tmpfile = $_.FullName + "_1" try{ $test = select-string -pattern ~ -InputObjec $fso.getfile($workfile).ShortName } catch { $Log_Message = "Exception for Directory [$workdir] : $_" write_error_log } if ($test){ if ($ReportOnly) { $Log_Message = "REPORT ONLY - Found File: [$workfile] with a short name " + $test.Line write_log } else { $Log_Message = "Working on File: [$workfile] as it has short name " + $test.Line write_log try{ Rename-Item -LiteralPath $_.FullName -NewName $tmpfile -Force -ErrorAction 'Stop' #-WhatIf Rename-Item -LiteralPath $tmpfile -NewName $_.Name -Force -ErrorAction 'Stop' #-WhatIf } catch { $Log_Message = "Exception for File [$workfile] : $_" write_error_log } } }else{ $Log_Message = "Skip File as no short name found: [$workfile]" write_skip_log } } } } catch { $Log_Message = "General Exception: $_" write_error_log } $sw.Stop() $elHours = $sw.Elapsed.Hours $elMinutes = $sw.Elapsed.Minutes $elSeconds = $sw.Elapsed.Seconds $Log_Message = "Script complete after $elHours hours, $elMinutes minutes, $elSeconds seconds" write_log