Home > Blockchain >  How can i only Move-Item if the destination does not equal specified desitnation?
How can i only Move-Item if the destination does not equal specified desitnation?

Time:06-20

I'm hoping someone can help me here. I'm trying to make a Move-Item script where it will move all the "Music" folders into their parent directory unless the directory equals "C:\Temp\Users".

For example.. if the folder is located in "C:\Temp\Users\Billy Bob\Documents\Music" then the Music file will move to "C:\Temp\Users\Billy Bob\Music".

But if the "Music" folder is located at "C:\Temp\Users\Billy Bob\Music" then it won't be allowed to move as the "C:\Temp\Users" directory is specified within an "If-Statement" to block all moves into this directory.

This is what I have so far but I can't seem to get it to work for me

Get-ChildItem -Path C:\Temp\Users -Recurse -Directory -Force -Filter "Music"|
ForEach-Object {
            if (Move-Item -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath) = C:\Temp\Users ) {
                Write-Output "Move Stopped" -WhatIf
            }
            elseif (Move-Item -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath) -ne C:\Temp\Users) {
                Move-Item -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath) -WhatIf
            }
}

I have this part working but it moves all "Music" Folders to the Parent directory so I would like to add a condition to cancel any move where the destination of the move equals specifically "C:\Temp\Users". Any other destination would be okay to proceed to move the "Music" folder into the parent directory.

Get-ChildItem -Path C:\Temp\Users -Recurse -Directory -Force -Filter "Music"|
ForEach-Object {
    Move-Item -Path $_.FullName -Destination $(Split-Path -Parent $_.PSParentPath) -WhatIf
}

CodePudding user response:

You don't need any condition if you start searching at a deeper level within the directory tree:

Get-ChildItem -Path C:\Temp\Users\*\*\* -Recurse -Directory -Force -Filter "Music" |
    Move-Item -Destination { $_.Parent.Parent.FullName } -WhatIf

The wildcard part \*\*\* forces Get-ChildItem to enumerate directories which are at least three levels deeper than C:\Temp\Users. So C:\Temp\Users\Billy Bob\Documents\Music gets enumerated, but C:\Temp\Users\Billy Bob\Music won't, because it only matches the first two * from the wildcard path.

I've also simplified the Move-Item call. You can pipe directly into Move-Item, so it gets the -Path parameter from the pipeline. For -Destination you can pass a delay-bind script block ({ ... }) argument, which makes ForEach-Object obsolete (see this answer for further details).

Also, Split-Path -Parent is not needed when working with DirectoryInfo objects from Get-ChildItem output. It has a .Parent property which contains a DirectoryInfo object as well, so by chaining you can get multiple levels up in the directory tree.

  • Related