tsunami

log in
history

Move-Item with wildcard literals

Luke Breuer
2018-08-16 18:25 UTC

Summary

If a variable name has wildcard characters in it, Move-Item treats them as wildcards, which is as one would expect. Use -LiteralPath if the wildcard characters are part of the filename (below: [a].txt).

What is more surprising is that the result from Get-ChildItem, a FileInfo object, is treated as a string and not an object when passed to Move-Item as a parameter instead of via the pipeline. PowerShell is supposed to work with objects when it can, not just strings.
Code
$ErrorActionPreference = 'Stop'

$dir = mkdir tmp
cd $dir

$name = '[a].txt'
function is_there() { if ((ls -LiteralPath $name -ea Ignore).Count -eq 1) { "still exists"} else { "moved" } }

#"" | out-file $name  # Cannot perform operation because the wildcard path [a] did not resolve to a file.
[System.IO.File]::WriteAllText("$PWD$name", "")
$new = mkdir new

mv $name $new
Write-Host "mv $name $new: $(is_there)" -ForegroundColor Green

$f = ls "*a*"
mv $f $new
Write-Host "mv $f $new: $(is_there)" -ForegroundColor Green

mv -LiteralPath $name $new
Write-Host "mv -LiteralPath $name $new: $(is_there)" -ForegroundColor Green
mv $new* .

ls -LiteralPath $name | mv -Destination $new
Write-Host "ls -LiteralPath $name | mv -Destination $new: $(is_there)" -ForegroundColor Green
mv $new* .

ls -LiteralPath $name | % { mv $_ $new }
Write-Host "ls -LiteralPath $name | % { mv $_ `$new }: $(is_there)" -ForegroundColor Green

cd $dir.Parent.FullName
rm -Recurse $dir

yields:

mv $name $new: still exists
mv $f $new: still exists
mv -LiteralPath $name $new: moved
ls -LiteralPath $name | mv -Destination $new: moved
ls -LiteralPath $name | % { mv $_ $new }: still exists