2
votes

I want to move all files of a particular file type to a subfolder within their existing structures. All the examples I can find have hard-coded subfolders. I have many redundant folder structures so hard-coding isn't an option.

I have tried this:

$Dir = "\\root\*\REPORTS\*"

Get-ChildItem $Dir | Where-Object {$_.Name -match "csv"} | Move-Item -dest .\Queue\

It yields this error:

  • Get-ChildItem $Dir | Where-Object {$_.Name -match "csv"} | Move-Item <<<< -dest .\Queue\
    • CategoryInfo : WriteError: (\root...ity20170823.csv:FileInfo) [Move-Item], IOException
    • FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand

I have read that the period denotes the current folder, and so I am trying to use that for destination but it appears to only apply to path. It finds the files ok but is just unable to move them. Help!

EDIT I tried this based on the below suggestion:

$Dir = "\\root\*\REPORTS\*"

Get-ChildItem $Dir | Where-Object {$_.Name -match "xml"} |  %{
    #Move-Item -path $_.FullName -dest $_.FullName.Replace('REPORTS', 'REPORTS\Queue')
    write-output $_.FullName
    write-output $_.FullName.Replace('REPORTS', 'REPORTS\Queue')
}

The write-output values look good but the move-item line yields this error:

Move-Item : Could not find a part of the path. At C:\Users[me]\Desktop[filename].ps1:18 char:14 + Move-Item <<<< -path $.FullName -dest $.FullName.Replace('REPORTS', 'REPORTS\Queue') + CategoryInfo : WriteError: (\root\d$...ity20170823.csv:FileInfo) [Move-Item], DirectoryNotFoundException + FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand

Ah, because the path doesn't exist. This will work if I put in a if-folder-exists-else-create check, I believe.

EDIT 2 This works, except that it puts all of the files into directories named for the files.

$Dir = "\\root\*\REPORTS\*"

Get-ChildItem $Dir | Where-Object {$_.Name -match "csv"} |  %{
    New-Item -ItemType Directory -Force -Path $_.FullName.Replace('REPORTS', 'REPORTS\Queue')
    Move-Item -path $_.FullName -dest $_.FullName.Replace('REPORTS', 'REPORTS\Queue')
    #write-output $_.FullName
    #write-output $_.FullName.Replace('REPORTS', 'REPORTS\Queue')
}

Results in a move to:

\\root\abc\REPORTS\Queue\20170707-resub.csv\20170707-resub.csv

It would be nice if the folder created was just the path and not the file.

4
. refers to your current working directory.Maximilian Burszley
OK... the one where each of the found files are in?n8.
Can you give me a example of what you want to happen?ArcSet
I want \\root\abc\REPORTS\thisFile1.csv moved to folder \\root\abc\REPORTS\Queue\thisFile1.csv. I'm playing with Replace but failing.n8.
I added an answer that worked with my testing @n8.Maximilian Burszley

4 Answers

2
votes

This solution should accomplish what you want based on comments (faster, too):

$Dir = '\\root\*\REPORTS\*'

Get-ChildItem -Path $Dir -File -Filter '*.csv' |
  ForEach-Object {
      $Dest = "$($_.DirectoryName)\Queue"
      If (!(Test-Path -LiteralPath $Dest))
      {New-Item -Path $Dest -ItemType 'Directory' -Force}

      Move-Item -Path $_.FullName -Destination $Dest
  }
0
votes

You are missing -path in the Move-item cmdlet where PS is supposed to read what you are moving. Thats why you may be getting that error. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/move-item?view=powershell-5.1

Im assuming you want to loop through all files. I would do this instead...

$dir = "\\root\*\REPORTS\*"

Get-ChildItem $Dir | Where-Object {$_.Name -match "csv"}| %{
    Move-Item -path $_.FullName -dest "$Dir\Queue\$($_.Name)"
}

I do not recommend using -match because it could pick up csv anywhere in the filename unless you are certain that you want all of the files with csv anywhere in the name.

0
votes

You'll need a two step approach, first iterate the folders then the files.
Move won't create new Folders, you've to check yourself.

$Dir = "\\root\*\REPORTS"

Get-ChildItem -Path $Dir | Where-Object {$_.PSIsContainer | ForEach-Object {
  $Destination = Join-Path $_.FullName 'Queue\'
  If (!(Test-Path $Destination)){MD $Destination|Out-Null}
  Move-Item "$($_.FullName)\*.csv" -Destination $Destination -WhatIf
}

Check if the folders were created and if output look OK remove/comment out the -WhatIf

0
votes

If one need the code to look in folders, and in each folders create a new subfolder, and move files from each folder to the new subfolder. I removed the file filter, as I did not need that. (I used the code from TheIncorrigible1 and credit to Pawtuxet for the change in code) Hope I do follow the rules by posting this, so if others could use a modified version for subfolders.

<#
     Before:
     c:\foldertest
          folder1
              fil
              fil
          folder2
              fil
              fil
          folder3
              fil
              fil
    ----->

    After:
    c:\foldertest
          folder1
             subfolder
                 fil
                 fil
          folder2
             Subfolder
                 fil
                 fil
          folder3
             Subfolder
                 fil
                 fil
       #>

        $Dir = 'C:\temp\pstest\target\*'
        Foreach ($folder in Get-ChildItem -Path $Dir -Directory) {
        Foreach ($file in Get-ChildItem -Path $folder -File) {
            $Dest = "$folder\Subfolder"
            If (!(Test-Path -LiteralPath $Dest)) {
                New-Item -Path $Dest -ItemType 'Directory' -Force
            }
            Move-Item -Path $file.FullName -Destination $Dest
        }
    }