Clean Windows Junk Files using PowerShell Script

Junk Files! Sounds unhealthy, but unfortunately that is not the case. If you ask your tech expert, even they will suggest you to delete it regularly. You have no idea, at what extent the temporary files created. So, why to keep such files in your computer which can increase the risk for sort of problem and can decrease the performance in the terms of utilizing unnecessary disk space. Although you have huge storage system but that doesn’t make sense. It definitely makes your computer slow to operate or sometimes your computer can go unresponsive.

clean-junk-files-using-PowerShell


Download Script 342 downloads

How Junk Files are created ?
Every time when you run some program like Microsoft Word, Excel or web browsers. To provide a better response, temporary files are created and stored on the disk by the running program. When the program are terminated, those files are not deleted automatically. This happens most probably and Later on, these files becomes outdated and reside remain on the disk. So, when you try to run another application, the program takes longer time to scan the temporary files and this process affect your system performance.

Advantages of cleaning Junk Files
Deleting junk files helps your system to provide a better performance and makes your application program more stable. Junk Files consuming a huge space on the disk sometimes in Gigs. So, deleting such files can save wastage of huge space.

If you are dealing with a single system, you can manage to delete the junk files manually but what if you are dealing with thousands number of system in your infrastructure. A bulk amount of junk files will be generated every day and you cannot make an effort to clean it on all the server one by one.

Now, a days different kind of software are available to perform this task but you will no longer needed these software if you know PowerShell

Creating PowerShell Script

Let’s see how can we achieve this .We will create a PowerShell Script which will delete junk files from the directory like RecycleBin, Local Temp, System Temp folder and WinEvt Logs.

So, Here We go….

We will create some more functions to make our task easy and more effective.
Ping-Host :To check if the server is pingable
Trim-String :To remove left and right space from server name
Get-DiskStatus :To get the disk status of the server
Delete-RecyleBin : To clear Recyclebin folder
Delete-BasicStuffs : To clear folder like temp,system temp
Delete-EventLogs :To delete older winevt logs files

Basic script template
function Ping-Host {

 ...our ping codes...
                   }

function Trim-String {

..Removing space..
                     }

function Get-DiskStatus {

..get disk status...
                        }

function  Delete-RecyleBin {

..empty recyclebin..
                          }

function Delete-BasicStuffs {

..custom folders..

                            }

function Delete-EventLogs  {

..older event logs..

                            }

$ServersList = Get-Content -path servers.txt

foreach($Computer in $ServersList)
                  {

Trim-String

Ping-Host

Get-DiskStatus

Delete-RecyleBin

Delete-BasicStuffs 

Delete-EventLogs

Export-Csv
                  }
                     
Implementation of script
Setting up Variables

$Global:Flag : We are creating a global variable to track Get-DiskStatus function (not compulsory to be used) $ErrorActionPreference : If it is set to SilentlyContinue", then the script will ignore the non-terminating errors.


$Global:Flag
$ServersList=Get-Content -path servers.txt
$ErrorActionPreference="SilentlyContinue"

Coding for Ping-Host function


   function Ping-Host {

Param([string]$Computer)

Write-Host "Pinging the Server : " $Computer -ForegroundColor Cyan

$query="select * from Win32_PingStatus where address='$Computer'";

$PingData =Get-WmiObject -Query $query

return $PingData;
                  }

   
Coding for Trim-String function

   function Trim-String    {

Param([string]$Computer)
return $Computer.Trim();
                           }

   
Coding for Get-DiskStatus function

  function Get-DiskStatus {

Param([String]$Computer)

if ($Global:Flag -eq 0) {


Write-Host "Checking Disk Status......";

                        }


elseif ($Global:Flag  -eq 1) {

Write-Host "After deletion,Re-Checking Disk Status......" -ForegroundColor Green

                              }

 elseif($Global:Flag  -eq 2) {

Write-Host "Re-Checking Disk Status......" -ForegroundColor Green

                             }

elseif ($Global:Flag  -eq 3)
 {
 Write-Host "Let Me Check Final Disk Status......" -ForegroundColor Green
 }

$disk = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter "DeviceID='C:'"

if ($disk.size -gt 0) {

$PercentFree = [Math]::round((($disk.freespace/$disk.size) * 100))

                      }

       else {

       $PercentFree = 0

          }
Write-Host "The Disk Status on the Server :"$PercentFree"%" -ForegroundColor Yellow

$Global:Flag =$Global:Flag  +1


 return $PercentFree;


                    }

   
Coding for Delete-RecyleBin function

   function Delete-RecyleBin {

Param([String]$Path,[String]$Status)

if (Test-Path $Path) {

Write-Host "Deleting data from " $Status
 Get-ChildItem -Path $Path -Recurse -Force |`
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue


                    }
else {

  Write-Host  $Status "is not found this Server";

     }

                       }
   
Coding for Delete-BasicStuffs function

   function Delete-BasicStuffs   {

Param([String]$Path,[String]$Status)

if (Test-Path $Path) {

Write-Host "Deleting data from " $Status
<# Get-ChildItem -Path $Path -Recurse -Force |`
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
#>
Get-ChildItem -Path $Path -Include * -File -Recurse | foreach { $_.Delete() }

                      }
 else {

 Write-Host $Status "is not found on this Server";

       }

                              }
   
Coding for Delete-EventLogs function

Here, We are ignoring 64Kb and 68Kb Logs files.


  function Delete-EventLogs {

Param([String]$Path,[String]$Status,[String]$Time)

if (Test-Path $Path)
{

Write-Host "Deleting data from " $Status

Get-ChildItem -Path $Path -Recurse -Force | `

Where-Object {$_.LastWriteTime -lt $Time -AND $_.Length -gt 64Kb -AND $_.Length -gt 68Kb} | `

Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

   }

 else {

 Write-Host $Status "is not found on this Server";

       }

                          }
   
Coding for Main Body part

Here, I need to explain the process before you get confused.

Line no. 2 : We are calling each server one by one from the exported list via Get-Content cmdlet

Line no. 5 : We are initializing our variable

Line no. 7 : We are trying to remove the space with the function call

Line no. 7 - 13 : We are validating server whether it is reachable. if it is then the script will enter in the next block or else it is unreachable then it will jump to Line no. 94

Line no. 16 - 20 : Traget folders path are set for processing

Line no. 25 : Here We are calling the Get-DiskSatus for the first time so, we can get the exact free space of the drive at initial stage on the server. If the result is less than 15% then the script will call each function first time with adjusting the time Adddays(-15)(Line no. 33) that means script will look for event logs which is older than 15 days

Line no. 37,43,45 : Here We have set $Status variable with different folders name. By doing this, we can get idea what our script is doing right now.

Line no. 52 : We have checked the free disk space again. After executing the above block, the script may have cleard the Recycle bin, Software distrubution folder and 15 days older Event logs. But if the free space is still less than 15%, The script will execute next part for deleting the event logs older than 10 days(Line no. 58). On the line no. 66 and 70, it is repeating the same job there.

Line no. 86,100 : We are creating Custom Object to keep our output data returned by the script during run time.

Line no. 109 -111 : The data of $CustomObject is being exported to CSV file in the current folder of script


  foreach($Computer in $ServersList)
                                  { #foreach

$Global:Flag  = 0;

$Computer =Trim-String $Computer

if($Computer)   {

$PingData = Ping-Host $Computer

if($PingData.StatusCode -eq 0)
{

$RecylePath = "\\" + $Computer + "\c$\`$Recycle`.Bin"
$SoftDist ="\\" + $Computer + "\c$\Windows\SoftwareDistribution"
$WinEvtLogs ="\\" + $Computer + "\c$\Windows\System32\winevt\Logs"


"The Server responded in {0}ms " -f $PingData.ResponseTime

$DStatus=Get-DiskStatus $Computer

#Stage 1(for -15 days)

#Here Disk space will be checked for 15%, you can modify your own value like 10%)

     if($DStatus -lt 15)

 {

$time=(Get-Date).Adddays(-15)

Write-Host "Now accessing C drive........"

$Status="Recycle Bin folder"

Delete-RecyleBin $RecylePath $Status

$Status="Software Distrubution folder"

Delete-BasicStuffs $SoftDist $Status

$Status="Win Evt Logs folder"

Delete-EventLogs  -Path $WinEvtLogs -Status $Status -Time $time


#Stage2(for -10 days)
$DStatus=Get-DiskStatus $Computer

 if($DStatus -lt 15)
                     {

      $Status="Win Evt Logs folder"
      $time=(Get-Date).Adddays(-10)
      Delete-EventLogs $WinEvtLogs $Status $time

#Stage3( for -2 days)

$DStatus=Get-DiskStatus $Computer


if($DStatus -lt 15)
 {

 $Status="Win Evt Logs folder"
 $time=(Get-Date).Adddays(-2)
 Delete-EventLogs $WinEvtLogs $Status $time
 $DStatus=Get-DiskStatus $Computer

  }


                  }



            }


Write-Host " "

$CustomObject = [pscustomobject][ordered]@{
    ServerName      =$Computer
    FreeSpace  =' '+$DStatus+'% '
                                           }

                                                     }


else {

Write-Host "The Server is not reachable from source" $PingData.PSComputerName  -ForegroundColor Red

 Write-Host " "
   $CustomObject = [pscustomobject][ordered]@{
    ServerName      =$Computer
    FreeSpace  =' '+"UnReachable"
                                             }


  }


$CustomObject
$CustomObject |
 Export-Csv  DiskStatus.Csv -Append -NoTypeInformation

}
Write-Host " "
Write-Host " "

sleep  -Seconds 2

                                       } #Foreach

 Write-Host "Generating CSV File........" -ForegroundColor Gray

   
Adding new folder Eg:Temp

Here, We will see what changes we need to do if we are modify the above script for one more folder "Temp"

Below Line No. 20 : We need to add the following line

$Temp ="\\" + $Computer + "\c$\Windows\Temp"

Then, After Line no. 45 add these lines and your done with this.

 $Status="System Temp folder"

Delete-BasicStuffs $Temp $Status

People Reaction : 2

Ajay Singh
5th Oct 16 AT 11:06 PM Ajay Singh
Thanks buddy. I was really looking for this kind of script. Can you tell me one more thing, Windows Server 2008,12 have almost same file structure except 2003. Will it harm the server if i gonna try this there.
Rohit Sharma
5th Oct 16 AT 11:06 PM Rohit Sharma
Hi Ajay, This script will not work with windows server 2003 because 2003 has different folders hierarchy if compared to other servers like 2008 and 2012. Anyhow, the script will not harm the 2003 servers as we are already validating the folder paths via (Test-Path $Path)
Clement Bjelland
29th Jun 19 AT 5:59 AM Clement Bjelland
Hi, I created a web app that removes junk files from your Google Drive. As your drive gets synched with your PC and other devices, they will get cleaned too. Check it out: https://givemesomespace.net.
Rohit Sharma
Name : Email : Website :
Rohit Sharma

Hi There! My name is Rohit and I am working in the one of MNC as Web Apps developer. I have been in this tech industry for last 3.6 years. This blog is just a part of my career journey.
Ready to make new mistakes without repeating the previous ones.

"All life is an experiment. The more experiments you make the better"


© 2020 WriteSomeCode. All Right Reserved. A Rohit Sharma Blog. Creative Commons License licensed under a Creative Commons Attribution 4.0 International License