How Can I Use Windows PowerShell to Delete All the .TMP Files on a Drive?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I use Windows PowerShell to locate and delete all the .tmp files on a drive?

— OR

SpacerHey, Scripting Guy! AnswerScript Center

Hey, OR. You know, there’s an old saying: Give a man a fish and he’ll eat for a day; teach that man to fish and he’ll eat for the rest of his life.

Well, unless he’s like the Scripting Guy who writes this column and doesn’t like seafood. In that case he probably won’t even want to learn to fish. And there’s no point in giving him a fish, because he won’t eat it. Instead, he’ll end up starving to death and you’ll spend the rest of your life wracked by guilt. “Why did I give him a fish?” you’ll think. “Why didn’t I give him a hamburger or something? This is all my fault, isn’t it?”

Yes, it is.

The point is – well, to tell you the truth, we’re no longer sure what the point is. Oh, now we remember. Can we show you how to use Windows PowerShell to locate and delete all the .tmp files on a drive? Of course we can. But then you’d run a script for just one day. But if you learned Windows PowerShell then you could run scripts for the rest of your life. (You’ll still be hungry, but at least you’ll have something to take your mind off food.)

In other words, if you’re interested in Windows PowerShell then you owe it to yourself to attend Windows PowerShell Week, November 6-10, 2006. This week is designed with one purpose in mind: to introduce you to Windows PowerShell. We’ll have a series of webcasts (one each day, Monday through Friday); we’ll have a virtual lab where you can try your hand at Windows PowerShell; and we’ll have a few other assorted goodies (like a “labcast,” which is a combination virtual lab and webcast). It will be fun, it will be exciting, and, with any luck, it will be educational as well. We won’t teach you how to fish, but we will teach you everything you need in order to get started with Windows PowerShell.

Well, that’s a good point: you never know what Peter will do during a webcast, do you? So maybe Peter will teach you to fish; we’ll just have to wait and see.

Update: Windows PowerShell Week is over, but you can watch the webcasts on-demand anytime.

So, other than fishing, what kinds of things will you learn during Windows PowerShell Week? Why, things like how to locate and delete all the .tmp files on a drive:

get-childitem c:\ -include *.tmp -recurse | foreach ($_) {remove-item $_.fullname}

Believe it or not that is the entire command; as you can see, if you don’t enjoy typing then Windows PowerShell is like a dream come true. What we have here are actually two commands crammed into one: we first retrieve a collection of all the .tmp files on drive C, then we go ahead and delete each of those files. How do we do that? Let’s see if we can figure that out.

To begin with, we use the Get-ChildItem Cmdlet to retrieve a collection of all the .tmp files on drive C. That’s what we do here:

get-childitem c:\ -include *.tmp -recurse

This is actually fairly straightforward. We call Get-ChildItem (which, when working with the file system, functions somewhat similar to the dir command) and pass it three parameters:

c:\, which represents the starting folder for our search.

-include *.tmp, which tells Get-ChildItem to return only files that have a .tmp file extension. Suppose we also wanted to include files that have a .temp file extension. That’s fine; all we’d have to do is add .temp to the list of included files: -include *.tmp, *.temp.

-recurse, which tells Get-ChildItem to look for files in all of the subfolders of C:\ (and all the sub-subfolders of those subfolders, and so on). And yes, that is cool: you don’t have to write some complicated recursive function to get at the files in the subfolders of a folder. Instead, just tack on the –recurse parameter.

After we’ve retrieved our collection we “pipe” it over to the second half of our command (the | character represents the pipeline). Needless to say, we’ll talk about piping in much more detail during Windows PowerShell Week. For now we’ll just say that, by itself, Get-ChildItem typically retrieves a collection and then displays the returned information onscreen. However, we aren’t interested in seeing the .tmp files displayed on screen; we want to delete those files. Therefore, instead of displaying the items on screen we ask Get-ChildItem to hand over (pipe) the entire collection to the second half of our command.

In case you’ve forgotten, the second half of our command looks like this:

foreach ($_) {remove-item $_.fullname}

What we’re doing here is setting up a For Each loop to loop through the collection handed over by Get-ChildItem. Don’t worry too much about the syntax for now; we’ll discuss For Each loops in much more detail during Windows PowerShell Week. We will note, however, that the $_ is a special Windows PowerShell variable that represents the individual items in the pipeline. When we say foreach ($_) that’s equivalent to a VBScript statement like this:

For Each objItem in colItems

In other words, we’re just looping through all the files in the collection.

And what are we going to do to each of those files? Why we’re going to use the Remove-Item Cmdlet to delete them, of course:

{remove-item $_.fullname}

Here we call Remove-Item and pass, as the sole parameter, the FullName property of each individual file in the collection. (FullName is equivalent to the file path.) Believe it or not, that’s all we have to do; Remove-Item takes care of the rest for us.

What’s that? You say this sounds cool, but, seeing as how you’re new to Windows PowerShell, you’re a little nervous about running a script that deletes a bunch of files? Hey, no problem. If that’s the case, just tack the –whatif parameter on to the Remove-Item command, like so:

get-childitem c:\ -include *.tmp -recurse | foreach ($_) {remove-item $_.fullname -whatif}

That –whatif parameter is pretty neat: instead of deleting the .tmp files it simply tells you what would happen if you really did ask Remove-Item to delete all the files. In other words, you’ll get back a report of the files that would be deleted if you ran the command for real:

What if: Performing operation “Remove File” on Target “C:\WINDOWS\SET3.tmp”.
What if: Performing operation “Remove File” on Target “C:\WINDOWS\SET4.tmp”.
What if: Performing operation “Remove File” on Target “C:\WINDOWS\SET8.tmp”.

It’s like fantasy football, only with Windows PowerShell.

At any rate, we – oops, we need to go: Peter just walked by wearing hip waders and carrying a fishing pole. Admittedly, that’s not all that unusual for Peter. But we better find out what he’s up to, just in case.

Comments (17)

  1. Anonymous says:

    @Jack ‘del *.tmp’ would only delete .tmp files in the directory you are currently in, the command demonstrated in this blog post would delete all .tmp file stored anywhere on the C: drive, and you could of course easily modify the command to delete files of any extension you wanted from any drive you wanted.

    So I certainly would not compare it to the command you posted.

  2. I am using Remove-Item file by file, because i need it.

    The process start with a rename of the file and then a copy of them to sharepoint,

    the issue is when i try to delete some files, i receive a message issue like this:

    Remove-Item : Cannot remove item E:108_218511852DP08F1-AA01-Z0100-BD001_0001.dwg: The process cannot access the file 'E:108_218511852DP08F1-AA01-Z0

    100-BD001_0001.dwg' because it is being used by another process.

    At E:Scripts de Carga inicial SS10QuitarBloqueoFile.ps1:52 char:12

    + Remove-Item <<<<  $FilePath -force

       + CategoryInfo          : WriteError: (E:108_218511…-BD001_0001.dwg:FileInfo) [Remove-Item], IOException

       + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

    Do you know, how can i solve this issue?

    Any idea?


  3. Oliver Franke says:

    Sorry, but have you ever tested the script.

    Perhaps on c:users

    I tried to clear our ms terminal servers from useless profiles… but it won't work…

    Kind regards,


  4. Suzanne says:

    This worked far better then the flaky xp_delete_files and was far easier (KISS) then all the other scripts I found.

  5. Mr Mister says:

    That was extremely helpful – THANK YOU!

    I used the following to delete all "session" subdirectories:

    gci -rec | where {($_.PSIsContainer -eq $true) -and ($ -like "session*")} | foreach ($_) {remove-item $_.fullname -recurse -force}

  6. Loren-Luo says:

    get-childitem c: -include *.tmp -recurse | foreach ($_) {remove-item $_.fullname -whatif}

    should be

    get-childitem c:* -include *.tmp -recurse | foreach ($_) {remove-item $_.fullname -whatif}

  7. Jack says:

    Wow, this is so much simpler than 'del *.tmp'

  8. so much easier says:

    del *.tmp /s Same command since dos – so much easier Good luck running this command without screwing around with execution contexts those powershell error messages are useless !

  9. Chaosmonkey_man says:

    Thank you.

  10. sam says:

    its amazing to me that MS wrote a scripting language that makes basic tasks so stupidly verbose and absurd. think on nix u do: rm -Rf *.orig only slightly longer is the dos: del *.orig /s
    powershell team are drunk!

  11. Sachin Jadhav says:

    How to delet mp3 files through powershell

    follow the following command:

    D: is the drive
    TEST is the folder created for testing

    get-childitem -path d:TEST -include *.mp3 -recurse | foreach { $_.delete() }

  12. I made a script that delete’s .tmp and .temp files prior to the current date based on the example given by you.
    However when i run the script it gives me pop-ups telling me that because i don’t use -recurse for my get-childItem
    it wants to know if i really dont want to use -recuse to loop through the other folders in search of the *.tmp files.

    i have to manually tell it "no to all" to not search these folders. is there a better way to complete my scrip so that i won’t have manually react to the questions it asks ?? tnx in advance

    Case = i want to clean tmp files on 2 machines when the date is older than the current one.

    $Root = "\srv-publish01c$Documents and Settingsinfo-assistentLocal SettingsTemp" , "\srv-publish02c$Documents and Settingsinfo-assistentLocal SettingsTemp"
    $date = Get-Date
    Foreach( $item in $Root)
    $Folder = Get-ChildItem $item
    Foreach ($File in $Folder)
    if ($File -like "*.tmp" -or "*.temp" -and $file.LastWriteTime -lt $
    remove-item $File.FullName -Force

  13. francisco says:

    Hi, I did run the script that you say. But it ask for permission to delete every single file, even if a chose the option [A] Yes to All.

    The item at C:TEMP%user%nss738D.tmp 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?
    [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):

    There is any way to make this automatic?

  14. Fransisco, that is exactly my question, I get the same popup when i run my script. I posted it here so maybe scripting guy could help me with this.

  15. sorry was a bit to fast in posting, When i add -recurse tot the dele string it doesnt give me popups.

    remove-item $File.FullName -Force -Recurse

  16. Rob B says:


    I have a similar challenge here. I want to delete all .errlog files from a specific folder on c drive (c:\Program Files\Mricosoft Data Protection Manager\DPM\Temp) that have not been modified in the last 30 days but I DO NOT want to delete any files form the subfolder in this location, nor do I want to delete the subfolder itself.

    So far I have:

    Get-ChildItem ‘C:\Program Files\Microsoft Data Protection Manager\DPM\Temp’-Include *.errlog

    How can I further filter the results of this get command to only return .errlog files that have not been modified in the last 30 days and equally as important, not include the MTA subfolder in this location? If I can get this part right then i’m assuming I would use the same command suggested in this post after the pipe?

    I’m new to PS scripting so would appreciate any input.



    1. Thorsten says:

      @ Rob B
      you can try this:
      $Now = Get-Date
      Get-ChildItem ‘C:\Program Files\Microsoft Data Protection Manager\DPM\Temp’-Include *.errlog | where {$_.LastWriteTime -le ($Now.AddDays(-30))} | foreach ($_) {remove-item $_.fullname}

Skip to main content