Question:
I would like to scan and move folders (and sub folders or even deeper) from one folder to another using Powershell.
Currently I’m using this pipe of commands.
1 2 |
Get-ChildItem -recurse -path sub\WORK -filter "* OK" | Where-Object { $_.PSIsContainer } | foreach { Move-Item -path $_ -destination sub\OK } |
Unfortunately it doesn’t work because the found results are relative to .\sub\WORK
, when trying to move them Move-Item complains that the folders are not in the current folder:
1 2 |
Move-Item : Cannot find path 'C:\TMP\2011-12-12 test 2 OK' because it does not exist. |
I expect that $_ would contain: 'C:\TMP\sub\WORK\2011-12-12 test 2 OK'
because these are objects in Powershell and no strings like in Linux.
Answer:
In case you use Get-ChildItem
, be very careful. The best way is to pipe the objects to Move-Item
and you don’t need to think about it more:
1 2 |
Get-ChildItem -recurse -path sub\WORK -filter "* OK" | Where-Object { $_.PSIsContainer } | Move-Item -destination sub\OK |
(no need to use Foreach-Object
)
The main reason why I’m answering is this one: Get-ChildItem
constructs object differently, depending on the parameters. Look at examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS C:\prgs\tools\Console2> gci -include * | % { "$_" } | select -fir 5 C:\prgs\tools\Console2\-verbose C:\prgs\tools\Console2\1UpdateDataRepositoryServices.ps1 C:\prgs\tools\Console2\22-52-59.10o52l C:\prgs\tools\Console2\2jvcelis.ps1 C:\prgs\tools\Console2\a PS C:\prgs\tools\Console2> gci | % { "$_" } | select -fir 5 -verbose 1UpdateDataRepositoryServices.ps1 22-52-59.10o52l 2jvcelis.ps1 a |
Then if you use $_
in a cycle and PowerShell needs to convert FileInfo
from Get-ChildItem
to string, it gives different results. That happened when you used $_
as argument for Move-Item
. Quite bad.
I think there is a bug that reports this behaviour.