views:

550

answers:

3

I have a list of filenames in a text file like this:

f1.txt f2 f3.jpg

How do I delete everything else from a folder except these files in Powershell?

Pseudo-code:

Read the text file line-by-line Create a list of filenames Recurse folder and its subfolders If filename is not in list, delete it.

Thanks in advance. ~HP

+5  A: 

Data:

-- begin exclusions.txt --
a.txt
b.txt
c.txt
-- end --

Code:

# read all exclusions into a string array
$exclusions = Get-Content .\exclusions.txt

dir -rec *.* | Where-Object {
   -not ($exclusions -contains [io.path]::GetFileName($_)) } | `
   Remove-Item -WhatIf

Remove the -WhatIf switch if you are happy with your results. -WhatIf shows you what it would do (i.e. it will not delete)

-Oisin

x0n
I like it. Why not use -notcontains, though?
Mike Shepard
Thanks. This works perfectly for me. I tried with -notcontains as Mike suggested and the results are same.
Mrchief
i hate -notcontains. nah, only kidding. yeah, that's ever terser.
x0n
+5  A: 

If the files exist in the current folder then you can do this:

Get-ChildItem -exclude (gc exclusions.txt) | Remove-Item -whatif

This approach assumes each file is on a separate line. If the files exist in subfolders then I would go with Oisin's approach.

Keith Hill
Yeah, files are on separate lines. Thanks for the answers. If the parent location has subfolders, I get a prompt saying "The item at Microsoft.PowerShell.Core\FileSystem::<<path>> has children and the Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want to continue?" Probably adding the -recurse switch will fix it.Oisin's approach doesn't cause this prompt.
Mrchief
If subdirs are involved then you do *not* want to use my approach and you don't want to use -r otherwise it will delete entire folders.
Keith Hill
A: 

actually this only seems to work for the first directory rather than recursing - my altered script recurses properly.

$exclusions = Get-Content .\exclusions.txt

dir -rec | where-object {-not($exclusions -contains [io.path]::GetFileName($_))} | `  
where-object {-not($_ -is [system.IO.directoryInfo])} | remove-item -whatif
Wayne Theisinger