PowerShell使用Move-Item报错“Cannot create a file when that file already exists”的解决方法:将子文件夹PNG图片迁移至同目录Oneshot文件夹
Let's break down what's breaking your current code and get it working smoothly for your thousands of files.
What's Wrong With Your Original Code?
Your line Move-Item -Destination "$($_.FullName)\Oneshot\" is the root issue. When you use $_.FullName, you're referencing the full path of the PNG file itself (e.g., C:\Users\a\Desktop\stuff\FolderExample\image.png). Appending \Oneshot\ to that tries to move the file into a folder named after the file—like C:\Users\a\Desktop\stuff\FolderExample\image.png\Oneshot\—which doesn't exist (and can't exist, since you can't have a folder with the same name as a file in the same location). That's why you get the "Cannot create a file when that file already exists" error.
Fixed PowerShell Script (Basic Version)
This version will create the Oneshot folder if it doesn't exist, then move each PNG into the Oneshot subfolder of its parent directory:
Get-ChildItem -Path "C:\Users\a\Desktop\stuff" -Filter *.png -Recurse | ForEach-Object { # Get the folder where the current PNG is stored $parentFolder = $_.Directory.FullName # Build the path to the target Oneshot folder $targetFolder = Join-Path -Path $parentFolder -ChildPath "Oneshot" # Create Oneshot folder if it doesn't exist (suppress output with Out-Null) if (-not (Test-Path -Path $targetFolder)) { New-Item -ItemType Directory -Path $targetFolder | Out-Null } # Move the file to the Oneshot folder; skip duplicates silently Move-Item -Path $_.FullName -Destination $targetFolder -ErrorAction SilentlyContinue }
Key Improvements:
-Filter *.png: More efficient than putting*.pngin the path, as it filters files early in the process.$_.Directory.FullName: Correctly grabs the parent folder of each PNG, not the file's own path.Join-Path: Ensures proper path formatting (works across different Windows versions without manual slash issues).- Folder Creation Check: Prevents errors if
Oneshotdoesn't exist yet. -ErrorAction SilentlyContinue: Lets the script keep running even if a duplicate file exists inOneshot(it just skips that file).
Handle Duplicate Files (Advanced Version)
If you don't want to skip duplicates and instead want to automatically rename them (e.g., image.png → image(1).png), use this script:
Get-ChildItem -Path "C:\Users\a\Desktop\stuff" -Filter *.png -Recurse | ForEach-Object { $parentFolder = $_.Directory.FullName $targetFolder = Join-Path -Path $parentFolder -ChildPath "Oneshot" if (-not (Test-Path -Path $targetFolder)) { New-Item -ItemType Directory -Path $targetFolder | Out-Null } # Start with the original filename $targetFilePath = Join-Path -Path $targetFolder -ChildPath $_.Name # If the file already exists, add a counter until we find an unused name $counter = 1 while (Test-Path -Path $targetFilePath) { $newFileName = "$($_.BaseName)($counter)$($_.Extension)" $targetFilePath = Join-Path -Path $targetFolder -ChildPath $newFileName $counter++ } # Move the file to the unique target path Move-Item -Path $_.FullName -Destination $targetFilePath }
This way, you won't lose any files—duplicates get renamed instead of skipped.
内容的提问来源于stack exchange,提问作者needbetterusername

