0

I need to delete some subfolders under a folder 'ToDelete'. I am using this to do that: (both should do the same deletion). my problem is that there is other folder called 'Do_Not_Copy' under ToDelete folder that contain also a folder called 'Tools' that should not be deleted. how I can protect this 'Tools' subfolder? -Exclude doesn't work. My workaround for now is to use Rename-Item for the Tools folder

$DestinationFolder = "\\google\server\ToDelete"

Remove-Item -Path $DestinationFolder\  -Include "Tools", "Support", "Installer", "GUI", "Filer", "Documentation" -Recurse -Exclude "Do_not_copy\SI\Tools" -Force 
Get-ChildItem $DestinationFolder\ -Include "Tools", "Support", "Installer", "GUI", "Filer", "Documentation" -Recurse -Force | ForEach-Object { Remove-Item -Path $_.FullName -Recurse -Force }
2

1 Answer 1

1

The -Recurse switch does not work properly on Remove-Item (it will try to delete folders before all the subfolders 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.

Try

$rootFolder = '\\google\server\ToDelete'
# create a regex of the folders to exclude
$Exclude = 'Do_not_copy\SI\Tools'  # this can be an array of items to exclude or a single item
# each item will be Regex Escaped and joined together with the OR symbol '|'
$notThese = ($Exclude | ForEach-Object { [Regex]::Escape($_) }) -join '|'
# the array of folder names (not full paths) to delete
$justThese = 'Tools', 'Support', 'Installer', 'GUI', 'Filer', 'Documentation'

(Get-ChildItem -Path $rootFolder -Directory -Recurse -Include $justThese).FullName |
    Where-Object { $_ -notmatch $notThese } |
    Sort-Object Length -Descending |
    Remove-Item -Recurse -Confirm:$false -Force -WhatIf

As usual, I have added the -WhatIf safety switch, so no folders will be deleted and in the console you can see what would happen. When satisfied the correct folders will be removed, comment out or remove that -WhatIf switch and run again


Since the code above uses regex to determine if a fullname matches (or in this case not) the string contained in $notThese, we need to make sure all characters that have special meaning for regex in that string are correctly escaped with a backslash. See the table below.
To do that, the code loops over the string(s) in the string or array in $Exclude and escapes these using [Regex]::Escape($_).
After escaping, the strings are combined with the regex OR symbol | using -join '|'

Special Characters in Regex

Char Description Meaning
\ Backslash Used to escape a special character
^ Caret Beginning of a string
$ Dollar sign End of a string
. Period or dot Matches any single character
| Vertical bar or pipe symbol Matches previous OR next character/group
? Question mark Match zero or one of the previous
* Asterisk or star Match zero, one or more of the previous
+ Plus sign Match one or more of the previous
( ) Opening and closing parenthesis Group characters
[ ] Opening and closing square bracket Matches a range of characters
{ } Opening and closing curly brace Matches a specified number of occurrences of the previous
Sign up to request clarification or add additional context in comments.

14 Comments

Thank you champ, I got a confirmation popup. any way to a void this?
@Bandit I have added -Confirm:$false. Does that help?
unfortunately no
@Bandit Then where and when does it trigger a confirmation? Can you show us exactly what it says ?
The item at $rootFolder\Installer has children and the Recurse parameter was not specified
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.