Delete all files in a group of folders and list the deleted files

I have in folder MyDocs, several sub-folders named Temp*. I wish to delete all the files in every Temp* sub-folder while keeping the sub-folders intact.

$dir = "C:\Users\Me\Documents\Temp*’

Get-Childitem -directory $dir |

Get-Childitem -file -recurse |


This works fine, but I also wish to have a list of the files deleted. In checking Remove-Item, the closest feature is the -Confirm parameter but this would become unwieldy if there are many files. Would appreciate some tips or guidance, thanks.

$dir = 'C:\Users\Me\Documents\Temp*'
$DeletedFileList = @()

Get-Childitem -Directory $dir | 
    Get-Childitem -File -Recurse | 
        foreach { 
            $DeletedFileList += $_.FullName

'List of deleted files is:'

Sorry, I struggled for over an hour with my post/question. Please ignore this post/reply (to myslef), it was intended for another post.

Many thanks, Mr Sam Boutrous, your inputs are highly appreciated.

Another approach.

Get-ChildItem -File | Remove-Item -Path {[array]$Global:List += $.FullName;$.FullName} -Force -Recurse


Sincerest thanks Mr Kvprasoon, much appreciated. I understand the -PATH parameter takes the form of a script block which contains 2 statements separated by a semi-colon. The first statement

$Global:List +=$_.Fullname

simply accumulates each file’s pathname into an ARRAYLIST which is used later for printing. The second


is actual input to the -PATH parameter for file deletion.

My question is more on the general side: in such a script block, where you can have many statements, how does Powershell “operate” so that it knows which one is to be the actual parameter input? Or is it the programmer’s responsibility to ensure that there’s no ambiguity: i.e., in this case the -PATH parameter of Remove-Item expects an object of Type [string] so the programmer must ensure this “happens”. Thanking you in advance for your attention and kind consideration.

Awesome, your understanding is correct on using the ScriptBlock. PowerShell takes what ever comes out of the expression execution inside the ScriptBlock.
Here the first statement is just storing the file names in an array and the second one actually spits out and will be bound to -Path parameter.

This technique is called delay binding. Below tracing output will help you.

Trace-Command ParameterBinderBase,ParameterBinderController,ParameterBinding {1..5 | Write-Output -InputObject {[array]$global:r += $_; $_}} -PSHost

Any parameter that can take input from the pipeline can use a script block instead. The classic case is rename-item. I thought remove-item might have a -passthru option, but I guess it makes sense it doesn’t.

Get-ChildItem *.txt | Rename-Item -NewName { $ -Replace '\.txt$','.log' }

Much thanks Messrs. Kvprasoon and JS. I am highly grateful that you have taken the time and effort to answer my questions and provide clear explanations with excellent examples. This has improved my Powershell learning. Best,