0
votes

I am trying to find a way to deal with such task:

there are several directories which are named differently. They contain 2 files hi.exe and newScript.bat I need to write script that looks in the current directory and its descendants for folders containing these two files, deletes those, then deletes the containing directory.

I found a way to delete those files and how to delete an empty directory. Is there a way to link directory name before deleting those files? Or any other way?

I found a way to delete files, but I need to save their paths somehow and then delete a folder : Remove-Item -path H:* -include hi.exe , newScript.bat -recurse -whatif

Also I can delete empty folders but it's not a solution that I am looking for.

Upd: Why with -and it is not working? But it works fine with -or? powershell execution

2
please, post your code ... and what does not work as expected. why? lookee ... Tour - Stack Overflow — stackoverflow.com/tourLee_Dailey

2 Answers

1
votes

If you go this way, it's a beginning.

Get-ChildItem -Path C:\ -Recurse | Where-Object {$_.Name -eq "hi.exe" -or $_.Name -eq "newScript.bat" } | foreach { $_.Directory }

Instead of sending the directory name to console, you can delete the directory where they resides.

EDIT:

Since I missed the "contains both files", I suggest this. Feel free to write it to a one-liner, but I did it step-by-step so there is "checkpoints" on the way.

$potensial_files = Get-ChildItem -Path C:\ -File -Recurse | Where-Object { @("calc.exe", "cmd.exe").Contains($_.Name) }

$potensial_files.Directory.FullName | select –unique | foreach { 

    $dir = $_
    $files = $potensial_files | Where-Object { $_.Directory.FullName -eq $dir }
    if(($files | Measure-Object).Count -eq 2)
    {
        Write-Host "$dir contains $files"
    }
}

And I am sure that this can be written a lot shorter, but what is the point for a "run once" script?

0
votes

If I understand correctly, you need to find folders where two specific files are found and if that is the case, output the path so it can be written to a file and next remove the folder including its files and subdirectories, correct?

# this is where you log the folder fullnames that have been deleted
$outFile = 'D:\Test\RemovedItems.log'
$removed = (Get-ChildItem -Path 'D:\Test' -Directory -Recurse).FullName | 
           Sort-Object -Property Length -Descending |   # sort descending is needed, see *
           ForEach-Object {
                # get a list of the files in each directory
                $files = (Get-ChildItem -Path $_ -File).Name
                # only if if BOTH files are present
                if ($files -contains 'hi.exe' -and $files -contains 'newscript.bat') {
                    # output the path of the directory before you delete the folder in order to save these
                    $_
                    # now remove the folder and its files
                    $_ | Remove-Item -Recurse -Force -WhatIf
                }
            }

$removed | Set-Content -Path $outFile -PassThru

* The -Recurse switch does not work nicely on Remove-Item (it will try to delete folders before all the child items in the folder have been deleted). Sorting the fullnames in descending order by length ensures than no folder is deleted before all the child items in the folder have been deleted.

  1. The -WhatIf switch only outputs to the console what would happen. Nothing is really deleted yet. If you are satisfied with that output, remove that switch.
  2. The final -PassThru switch also writes whatever is written to the RemovedItems.log file to console