I have a whole bunch of users that are simply dragging emails from outlook on to a network share. That network SMB share gets sync'd with OneDrive and one drive hates to have leading spaces in a filename. Also some of the file names are so large that windows refuses to let me do anything with it (over 255 characters). I've found that simply renaming the files and taking out all the spaces does the trick. I have thousands of files in many sub directories and they keep adding more every day. I'd like a simple script that I can run everyday on the file server that scans all the *.msg files in a directory and all the sub directories and simply removes all the spaces. Can someone help me with a powershell script that will accomplish this?
-
I've tried using this script but it gives me lots of "Cannot create a file when that file already exists." errors. get-childitem -recurse *.msg | foreach { rename-item $_ $_.Name.Replace(" ", "") }Kris Fluckiger– Kris Fluckiger2018-11-08 19:03:23 +00:00Commented Nov 8, 2018 at 19:03
-
1this will take time - every day - and will take longer every day since more files are being added. can you fix the problem on the user side? if not that, then perhaps a filesystemwatcher that will [1st] shorten the names, and [2nd] remove the spaces [both with a name collision check]. ///// for this one-time fix, tho, i would look into using a dedicated utility like this one ... Introduction - Bulk Rename Utility — bulkrenameutility.co.uk/Main_Intro.phpLee_Dailey– Lee_Dailey2018-11-08 19:37:30 +00:00Commented Nov 8, 2018 at 19:37
-
Actually the above command worked perfectly for what I need to doKris Fluckiger– Kris Fluckiger2018-11-08 19:42:39 +00:00Commented Nov 8, 2018 at 19:42
-
i presume the "it worked perfectly" comment is aimed at me. [grin] ///// if it worked perfectly, then why are you asking for help ... and why did you post that i created errors?Lee_Dailey– Lee_Dailey2018-11-08 19:45:08 +00:00Commented Nov 8, 2018 at 19:45
2 Answers
The following variation of your own answer should perform significantly better:
Get-ChildItem -Recurse -Filter *.msg |
Rename-Item -NewName { $_.Name.Replace(' ', '') }
Note: You could add -File to Get-ChildItem in order to limit matches to files for extra robustness, but it actually slows down the command a bit (not much).
-Filterfilters at the source and is therefore much faster than using-Path(implied in your command) or-Include, which require PowerShell itself to examine all items.Using a delay-bind script block as the
-NewNameargument performs better than a call to theForEach-Objectcmdlet in whose script blockRename-Itemis called once every iteration.
Note:
There's a risk of name collisions.
Attempts to rename a file to itself - if the name contains no spaces - are quietly ignored.
Comments
This script works great:
get-childitem -recurse *.msg | foreach { rename-item $_ $_.Name.Replace(" ", "") }