I have two folders, A and B which contain mostly similar file names, but some files are missing from A.

| 2.txt
| 10.txt
| zxc.txt

| 1.txt // this should be deleted
| 2.txt
| 10.txt
| asd.txt // this should be deleted
| asdfg.txt // this should be deleted
| zxc.txt

How can I delete all files from B that don't have a coresponding name with the same file in A? So, in the end B should have the same file names remaining as in A.

It doesn't really have to be powershell, I just need a way to bulk-remove the files on Windows 10.

  • Have you tried something? I'd do it by doing something like $A=GCI -Path A:\ | select fullname,name; $B=GCI -Path B:\ | select fullname,name; if($B[$i].name) -notin $A.name){Remove-Item $B.fullname}. – flolilo Sep 2 '17 at 21:42
  • Note that the file names in A and B are the same, but the file contents are different (eg: think of version A and version B of those files, but I no longer need version B for those who no longer have a version A). – Cristy Sep 2 '17 at 21:42
  • @flolilolilo Thanks, I'll try that, I have 0 experience with powershell. – Cristy Sep 2 '17 at 21:43

In PowerShell there always is an alternative way.
With this initial tree (on ramdrive A:):

PS A:\> tree . /F
│       10.txt
│       2.txt
│       zxc.txt

This one liner outputs:

PS A:\> gci B|?{! (test-path ("A\$($_.Name)"))}|rm -whatif
What if: Performing the operation "Remove File" on target "A:\B\1.txt".
What if: Performing the operation "Remove File" on target "A:\B\asd.txt".
What if: Performing the operation "Remove File" on target "A:\B\asdfg.txt".

The more verbose version (! equals not ):

Get-ChildItem B|Where-Object {! (Test-Path ("A\$($_.Name)") ) }|Remove-Item

No vars just piping ( on condition)

  • The second one says Remove-Object does not exist, the first one outputs "performing the operation" but doesn't actually remove the files. – Cristy Sep 3 '17 at 20:35
  • 1
    @Cristy Sorry, it's Remove-Item and if you remove the -Whatif (a precaution) from the first it should do. – LotPings Sep 3 '17 at 20:38

As per @flolilolilo comment, this worked:

$A=GCI -Path ./A | select fullname,name;
$B=GCI -Path ./B | select fullname,name; 

for ($i = 0; $i -lt $B.Count ; $i++) {
  if($B[$i].name -notin $A.name){
    Remove-Item $B[$i].fullname

I had to search for the for syntax in PowerShell, so I hope it's correct. It worked in my case.

  • Glad I could help; and yes, you used for correctly. – flolilo Sep 2 '17 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.