KMckenzie
KMckenzie

Reputation: 33

PowerShell with Square Brackets

So, I've read a lot about the Square Bracket [] problems with renaming a file with Powershell. Most of these post talked about removing the brackets. I have a need to keep the brackets, and just remove the file extension .crypted(CryptoLocker). There are 400,000+ files and 172,000+ folders. I tried the Move-Item cmdlet...

Get-ChildItem c:\temp *.crypted | Move-Item -LiteralPath {$_.FullName.Replace(".crypted", "")} 

I get an error Move-Item : Cannot move item because the item at 'C:\temp\Rule [1].txt' does not exist

As you might be able to see the new path is correct, but it says it doesn't exist. I'm stumped. Any help would be greatly appreciated.

Upvotes: 3

Views: 4051

Answers (2)

Kory Gill
Kory Gill

Reputation: 7163

Debugging tip: when you have issues with code and you are using the pipeline, rewrite the code to not use the pipeline and break the problem down into steps and insert debugging aids to help troubleshoot. Could be Write-Host, saving to temp variables, etc.

For me, your Move-Item as written does not work, and I get a similar error message.

Here is what I arrived at as a solution:

Get-ChildItem *.crypted | ForEach-Object {Move-Item -LiteralPath $_.FullName $_.FullName.Replace('.crypted', '')}

Note that I pass 2 arguments to Move-Item after -LiteralPath, and there are no backticks needed or anything out of the ordinary.

Here is my work to demonstrate the issue, and my solution.

D:\test\move> dir


    Directory: D:\test\move


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/17/2016   9:21 PM         100347 file [1].pdf


D:\test\move> Get-ChildItem *.pdf | Move-Item -LiteralPath {$_.FullName.Replace('1', '2')}
Move-Item : Cannot move item because the item at 'D:\test\move\file [2].pdf' does not exist.
At line:1 char:23
+ ... ldItem *.pdf | Move-Item -LiteralPath {$_.FullName.Replace('1', '2')}
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Move-Item], PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.MoveItemCommand

D:\test\move> Get-ChildItem *.pdf | ForEach-Object {Move-Item -LiteralPath $_.FullName $_.FullName.Replace('1', '2')}
D:\test\move> dir


    Directory: D:\test\move


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/17/2016   9:21 PM         100347 file [2].pdf

Works on the extention too...

D:\test\move> dir


    Directory: D:\test\move


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/17/2016   9:21 PM         100347 file [2].txt.crypted


D:\test\move> Get-ChildItem *.crypted | ForEach-Object {Move-Item -LiteralPath $_.FullName $_.FullName.Replace('.crypted', '')}
D:\test\move> dir


    Directory: D:\test\move


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        3/17/2016   9:21 PM         100347 file [2].txt


D:\test\move>

Upvotes: 2

vonPryz
vonPryz

Reputation: 24071

In order to work around the brackets, escape it with double backtick `` like so,

gci c:\temp\brackets *.crypted | % { 
  move-item $_.FullName.replace('[','``[') $_.FullName.Replace(".crypted", "")
}

Doubling the backtick is needed so that a backtick is passed and not interpreted as escape character to the bracket. This is a bit messy, so it looks like a bug in Powershell or very surprising a behavior.

Upvotes: 2

Related Questions