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

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

  •  21-07-2023
  •  | 
  •  

Question

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)}
}
Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top