{"id":3829,"date":"2013-04-14T00:01:00","date_gmt":"2013-04-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/04\/14\/weekend-scripter-use-powershell-to-clean-out-temp-folders\/"},"modified":"2021-07-26T12:46:26","modified_gmt":"2021-07-26T19:46:26","slug":"weekend-scripter-use-powershell-to-clean-out-temp-folders","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-use-powershell-to-clean-out-temp-folders\/","title":{"rendered":"Weekend Scripter: Use PowerShell to Clean Out Temp Folders"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Guest blogger, Bob Stevens, talks about using Windows PowerShell to clean out temporary folders on desktops following a malware infection.<\/span><\/p>\n<p>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: <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/04\/13\/weekend-scripter-pick-comments-from-a-powershell-script.aspx\" target=\"_blank\" rel=\"noopener\">Weekend Scripter: Pick Comments from a PowerShell Script<\/a>.<\/p>\n<p>I made Bob\u2019s virtual acquaintance recently when I did a Live Meeting presentation to the Twin Cities PowerShell User Group.<\/p>\n<p>Here is Bob\u2019s contact information:<\/p>\n<p style=\"padding-left: 30px\">\n  Blog: <a href=\"http:\/\/stuckinmypowershell.blogspot.com\/\" target=\"_blank\" rel=\"noopener\">Help! I\u2019m Stuck In My Powershell!<\/a><br \/> Twitter: <a href=\"https:\/\/twitter.com\/B_stevens6\" target=\"_blank\" rel=\"noopener\">@B_stevens6<\/a><br \/> LinkedIn: <a href=\"http:\/\/www.linkedin.com\/profile\/edit?trk=hb_tab_pro_top\" target=\"_blank\" rel=\"noopener\">Robert Stevens<\/a>\n<\/p>\n<p>Take it away, Bob\u2026<\/p>\n<p>For a local service desk systems analyst, nothing is more frustrating than malware. Not only is it a time sink\u2014it also has the indented potential to cause irreparable damage. No network that connects to the Internet is immune to it.<\/p>\n<p>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.<\/p>\n<p>I started by creating a list of the locations that temporary files are automatically placed by the Windows\u00a0XP operating system (starting with Windows Vista, they are in the C:\\Users folder):<\/p>\n<ul>\n<li><span style=\"font-size: small\">C:\\Windows\\Temp<\/span><\/li>\n<li><span style=\"font-size: small\">C:\\Windows\\Prefetch<\/span><\/li>\n<li><span style=\"font-size: small\">C:\\Documents and Settings*\\Local Settings\\Temp<\/span><\/li>\n<li><span style=\"font-size: small\">C:\\Users*\\Appdata\\Local\\Temp<\/span><\/li>\n<\/ul>\n<p>Now that I have defined our locations, I need to define what I want to do. For this, I create a flowchart:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/6472.1.PNG\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Image of flowchart\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/6472.1.PNG\" alt=\"Image of flowchart\" \/><\/a><\/p>\n<p>I start with the <strong>Set-Location<\/strong> command and define the location as <strong>\u201cC:\\Windows\\Temp\u201d<\/strong>:<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Set-Location \u201cC:\\Windows\\Temp\u201d<\/p>\n<p>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 <strong>Del<\/strong>, but I prefer using the Windows Powershell cmdlet <strong>Remove-Item<\/strong> 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 (<strong>?<\/strong>) 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.<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">Remove-Item *<\/span>\n<\/p>\n<p>Next I tell the <strong>Remove-Item<\/strong> cmdlet to also remove all files in subdirectories with the <strong>-recurse<\/strong> switch:<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">Remove-Item * -recurse<\/span>\n<\/p>\n<p>And I tell it to select hidden files with the <strong>-force<\/strong> switch:<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">Remove-Item * -recurse -force<\/span>\n<\/p>\n<p>Together the two lines looked like this:<\/p>\n<p style=\"padding-left: 30px\">\n  Set-Location \u201cC:\\Windows\\Temp\u201d<br \/> Remove-Item * -recurse -force\n<\/p>\n<p>I do the same for the rest of the folders and the complete script begins to take shape:<\/p>\n<p style=\"padding-left: 30px\">\n  Set-Location \u201cC:\\Windows\\Temp\u201d<br \/> Remove-Item * -recurse -force\n<\/p>\n<p style=\"padding-left: 30px\">\n  Set-Location \u201cC:\\Windows\\Prefetch\u201d<br \/> Remove-Item * -recurse -force\n<\/p>\n<p style=\"padding-left: 30px\">\n  Set-Location \u201cC:\\Documents and Settings\u201d<br \/> Remove-Item \u201c.\\*\\Local Settings\\temp\\*\u201d -recurse -force\n<\/p>\n<p style=\"padding-left: 30px\">\n  Set-Location \u201cC:\\Users\u201d<br \/> Remove-Item \u201c.\\*\\Appdata\\Local\\Temp\\*\u201d -recurse -force\n<\/p>\n<p>Wait. Why is there an asterisk in the middle of the last path? You can use wildcard characters to do this:<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">Remove-Item \u201c.\\*\\Appdata\\Local\\Temp\\*\u201d -recurse -force<\/span>\n<\/p>\n<p>This says, \u201cLook in all folders in this directory with the path structure that matches this.\u201d In my case, this is all of the user profile Local Settings\\temp folders.<\/p>\n<p>But this looks very busy, so at Ed Wilson\u2019s suggestion, an array would prevent all the unnecessary jumping around with the <strong>Set-Location<\/strong> command. So we change our flowchart to look something like this:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0218.2.PNG\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Image of flowchart\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0218.2.PNG\" alt=\"Image of flowchart\" \/><\/a><\/p>\n<p><span style=\"font-size: 12px\">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\u2014they start with the variable (<\/span><strong style=\"font-size: 12px\">$<\/strong><span style=\"font-size: 12px\">) indicator followed by the array name:<\/span><\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">$tempfolders<\/span>\n<\/p>\n<p>Just like a variable, I use the equal sign (<strong>=<\/strong>) to define it.<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">$tempfolders =<\/span>\n<\/p>\n<p>Here is where the arrays and variables differ when defining. I start with the array indicator (<strong>@<\/strong>):<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">$tempfolders = @<\/span>\n<\/p>\n<p>And I follow it with parentheses to group strings together:<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">$tempfolders = @()<\/span>\n<\/p>\n<p>What you put inside the parentheses is your choice. For my purposes, I fill it with temp folder paths:<\/p>\n<p style=\"padding-left: 30px\">\n  $tempfolders = @( &#8220;C:\\Windows\\Temp\\*&#8221;, &#8220;C:\\Windows\\Prefetch\\*&#8221;, &#8220;C:\\Documents and Settings\\*\\Local Settings\\temp\\*&#8221;, &#8220;C:\\Users\\*\\Appdata\\Local\\Temp\\*&#8221; )\n<\/p>\n<p>Notice that each string is neatly encapsulated by double quotation marks (<strong>\u201c \u201d<\/strong>) 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.<\/p>\n<p>Now I use the <strong>Remove-Item<\/strong> cmdlet again; but this time for the <strong>-path<\/strong> operator, I use the <strong>$tempfolders<\/strong> array variable:<\/p>\n<p style=\"padding-left: 30px\">\n  <span style=\"font-size: small\">Remove-Item $tempfolders -force -recurse<\/span>\n<\/p>\n<p><span style=\"font-size: small\">This line instructs Windows Powershell to do exactly the same as previously, but for every item in the array.<\/span><\/p>\n<p><span style=\"font-size: small\">Side-by-side, here are the two versions of the script:<\/span><\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"313\">\n<p>\n          1 Set-Location \u201cC:\\Windows\\Temp\u201d\n        <\/p>\n<p>\n          2 Remove-Item * -recurse -force\n        <\/p>\n<p>\n          3 Set-Location\n        <\/p>\n<p>\n          4 \u201cC:\\Windows\\Prefetch\u201d\n        <\/p>\n<p>\n          5 Remove-Item * -recurse -force\n        <\/p>\n<p>\n          6 Set-Location \u201cC:\\Documents and Settings\u201d\n        <\/p>\n<p>\n          7 Remove-Item \u201c.\\*\\Local\n        <\/p>\n<p>\n          8 Settings\\temp\\*\u201d -recurse -force\n        <\/p>\n<p>\n          9 Set-Location \u201cC:\\Users\u201d\n        <\/p>\n<p>\n          10 Remove-Item \u201c.\\*\\Appdata\\Local\\Temp\\*\u201d -recurse -force\n        <\/p>\n<p>\n          \u00a0\n        <\/p>\n<\/td>\n<td valign=\"top\" width=\"325\">\n<p>\n          1 $tempfolders = @(&#8220;C:\\Windows\\Temp\\*&#8221;, &#8220;C:\\Windows\\Prefetch\\*&#8221;, &#8220;C:\\Documents and Settings\\*\\Local Settings\\temp\\*&#8221;, &#8220;C:\\Users\\*\\Appdata\\Local\\Temp\\*&#8221;)\n        <\/p>\n<p>\n          2 Remove-Item $tempfolders -force -recurse\n        <\/p>\n<p>\n          \u00a0\n        <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: small\">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!<\/span><\/p>\n<p><span style=\"font-size: small\">~Bob<\/span><\/p>\n<p>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.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[424,16,38,47,56,3,12,61,45],"class_list":["post-3829","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-bob-stevens","tag-desktop-management","tag-files","tag-general-management-tasks","tag-guest-blogger","tag-scripting-guy","tag-storage","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3829","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3829"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3829\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=3829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}