Wednesday, December 4, 2013

Cleanup a C: drive with Windows PowerShell

title

Being an overnight Administrator I get a lot of low disk space alerts when drives hit their thresholds. Tonight I’m going to put an end to all this work. I wrote the following script to help automate the cleaning of C:\ drives or any drives that have a Windows operating system installed.

What Does this Script do?

  1. Clears all code off the screen
  2. Stops the Windows Update Service
  3. Deletes the contents of Windows Software Distribution
  4. Deletes the contents of windows temp folder
  5. Deletes files in users temp folder
  6. Deletes temporary internet files
  7. Cleans IIS logs
  8. Empties the Recycling Bin
  9. Starts Windows update service
  10. Outputs disk space before and after.
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
<#
.CREATED BY:
    Matthew A. Kerfoot
.CREATED ON:
    10\17\2013
.Synopsis
   automate cleaning up a C: drive with low disk space
.DESCRIPTION
   Cleans up the C: drives temp files and other misc. unneeded files.
.EXAMPLE
   .\cleanup_log.ps1
#>
function global:Write-Verbose
   (
    [string]$Message
   )
    # check $VerbosePreference variable
   { if ( $VerbosePreference -ne 'SilentlyContinue' )
       { Write-Host " $Message" -ForegroundColor 'Yellow' } }
         Write-Verbose  
          $DaysToDelete = 7
          $LogDate = get-date -format "MM-d-yy-HH"
          $objShell = New-Object -ComObject Shell.Application 
          $objFolder = $objShell.Namespace(0xA) 
                    
            Start-Transcript -Path C:\Windows\Temp\$LogDate.log

            ## Cleans all code off of the screen.
            Clear-Host

          $Before = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,
          @{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
          @{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
          @{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
          @{ Name = "PercentFree" ; Expression = {"{0:P1}" -f( $_.FreeSpace / $_.Size ) } } |
          Format-Table -AutoSize | Out-String                      
                    
            ## Stops the windows update service.
            Get-Service -Name wuauserv | Stop-Service -Force -Verbose -ErrorAction SilentlyContinue
            ## Windows Update Service has been stopped successfully!

            ## Deletes the contents of windows software distribution.
            Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
            Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete)) } |
            remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
            ## The Contents of Windows SoftwareDistribution have been removed successfully!

            ## Deletes the contents of the Windows Temp folder.
            Get-ChildItem "C:\Windows\Temp\*" -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
            Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete)) } |
            remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
            ## The Contents of Windows Temp have been removed successfully!

            ## Deletes all files and folders in user's Temp folder.
            Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue |
            Where-Object { ($_.CreationTime -lt $(Get-Date).AddDays(-$DaysToDelete))} |
            remove-item -force -Verbose -recurse -ErrorAction SilentlyContinue
            ## The contents of C:\users\$env:USERNAME\AppData\Local\Temp\ have been removed successfully!
                    
            ## Remove all files and folders in user's Temporary Internet Files.
            Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Microsoft\Windows\Temporary Internet Files\*"
            -Recurse -Force -Verbose -ErrorAction SilentlyContinue |
            Where-Object {($_.CreationTime -le $(Get-Date).AddDays(-$DaysToDelete))} |
            remove-item -force -recurse -ErrorAction SilentlyContinue
            ## All Temporary Internet Files have been removed successfully!
                    
            ## Cleans IIS Logs if applicable.
            Get-ChildItem "C:\inetpub\logs\LogFiles\*" -Recurse -Force -ErrorAction SilentlyContinue |
            Where-Object { ($_.CreationTime -le $(Get-Date).AddDays(-60)) } |
            Remove-Item -Force -Verbose -Recurse -ErrorAction SilentlyContinue
            ## All IIS Logfiles over x days old have been removed Successfully!
                  
            ## deletes the contents of the recycling Bin.
            $objFolder.items() | ForEach-Object { Remove-Item $_.path -ErrorAction Ignore -Force -Verbose -Recurse }
            ## The Recycling Bin has been emptied!
            ## Starts the Windows Update Service
            
            Get-Service -Name wuauserv | Start-Service -Verbose

          $After =  Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq "3" } | Select-Object SystemName,
          @{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
          @{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f( $_.Size / 1gb)}},
          @{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f( $_.Freespace / 1gb ) } },
          @{ Name = "PercentFree" ; Expression = {"{0:P1}" -f( $_.FreeSpace / $_.Size ) } } |
          Format-Table -AutoSize | Out-String

     ## Sends some before and after info for ticketing purposes
     Hostname ; Get-Date | Select-Object DateTime
     Write-Host "Before: $Before"
     Write-Host "After: $After"

   Write-Verbose ( Get-ChildItem -Path C:\* -Include *.iso, *.vhd, *.vhdx -Recurse -ErrorAction SilentlyContinue | 
   Sort Length -Descending | Select-Object Name, Directory,
   @{Name="Size (GB)";Expression={ "{0:N2}" -f ($_.Length / 1GB) }} | Format-Table | 
   Out-String )

 ## Completed Successfully!
 Stop-Transcript
Now just open an elevated command prompt and run the this script.
 
Sample Output:

VT-MKERFOOT-W8
nbsp;
DateTime
--------
Thursday, December 04, 2014 5:00:15 MATTHEW
Before:
SystemName     Drive Size (GB) FreeSpace (GB) PercentFree
----------     ----- --------- -------------- -----------
VT-MKERFOOT-W8 C:    223.2     41.8           18.7 %
After:
SystemName     Drive Size (GB) FreeSpace (GB) PercentFree
----------     ----- --------- -------------- -----------
VT-MKERFOOT-W8 C:    223.2     45.9           20.5 %
VT-MKERFOOT-W8 C:    223.2     29.2           13.1 %

Transcript stopped, output file is C:\Windows\Temp\12-04-14-9.log
 
 
Note this would have cleaned up more files and given a long verbose string of files removed except I just ran this against my computer and it brought it from 18% free to 20% free(which was shown above). Now all you have to do is Download my script here!