Tutorial Tool Cleaning image packs with PowerShell for fun and profit

Sassazael

Newbie
Jul 26, 2020
27
15
So you just downloaded an image collection for some game, that doesn't come with them from scratch.

It's huge, and contains loads of good stuff you want, but unfortunately has some things you don't want (eg furries, futa, or other things like that). The creator of the collection has helpfully tagged all the stuff you want to excise, but there are hundreds of folders, and several thousand images.

You absolutely do not want to do this manually.

How will you cope? PowerShell is how you will cope.


I know it says Bash, but there was no option for PowerShell.
Bash:
$path = "Yah path goes here"
$condition = "*blondes*" <# put your wild card condition here, only change this and the path#>


$items = Get-ChildItem $path -recurse | where name -like $condition
foreach ($item in $items){

    $itemToNuke = $item.PSPath

    if(Test-Path $itemToNuke){
        Try {
            Remove-Item -Path $itemToNuke -Recurse -Force -ErrorAction Stop
            Write-Host "Nuking $itemToNuke"
        } Catch {
            Write-Host "Unable to nuke $itemToNuke"
        }
    } else {
        Write-Host "Item $itemToNuke already nuked"
    }
}
So how does it work?Get-ChildItem takes in your path, and creates a set of all files and folders beneath it. where name -like $condition filters that set, so that only things matching your $condition, in this case blondes remain. These all go into the set, which will be deleted.

You can get reasonably fancy with $condition. For example
"*.png" will delete all png files,
"Redhead*" will delete all folders and files that start with Redhead,
"*Redhead" will delete all folders and files that end with Redhead,
and finally "*red*" will delete all folders and files that contain the string "red" in them, anywhere.

As far as I know, all comparisons in PowerShell are case insensitive, so Blonde and blonde will delete the same things. If you are dealing with characters outside the standard ASCII alphabet, for example Japanese, Chinese or Turkish characters, your mileage may vary.



Ok, so now you have the code. How do you get it to work?
First you need to save your script. Copy the script contents from here, and open Notepad. Paste the script contents, and hit Save As.
Select "Save as type" as "All Files", and end your filename as ".ps1". This is important.
You can call it whatever you like, as long as it ends with .ps1.

rec.png


The next step is to open the script in the PowerShell editor. You should already have this installed on your machine. Search for "Powershell ise" in the windows menu. Navigate to your file in explorer, and drag drop it into the console. Should look like this:

powershellmenu.png

Now you're all set right? Just replace $path and $condition and you're good right?

No. That way lies data loss and pain.

First we test. Make a backup of your pack, in case you screw up.
Then copy out a small subset of your pack, so you don't fill your console with too much info.
Make sure it contains what you want to delete, and maybe some edge cases.

Like, if you want to strip out redheads, make sure there are files with "redhead", "redheads" "red head" and "red heads", as well as some other stuff, like "brunettes". Don't stress too much over this, as you have in fact made a backup.

A handy tip to getting the path of something in windows, is holding shift when you left click, it gives you the copy as path option.
cpspth.png

Additionally, if you wish to test more before you run it, you can replace the delete part in the foreach with a simple printout to check that you've got the right folders and files.
Bash:
$path = "Yah path goes here"
$condition = "*Blondes*" <# put your wild card condition here, only change this and the path#>


$items = Get-ChildItem $path -recurse | where name -like $condition
foreach ($item in $items){

    $itemToNuke = $item.PSPath
    Write-Output $itemToNuke

}
Now when you run this, you're almost certainly going to get an error like:

This means that your computer (by Microsoft default) does not allow the running of unsigned or local PowerShell scripts.
Paste the following line in the PowerShell terminal (the big blue box in your editor), and run it, to allow local scripts and signed scripts.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
You might wish to set it back to AllSigned when you're done, if you're not running PowerShell often.

PS: While I am a developer, I am not a PowerShell wizard, and give no guarantees that this is the "right" or "optimal" way of doing this. If you are a PowerShell wizard, and this code offends you, I will happily take suggestions for improvement. If you are a normal, and didn't understand any of this, I'll also happily take suggestions for improvement.

I hope this will be useful for at least someone.