Перемещение jpg с помощью скрипта PowerShell с переменными каталогами

Я пишу запланированный сценарий, который будет перемещать изображения (jpg) из одного места в другое. Проблема в том, что родительский каталог имеет переменное имя, в то время как конечный каталог фиксирован.

Если бы это сделал robocopy, я был бы счастлив: robocopy C: \ temp \ pcbmodel ** \ defect c: \ test ** \ defect *. Но это не так

Например, это почти сработает:

foreach ($i in Get-ChildItem C:\temp\pcbmodel\*\*\defect -recurse)
{
if ($i.CreationTime -lt ($(Get-Date).AddMonths(0)))
{
    write $i.FullName
    Copy-Item $i.FullName C:\Test
}
}

Проблема в том, что файлы копируются в c: \ test, а путь ** - нет. И путь * мне нужен, так как он будет меняться для каждого клиента.

Несколько предложений было бы неплохо, Берт


person user2606845    schedule 22.07.2013    source источник
comment
Что конкретно мешает сделать robocopy C:\temp\pcbmodel C:\test *.jpg /s?   -  person Ansgar Wiechers    schedule 22.07.2013


Ответы (4)


Это должно направить вас на верный путь к получению рабочего решения. Важной частью является командлет Resolve-Path, который принимает параметр -Relative: http://technet.microsoft.com/en-us/library/hh849858.aspx. new-Item -Force просто указывает ему создать структуру папок, если это необходимо.

# $OldRoot = 'Top-level of old files'
# $DestRoot = 'Top-level of destination'
# Go to old root so relative paths are correct
Set-Location $OldRoot
# Get all the images, then for each one...
Get-ChildItem -Recurse -Include "*.jpeg", "*.jpg" | 
ForEach-Object { 
        # Save full name to avoid issues later
        $Source = $_.FullName

        # Construct destination filename using relative path and destination root
        $Destination = '{0}\{1}' -f $DestRoot, (Resolve-Path -Relative -Path:$Source).TrimStart('.\')

        # If new destination doesn't exist, create it
        If(-Not (Test-Path ($DestDir = Split-Path -Parent -Path:$Destination))) { 
            New-Item -Type:Directory -Path:$DestDir -Force -Verbose 
        }

        # Copy old item to new destination
        Copy-Item -Path:$Source -Destination:$Destination -Verbose
}
person Eris    schedule 22.07.2013
comment
Спасибо, но я не могу заставить это работать. Некоторая дополнительная помощь. Я не знаю, как отделить корень от первоисточника. Пожалуйста, объясните '{0} \ {1}' -f $ DestinationRoot, (Resolve-Path -Relative -Path $ _). Спасибо - person user2606845; 23.07.2013
comment
Это средство форматирования строк PowerShell; devcentral.f5.com/blogs/us/ есть хорошее объяснение. - person Eris; 23.07.2013
comment
благодаря. Теперь мне нужно только удалить. ? Любая идея? PS C: \ temp ›C: \ Temp \ test3.ps1 c: \ test \. \ Pcbmodel \ help1 \ help2 \ defect c: \ test \. \ Pcbmodel \ help1 \ help2 \ defect \ t.jpg - person user2606845; 23.07.2013
comment
Привет, у меня появилась эта ошибка: Resolve-Path: не удается найти путь «C: \ test \ pcbmodel \ help1 \ help2 \ defect \ t.jpg», потому что он не существует. + CategoryInfo: ObjectNotFound: (C: \ test \ pcbmode ... p2 \ defect \ t.jpg: String) [Resolve-Path], At C: \ Temp \ test5.ps1: 14 символов: 61 + If (-Not (Test-Path ($ DestDir = Split-Path -Parent -Path: $ DestItem))) {+ ~~~~~~~~~ + CategoryInfo: InvalidData: (:) [Split-Path], .. Это сделать путь правильным, но не создать каталог, если он не существует. Если вы можете взглянуть, пожалуйста! - person user2606845; 23.07.2013
comment
Resolve-Path работает только с уже существующими элементами. Во всяком случае, исправил. - person Eris; 23.07.2013

Как насчет этого:

$step1 = get-childitem  C:\temp\pcbmodel\
$Else = #FILETYPE YOU DO NOT WANT
$step1 | foreach {get-childitem -recurse -exclude "Directories", $ELSE | where {$_.Creationtime -lt ($(get-date).Addmonths(0))} 
                 }

Надеюсь, я понял, и это помогает :)

РЕДАКТИРОВАТЬ: Работайте с параметрами -Exclude и -Include, они очень помогают :)

EDIT2: Ofc, я что-то перечитал, извините за множество правок - вы просто ищете файлы jpg.

$step1 | foreach {get-childitem -recurse -include *.jpg, *.jpeg | where {$_.Creationtime -lt ($(get-date).Addmonths(0))} 
person XXInvidiaXX    schedule 22.07.2013
comment
Привет, спасибо, но проблема не в том, чтобы получить файлы, а в том, чтобы поместить их в соответствующий каталог. Исходной картой может быть: c: \ temp \ pcbmodel \ customerA \ Files \ Defect \ images.jpg. его нужно переместить в d: \ archive \ pcbmodel \ customerA \ Files \ Defect \ images.jpg. Я не могу получить файлы в другом каталоге, сохраняя исходный путь ... дайте мне знать, ясно ли оно (или нет). Благодарность! - person user2606845; 22.07.2013
comment
добавил новый ответ, потому что он полностью отличается от этого. надеюсь, что теперь это поможет :) - person XXInvidiaXX; 23.07.2013

Еще одна идея: не пытайтесь использовать это на своем C: диске. Это понадобится навсегда. Но если у вас есть разрешения для каждого каталога и подкаталога на определенном пути, а количество подкаталогов невелико, это должно работать.

Я создал каталог «Новый каталог» на C: и еще один «Новый каталог» в этом каталоге. И, конечно же, еще один «Новый каталог» в каталоге. и, наконец, я создал файл с именем "superduper.txt" -> C: \ New Directory \ New Directory \ New Directory \ superduper.txt

(get-childitem C:\).FullName | where {(Get-ChildItem $_).FullName | where {(get-childitem $_ -Recurse).FullName -match "superduper"}}

Результат:

C:\New Directory

Я думаю, что это будет не быстро, и вам понадобится 2 из них для достижения вашей цели, я думаю, это должно сработать.

person XXInvidiaXX    schedule 23.07.2013

Я пытаюсь скопировать все подпапки и их файлы из одной папки в другую, не копируя также их родительскую папку.

Например, в C:\test с некоторыми вложенными папками, содержащими файлы, скопируйте в D:\test, но не D:\test\test\subfolders.

person George    schedule 23.09.2015