Mathias's answer is the correct PowerShell way to do what you're looking for, however definitely not the fastest. If you want something faster you can rely on .NET API calls instead of relying on PowerShell cmdlets.
$queue = [System.Collections.Generic.Queue[System.IO.DirectoryInfo]]::new()
$copyFilePath = Get-Item 'absolute\path\to\initialDir'
$queue.Enqueue($copyFilePath)
while($queue.Count) {
$dir = $queue.Dequeue()
try {
$enum = $dir.EnumerateFileSystemInfos()
}
catch {
# Use `$_` here for error handling if needed
# if we can't enumerate this Directory (permissions, etc), go next
continue
}
foreach($item in $enum) {
if($item -is [System.IO.DirectoryInfo]) {
$queue.Enqueue($item)
continue
}
# `$item` is a `FileInfo` here, check its Length
if($item.BaseName.Length -eq 22) {
# skip this file if condition is met
continue
}
# here you can use `.CopyTo` instead of `Copy-Item`:
# public FileInfo CopyTo(string destFileName);
# public FileInfo CopyTo(string destFileName, bool overwrite);
try {
# `$destination` needs to be defined beforehand and should always be an absolute path
# if the folder structure needs to be preserved you also need to handle the folder creation here
$item.CopyTo($destination)
}
catch {
# error handling here
}
}
}