Search code examples
powershellsearchdelete-filefile-exists

Powershell - Delete a file based on the existence of another file


I'm trying to create a Powershell script that will delete specific files only when another file exists in the same folder as the file to be deleted. All my attempts up to now have proven fruitless. Here's an example of the folder structure I'm working with:

RootFolder

  • Client1Folder
    • SubFolder
      • abc1.txt
      • abc1_control.txt
      • def1.txt
      • def1_control.txt
      • ... other files
  • Client2Folder
    • SubFolder
      • abc2.txt
      • abc2_control.txt
      • ... other files
  • Client3Folder
    • SubFolder
      • abc3.txt
      • def3.txt
      • ... other files (but no _control.txt files)
  • Client4Folder
    • SubFolder
      • abc4.txt
      • abc4_control.txt
      • ... other files

What I want to be able to do is to delete abc*.txt files when the corresponding abc*_control.txt files exists in the folder (so in this example I want to be able to delete abc1.txt, abc2.txt, and abc4.txt, but not abc3.txt or def1.txt, def3.txt, etc). I also want to be able to delete the abc*_control.txt files after I've completed the deletion of the abc*.txt files, but that should be trivial.

I can find the files I need to delete by doing a manual search in Windows Explorer and deleting them that way, but considering there are over 200 clients in this root folder that I would need to delete the two files for, any help would be much appreciated.


Solution

  • You could use Get-ChildItem to recursively find the '*_control.txt' files and from these files construct the 'other file' which you can then delete:

    Get-ChildItem -Path $rootFolder -Filter 'abc*_control.txt' -File -Recurse |
    ForEach-Object {
        # construct the full path and name of the 'other file'
        $toDelete = '{0}\{1}{2}' -f $_.DirectoryName, ($_.BaseName -replace '_control$'), $_.Extension
        if (Test-Path -Path $toDelete -PathType Leaf) {
            Remove-Item -Path $toDelete -WhatIf
            # remove the *_control.txt file as well?
            # $_ | Remove-Item -WhatIf
        }
    }
    

    Please note that I have added a -WhatIf switch to the Remove-Item cmdlet. This is a safety measure and with that switch, you will only see a line in the console telling you what action would be performed. Nothing actually gets deleted.
    Once you are satisfied with all console messages that everything does what is expected, you can remove that -WhatIf switch.