Move-Item -Exclude -Recursive Is Not leaving excluded items in place within sub directories

StackOverflow https://stackoverflow.com/questions/23637762

  •  21-07-2023
  •  | 
  •  

Вопрос

I'm trying to move all items except a certain type of file. In this case *.msg. It does fine if the excluded file resides within the parent folder. However, the moment that same type of file is located within a subdirectory, it fails to leave the file in place and instead moves it to the new location.

username = Get-Content '.\users.txt'
foreach ($un in $username)
{
  $destA = "c:\users\$un\redirectedfolders\mydocuments"
  $destB = "c:\users\$un\redirectedfolders\desktop"
  $sourceA = "C:\users\$un\mydocuments"
  $sourceB = "C:\users\$un\desktop"

  New-Item -ItemType Directory -Path $destA, $destB

  Get-ChildItem $sourceA -Exclude '*.msg' -Recurse | Move-Item -Destination {Join-Path $destA $_.FullName.Substring($sourceA.length)}
  Get-ChildItem $sourceB -Exclude '*.msg' -Recurse | Move-Item -Destination {Join-Path $destB $_.FullName.Substring($sourceB.length)}
}
Это было полезно?

Решение

This is due to the filtering done by the Get-ChildItem exclude filter. It's kind of a known issue, and if you really want I could probably dig up some reference documentation, but it may take some time. Regardless, GCI doesn't handle wildcards very well when it comes to filtering things. What you are probably better off doing is piping it to a Where command like this:

$username = Get-Content '.\users.txt'
foreach ($un in $username)
{
  $destA = "c:\users\$un\redirectedfolders\documents"
  $destB = "c:\users\$un\redirectedfolders\desktop"
  $sourceA = "C:\users\$un\documents"
  $sourceB = "C:\users\$un\desktop"

  New-Item -ItemType Directory -Path $destA, $destB
  GCI $sourceA -recurse | ?{$_.Extension -ne ".msg" -and !$_.PSIsContainer} | %{
    $CurDest = Join-Path $destA $_.FullName.Substring($sourceA.length)
    If(!(Test-Path $CurDest.SubString(0,$CurDest.LastIndexOf("\")))){New-Item -Path $CurDest -ItemType Directory|Out-Null}
    $_ | Move-Item -Destination $CurDest
  }
  GCI $sourceB -recurse | ?{$_.Extension -ne ".msg" -and !$_.PSIsContainer} | %{
    $CurDest = Join-Path $destB $_.FullName.Substring($sourceB.length)
    If(!(Test-Path $CurDest.SubString(0,$CurDest.LastIndexOf("\")))){New-Item -Path $CurDest -ItemType Directory|Out-Null}
    $_ | Move-Item -Destination $CurDest
  }
}

Edit: Ok, now excludes folders, and also keeps folder structure.
Edit2: Re-designed to do a ForEach loop on the files, build the destination path as $CurDest, test to make sure it exists and make it if it doesn't, then move the files. Also changed mydocuments to documents which is the path to a user's My Documents folder.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top