Weekend Scripter: Use PowerShell to Clean Out Temp Folders

Summary: Guest blogger, Bob Stevens, talks about using Windows PowerShell to clean out temporary folders on desktops following a malware infection.

Microsoft Scripting Guy, Ed Wilson, is here. Today, we welcome back our newest guest blogger, Bob Stevens. Yesterday Bob wrote about a quick script that he developed to pick out comments from a Windows PowerShell script: Weekend Scripter: Pick Comments from a PowerShell Script.

I made Bob’s virtual acquaintance recently when I did a Live Meeting presentation to the Twin Cities PowerShell User Group.

Here is Bob’s contact information:

Blog: Help! I’m Stuck In My Powershell!
Twitter: @B_stevens6
LinkedIn: Robert Stevens

Take it away, Bob…

For a local service desk systems analyst, nothing is more frustrating than malware. Not only is it a time sink—it also has the indented potential to cause irreparable damage. No network that connects to the Internet is immune to it.

Most organizations have their own standard operating procedures regarding malware removal. Even so, individuals technician have their special tweaks and tricks to increase the likelihood of success. I like to target the malware where it resides: Temp Folders. And after cleaning and clearing a number of workstations, it occurred to me that I could use a Windows PowerShell script to do just that, saving myself five minutes of hoping that the computer will let me open a folder.

I started by creating a list of the locations that temporary files are automatically placed by the Windows XP operating system (starting with Windows Vista, they are in the C:\Users folder):

  • C:\Windows\Temp
  • C:\Windows\Prefetch
  • C:\Documents and Settings\*\Local Settings\Temp
  • C:\Users\*\Appdata\Local\Temp

Now that I have defined our locations, I need to define what I want to do. For this, I create a flowchart:

Image of flowchart

I start with the Set-Location command and define the location as “C:\Windows\Temp”:

            Set-Location “C:\Windows\Temp”

Now that I am located in the Windows temp folder, I need to delete the files. This can be done with the old DOS command Del, but I prefer using the Windows Powershell cmdlet Remove-Item to standardize the script. The items need to be removed indiscriminately, so I use a wildcard character. A wildcard character is a special character that represents one or more other characters. The question mark (?) wildcard stands for one character and the asterisk (*) wildcard stands for any number of characters. Because I do not want to discriminate between different files, I use the asterisk.

Remove-Item *

Next I tell the Remove-Item cmdlet to also remove all files in subdirectories with the -recurse switch:

Remove-Item * -recurse

And I tell it to select hidden files with the -force switch:

Remove-Item * -recurse -force

Together the two lines looked like this:

Set-Location “C:\Windows\Temp”
Remove-Item * -recurse -force

I do the same for the rest of the folders and the complete script begins to take shape:

Set-Location “C:\Windows\Temp”
Remove-Item * -recurse -force

Set-Location “C:\Windows\Prefetch”
Remove-Item * -recurse -force

Set-Location “C:\Documents and Settings”
Remove-Item “.\*\Local Settings\temp\*” -recurse -force

Set-Location “C:\Users”
Remove-Item “.\*\Appdata\Local\Temp\*” -recurse -force

Wait. Why is there an asterisk in the middle of the last path? You can use wildcard characters to do this:

Remove-Item “.\*\Appdata\Local\Temp\*” -recurse -force

This says, “Look in all folders in this directory with the path structure that matches this.” In my case, this is all of the user profile Local Settings\temp folders.

But this looks very busy, so at Ed Wilson’s suggestion, an array would prevent all the unnecessary jumping around with the Set-Location command. So we change our flowchart to look something like this:

Image of flowchart

Arrays are a nifty programming feature that groups a number of strings together into one variable, while remaining individual strings. They are defined much like a normal variable—they start with the variable ($) indicator followed by the array name:


Just like a variable, I use the equal sign (=) to define it.

$tempfolders =

Here is where the arrays and variables differ when defining. I start with the array indicator (@):

$tempfolders = @

And I follow it with parentheses to group strings together:

$tempfolders = @()

What you put inside the parentheses is your choice. For my purposes, I fill it with temp folder paths:

$tempfolders = @( "C:\Windows\Temp\*", "C:\Windows\Prefetch\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*" )

Notice that each string is neatly encapsulated by double quotation marks (“ ”) and separated by a comma and a space (, ). The quotation marks are necessary for any string with a space in it, and the comma with a space separates the values. Both are essential to define an array. Additionally you can see that each string ends with a wildcard character. This is going to remove the necessity for me to define exactly what to remove in the next line.

Now I use the Remove-Item cmdlet again; but this time for the -path operator, I use the $tempfolders array variable:

Remove-Item $tempfolders -force -recurse

This line instructs Windows Powershell to do exactly the same as previously, but for every item in the array.

Side-by-side, here are the two versions of the script:

1 Set-Location “C:\Windows\Temp”

2 Remove-Item * -recurse -force

3 Set-Location

4 “C:\Windows\Prefetch”

5 Remove-Item * -recurse -force

6 Set-Location “C:\Documents and Settings”

7 Remove-Item “.\*\Local

8 Settings\temp\*” -recurse -force

9 Set-Location “C:\Users”

10 Remove-Item “.\*\Appdata\Local\Temp\*” -recurse -force


1 $tempfolders = @("C:\Windows\Temp\*", "C:\Windows\Prefetch\*", "C:\Documents and Settings\*\Local Settings\temp\*", "C:\Users\*\Appdata\Local\Temp\*")

2 Remove-Item $tempfolders -force -recurse


With two lines of code, I was able to save myself between three minutes and 30 minutes of work. This is the purpose of scripting at its finest: automate repetitive tasks to allow the technician to do more in-depth work. Thank you all for reading, and as always, let me know if you have developed a better way!


Bob, thanks again for a real world example and a great suggestion. Join us tomorrow for a blog post by Boe Prox about installing WSUS on Windows Server 2012. It is a great blog and I am sure you will enjoy it.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (14)

  1. jrv says:


    That won't work because there is no mapping from "C:Users*AppdataLocalTemp*"   to $env:temp.

    $env:temp only works for the admin account and you need to purge ALL temp folders when cleaning up from malware.

  2. SCSM says:

    Hi All,

    I have downloaded the Cleanup.vbs script form the below site.


    I have created a new folder & deleted the same. Then it went to Recycle bin.

    After that I have ran the Script & its cleaned the Recycle bin. So I confirmed that, the script is working fine in a fast manner.

    OBSERVATION: When you run this script, its visible for the users, So users can cancel it. so I want to implement Script or .bat file in a silent mode, after the first login for users. How to do that via a Group Policy for all the desktoplaptops users.

    In the downloaded script, they mentioned need to be modify the Reg keys, But I didn’t make any change din my pc.

    Is it mandatory to edit the Reg keys?

    After cleaning the pc, No output displayed, but its cleaned . Is there any log file will be save somewhere in the Pc. I want to see, how many GB or MB files are cleaned.

    I would like to implement this script to all desktoplaptops pcs via a Group Policy, how to do that.

    I would like to run this script for the user first login & for every days.

    Please let me know the procedure for the above task.

    Or if any other bat files , please share the same.

  3. Hi Ed,

    In the above script, Remove-Item * -force will also work in the same way as Remove-Item * -recurse -force. Any reason why you used recurse here????


  4. Sean Kearney says:


    Nicely done!  Automation is a breeze with just a little Powershell.

    Coolest thing is if you had to TEST this and you had no test environment?   You can add a -whatif to your Remove-Item to show you what it is about to do without ACTUALLY doing it 🙂

  5. Jk says:

    Think you have a typo.

    Shouldn't "-temp" be "-force" ?

  6. kt says:

    Hi Ed,

    I'm wondering, what if we had different OSes (ex. XP, Vista7) in organization and we want to clean "TEMP's" on all client systems ? It will be right to use Test-Path before any Set-Location and then Remove-Item, something like this:

    $tempfolders = @('..','..')

    foreach($t in $tempfolders) {

     if(Test-Path $t)


       set-location ……





       Write-Host "There  is no: "$t




  7. kt says:

    Sorry, I've just got it 🙂

    $tempfolders = @( "C:WindowsTemp*", "C:WindowsPrefetch*", "C:Documents and Settings*Local Settingstemp*", "C:Users*AppdataLocalTemp*" )

    $tempfolders = @( "C:WindowsTemp*", "C:WindowsPrefetch*", $env:Temp) -> i think it will be better 🙂 and "Test-Path" is not necessary.


  8. Bob Stevens says:


    Your absolutly right!

    That should be -force.

    I cant believe I missed it.

    -Bob Stevens

  9. Mike W. says:

    This is great!  I work as an on-site tech (2nd level) and have a HARD time finding PS tools/scripts/etc. that folks like us can use to work with end-users.  I work in a global enterprise and we don't have domain admin rights; we've got some admin rights through a custom securtity group.  This means that we don't have access to to servers other than to read the info – and that's only on some of the servers.

    I look forward to more PS that can help those of us who work with end-users day-in and day-out.

  10. Bob Stevens says:


    I did use the -Whatif parameter while writing the code, but I tested it in a safe enviorment first.  It's my standing policy to be carefull when working with the Remove-Item command.

    Sean Kearney 14 Apr 2013 11:08 AM


    Nicely done!  Automation is a breeze with just a little Powershell.

    Coolest thing is if you had to TEST this and you had no test environment?   You can add a -whatif to your Remove-Item to show you what it is about to do without ACTUALLY doing it 🙂

  11. bill4 says:

    i am trying to run this script and i get permission error saying it is in use by another person or process

  12. Dan_IT says:

    Hi Ed – thanks for the script – how would I edit the script to run every month or couple of weeks?

  13. H3xCmd says:

    What if a specific temp file is in use with another process that may or may not be running, you may think its not running but it is running in the background for a specific program to be "on call" or "on demand" when the process and task is executed again.
    one thing I know about power shell is that if a task in the script halts/stops, the script cannot continue and cannot proceed/completing the written task. meaning if I run this fabulous 2 line code, and there is a break, the rest of the code will not execute.
    – this is the problem I am running into. where I have to stop all processes , halt any windows OS and program functions, execute, and restart. not good if there are present Junkware, bloatware, and any hindering unwanted programs accidentally downloaded and
    installed. I do agree though on a perfect system as routine maintenance this will work flawlessly.

  14. felix says:


    How can I exclude the same folder from all user profiles? It is deleted if I try
    Remove-Item $tempfolders -exclude "C:Users*AppdataLocalTempMyFolder" -force -recurse

Skip to main content