Copy all files with a certain name using Powershell
Solution 1:
My slightly modified answer from this question: Batch File:List all files of a type, rename files, flatten the directory
It does what you want: copies files using wildcard, flattens directory structure, handles filename conflicts. It uses Get-ChildItem
, as Tᴇcʜιᴇ007
suggested.
# Setup source and destination paths
$Src = '\\Server\Apps'
$Dst = 'C:\ReadMeFiles'
# Wildcard for filter
$Extension = '*ReadMe.txt'
# Get file objects recursively
Get-ChildItem -Path $Src -Filter $Extension -Recurse |
# Skip directories, because XXXReadMe.txt is a valid directory name
Where-Object {!$_.PsIsContainer} |
# For each file
ForEach-Object {
# If file exist in destination folder, rename it with directory tag
if(Test-Path -Path (Join-Path -Path $Dst -ChildPath $_.Name))
{
# Get full path to the file without drive letter and replace `\` with '-'
# [regex]::Escape is needed because -replace uses regex, so we should escape '\'
$NameWithDirTag = (Split-Path -Path $_.FullName -NoQualifier) -replace [regex]::Escape('\'), '-'
# Join new file name with destination directory
$NewPath = Join-Path -Path $Dst -ChildPath $NameWithDirTag
}
# Don't modify new file path, if file doesn't exist in target dir
else
{
$NewPath = $Dst
}
# Copy file
Copy-Item -Path $_.FullName -Destination $NewPath
}
Solution 2:
It's a known issue with Copy-Item, you can't specify a Wildcard in the source, and use Recurse (and have it work as you expect).
If you don't mind also copying the folder structure (yet only copying the readme's) try using the "Filter" option. Something like:
Copy-Item \\Server\Apps\ C:\ReadMeFiles\ -Filter *ReadMe.txt -Recurse
Alternatively you may be able to use Get-Child-Item with Recurse, and a For loop to feed Copy-Item the files one at a time.