Eu gosto de usar todos os comandos do Powershell quando posso. Após alguns testes, é o melhor que posso fazer.
$source = "C:\test"
$destination = "C:\test2"
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"
$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter}
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}
As três primeiras linhas são apenas para facilitar a leitura, você pode definir as variáveis dentro dos comandos reais, se desejar. A chave para esse exemplo de código é o comando "Where-Object", que é um filtro que aceita correspondência de expressão regular. Note-se que o suporte a expressões regulares é um pouco estranho. Encontrei um cartão de referência em PDF aqui com os caracteres suportados no lado esquerdo.
[EDITAR]
Como "@Johannes Rössel" mencionou, você também pode reduzir as duas últimas linhas para uma única linha.
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
A principal diferença é que a maneira de Johannes faz a filtragem de objetos e a minha maneira faz a filtragem de texto. Ao trabalhar com o Powershell, quase sempre é melhor usar objetos.
[EDIT2]
Como o @smoknheap mencionado, os scripts acima nivelam a estrutura da pasta e colocam todos os seus arquivos em uma pasta. Não tenho certeza se existe uma opção que mantém a estrutura da pasta. Eu tentei a opção -Recurse e ela não ajuda. A única maneira de fazer isso funcionar é voltar à manipulação de strings e adicionar pastas ao meu filtro.
$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
}
Tenho certeza de que existe uma maneira mais elegante de fazer isso, mas pelos meus testes funciona. Ele reúne tudo e filtra as correspondências de nomes e os objetos de pasta. Eu tive que usar o método ToString () para obter acesso à manipulação de string.
[EDIT3]
Agora, se você deseja relatar o caminho, verifique se tudo está correto. Você pode usar o comando "Write-Host". Aqui está o código que lhe dará algumas dicas sobre o que está acontecendo.
cls
$source = "C:\test"
$destination = "C:\test2"
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"
$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
Write-Host "
----
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
}
Isso deve retornar as seqüências relevantes. Se você não encontrar nada em algum lugar, saberá com qual item está tendo problemas.
Espero que isto ajude