'It is recommended to test the script on a local machine for its purpose and effects.
'ManageEngine Endpoint Central will not be responsible for any
'damage/loss to the data/setup based on the behavior of the script.
'Description - Script to Clean temp files, Thumbs.db and recycle bin for all users
'Parameters  -
'Remarks     -
'Configuration Type - COMPUTER
'==============================================================

On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002

Set fso      = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
strComputer  = "."

Set objWMIService       = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

For Each objOperatingSystem In colOperatingSystems
    Osname = objOperatingSystem.Caption
Next

If InStr(Osname, "Windows XP") <> 0 Then
    profpath     = "\Local Settings\Temp"
    recyclerpath = "\recycler\"
    cookiespath  = "%USERPROFILE%\Cookies"
Else
    profpath     = "\AppData\Local\Temp"
    recyclerPath = "\$recycle.bin\"
    cookiespath  = "%APPDATA%\Microsoft\Windows\Cookies"
End If

Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
objRegistry.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubkeys

'For cleaning Appdata for every user profile
For Each objSubkey In arrSubkeys
    strValueName = "ProfileImagePath"
    strSubPath   = strKeyPath & "\" & objSubkey
    objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, strSubPath, strValueName, strValue

    If Not IsValidPath(strValue) Then
        strValue = ""
    End If

    If strValue <> "" Then

        If fso.FolderExists(strValue & profpath) Then
            Set objTempFolder = fso.GetFolder(strValue & profpath)
            If InStr(objTempFolder.Path, "systemprofile") = 0 And _
               InStr(objTempFolder.Path, "LocalService")  = 0 And _
               InStr(objTempFolder.Path, "NetworkService") = 0 Then

                For Each oFile In objTempFolder.Files
                    If PathIsUnder(oFile.Path, objTempFolder.Path) Then
                        fso.DeleteFile oFile.Path, True
                    End If
                Next
                For Each oSubFolder In objTempFolder.SubFolders
                    If PathIsUnder(oSubFolder.Path, objTempFolder.Path) Then
                        Call KillSubFolders(oSubFolder)
                    End If
                Next

            End If
        End If

        If InStr(strValue, "systemprofile") = 0 And _
           InStr(strValue, "LocalService")  = 0 And _
           InStr(strValue, "NetworkService") = 0 Then
            If fso.FolderExists(strValue) Then
                Call DeleteThumbsDB(strValue)
            End If
        End If

    End If

Next

'For cleaning Windows Temp folder
Dim winTempPath : winTempPath = WshShell.ExpandEnvironmentStrings("%TEMP%")
If fso.FolderExists(winTempPath) Then
    Set oFolder = fso.GetFolder(winTempPath)
    For Each oFile In oFolder.Files
        If PathIsUnder(oFile.Path, winTempPath) Then
            fso.DeleteFile oFile.Path, True
        End If
    Next
    For Each oSubFolder In oFolder.SubFolders
        If PathIsUnder(oSubFolder.Path, winTempPath) Then
            Call KillSubFolders(oSubFolder)
        End If
    Next
End If
WScript.Echo "Temp Cleanup Completed."

'For cleaning Windows prefetch folder
Dim prefetchPath : prefetchPath = WshShell.ExpandEnvironmentStrings("%systemroot%\prefetch")
If fso.FolderExists(prefetchPath) Then
    Set oFolder = fso.GetFolder(prefetchPath)
    For Each oFile In oFolder.Files
        If PathIsUnder(oFile.Path, prefetchPath) Then
            fso.DeleteFile oFile.Path, True
        End If
    Next
    For Each oSubFolder In oFolder.SubFolders
        If PathIsUnder(oSubFolder.Path, prefetchPath) Then
            Call KillSubFolders(oSubFolder)
        End If
    Next
End If
WScript.Echo "Windows prefetch folder Cleanup Completed."

'For cleaning cookies folder
Dim cookiesFullPath : cookiesFullPath = WshShell.ExpandEnvironmentStrings(cookiespath)
If fso.FolderExists(cookiesFullPath) Then
    Set oFolder = fso.GetFolder(cookiesFullPath)
    For Each oFile In oFolder.Files
        If PathIsUnder(oFile.Path, cookiesFullPath) Then
             fso.DeleteFile oFile.Path, True
        End If
    Next
    For Each oSubFolder In oFolder.SubFolders
        If PathIsUnder(oSubFolder.Path, cookiesFullPath) Then
            Call KillSubFolders(oSubFolder)
        End If
    Next
End If

WScript.Echo "Cookies Cleanup Completed."

'For cleaning Recycle bin
Set objSWbemServices = GetObject("WinMgmts:Root\Cimv2")
Set colDisks = objSWbemServices.ExecQuery("Select * From Win32_LogicalDisk Where DriveType = 3")
For Each objDisk In colDisks
    Dim recycleFullPath : recycleFullPath = objDisk.DeviceId & recyclerPath
    If fso.FolderExists(recycleFullPath) Then
        Set oFolder = fso.GetFolder(recycleFullPath)
        For Each oFile In oFolder.Files
            If PathIsUnder(oFile.Path, recycleFullPath) Then
                fso.DeleteFile oFile.Path, True
            End If
        Next
        For Each oSubFolder In oFolder.SubFolders
            If PathIsUnder(oSubFolder.Path, recycleFullPath) Then
                Call KillSubFolders(oSubFolder)
            End If
        Next
    End If
Next
' PowerShell fallback for modern OS recycle bin metadata cleanup
Dim rbRC
rbRC = WshShell.Run("powershell.exe -NoProfile -ExecutionPolicy Bypass -Command Clear-RecycleBin -Force -ErrorAction SilentlyContinue", 0, True)
If rbRC <> 0 Then
    Set objShellApp = CreateObject("Shell.Application")
    objShellApp.NameSpace(10).Self.InvokeVerb "empty"
End If
WScript.Echo "Recycle Bin Cleanup Completed."


'For cleaning Windows Search database - Windows.db and related files
'Stops Windows Search service to release file locks; service will rebuild index on next start
WshShell.Run "cmd.exe /c net stop wsearch /y", 0, True
Dim winSearchPath : winSearchPath = "C:\ProgramData\Microsoft\Search\Data\Applications\Windows"
If fso.FolderExists(winSearchPath) Then
    Set oFolder = fso.GetFolder(winSearchPath)
    For Each oFile In oFolder.Files
        If PathIsUnder(oFile.Path, winSearchPath) Then
            fso.DeleteFile oFile.Path, True
        End If
    Next
    For Each oSubFolder In oFolder.SubFolders
        If PathIsUnder(oSubFolder.Path, winSearchPath) Then
            Call KillSubFolders(oSubFolder)
        End If
    Next
End If
WshShell.Run "cmd.exe /c net start wsearch", 0, True
WScript.Echo "Windows Search Database (Windows.db) Cleanup Completed."


'For disabling hibernation to remove hiberfil.sys (#1)
'NOTE: This disables the Windows hibernation feature.
'      To re-enable hibernation later, run: powercfg /h on
WshShell.Run "powercfg /h off", 0, True
Dim hiberFile : hiberFile = "C:\hiberfil.sys"
If fso.FileExists(hiberFile) Then
    WScript.Echo "Hibernation disabled - hiberfil.sys still present. The OS will remove it on next restart."
Else
    WScript.Echo "Hibernation disabled - hiberfil.sys removed successfully."
End If

Sub KillSubFolders(SubPath)
    fso.DeleteFolder SubPath, True
End Sub

'For cleaning thumbs.db 
Sub DeleteThumbsDB(folderPath)
    If fso.FolderExists(folderPath) Then
        Set folderObj = fso.GetFolder(folderPath)
        If fso.FileExists(folderPath & "\Thumbs.db") Then
            fso.DeleteFile folderPath & "\Thumbs.db", True
        End If
        For Each subFolder In folderObj.SubFolders
	    If PathIsUnder(subFolder.Path, folderPath) Then
		Call DeleteThumbsDB(subFolder.Path)
	    End If
	Next
    End If
End Sub

WScript.Echo "Thumbs.db cleanup Completed."

Function IsValidPath(p)
    IsValidPath = False
    If IsNull(p) Or IsEmpty(p) Or Len(p) < 3 Then Exit Function
    If Not (Mid(p,2,1) = ":" And Mid(p,3,1) = "\") Then Exit Function
    If InStr(p, "..\") <> 0 Then Exit Function
    If InStr(p, "../") <> 0 Then Exit Function
    IsValidPath = True
End Function

Function PathIsUnder(childPath, parentPath)
    Dim parent : parent = LCase(parentPath)
    Dim child  : child  = LCase(childPath)
    If Right(parent, 1) <> "\" Then parent = parent & "\"
    PathIsUnder = (Left(child, Len(parent)) = parent)
End Function

WScript.Echo "Disk Cleanup Completed."
