Bandit
Bandit

Reputation: 523

Deleting folders with Powershell recursively issue

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 }

Upvotes: 0

Views: 88

Answers (1)

Theo
Theo

Reputation: 61208

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

Upvotes: 1

Related Questions