So how do we clean up them orphaned icons!?

So we recently posted on orphaned icon files that could potentially be left behind in the users %appdata% . Well I was recently chatting to Kalle Saunamäki  from www.virtualapp.net and one of the tools that he was working on was the SoftGridJanitor. The SoftGridJanitor can help organisations clean up any old orphaned icons, bats, osd's that may have been left.
This has literally just been released and has some great possibilities so it would be well worth you starting to test this script in your test/dev environments for its potential use.

The Cleanup/maintenance script is to be run under user's context in order to clear out leftover files from SoftGrid data directory.
This script will examine which cached ICO (icon) files are currently referenced by active applications and associated FTAs (file types) and/or whether there is any leftover .bat files (in form of swxxxx.bat, created by SoftGrid Client but sometimes not properly deleted after use) from OSD SCRIPTBODY -scripting. If "orphaned" files are found, they will be removed to save space on user's profile directory which is the default location where SoftGrid Client will cache user-specific data. For orphaned .bat files, age threshold can be adjusted to prevent script from deleting any .bat -files currently active by SoftGrid Client.
Alternatively script can be run in Report Only -mode, which will display (provided that output is enabled) those files that are considered to be removable by the script but not actually remove them.

Script will, by default and for safety reasons, run in Report Only -mode so be sure to change it to fully operational before actually deploying!

Visual Basic scripting support enabled

Download

SoftGridProfileJanitor 1.0 - As VBS file (might be blocked by more aggressive content-filtering firewalls)

SoftGridProfileJanitor 1.0 - As ZIP package

(revision history)

Usage

You can execute script using either cscript.exe (runs in console-window) or wscript.exe (does not show console) by issuing command:

cscript.exe //nologo ..path_to..\ SoftGridProfileJanitor.vbs

wscript.exe //nologo ..path_to..\ SoftGridProfileJanitor.vbs

This command can then be included in logon-scripts, Run-key in registry etc. to have it run when user logs on; important thing is to make sure script is really run in user's context rather than in machine-context. Inside script, you can change following variables to affect script operation:

    1: ' Script parameters
    2: ' ------------------------------------------------
    3:  
    4: ' Change to False to get error/status messages
    5: Silent = True
    6:  
    7: ' Change to False to actually delete orphaned ICOs and sw00xxx.bat scripts.
    8: ' Otherwise, report only (if Silent = False) those that are found
    9: ReportOnly = True
   10:  
   11: ' Change to False to skip search of orphaned ICOs for reporting / deletion
   12: SearchOrphanICOs = True
   13:  
   14: ' Change to False to skip search of orphaned sw00xx.bat files for reporting / deletion
   15: SearchLeftoverScripts = True
   16:  
   17: ' How old in minutes cached script must be before it's considered for deletion,
   18: ' use for failsafe to bypass deletion of scripts that currently runs (default: 5 [minutes])
   19: ' Requires ReportOnly = False and SearchLeftoverScripts = True to be set.
   20: AgeThreshold = 5
   21:  
   22: ' ------------------------------------------------

Silent = True (default) to run everything silently or False to output status and error messages. Non-silent mode might not be wanted behavior when running with wscript.exe as it will prompt dialog boxes to user for each and every message, but if script is run for reporting purposes silent -mode needs to be switched off.

ReportOnly = True (default) to only report on files that script consider eligible for removal. If you want script to actually do cleanup, change to False.

SearchOrphanICOs = If set to True (default) will perform search and cleanup (mode of operation dependent on ReportOnly parameter) of orphaned ICO files for applications and FTAs no longer available to user. Change to False to skip search for ICOs.

SearchLeftoverScripts = If set to True (default) will perform search and cleanup (mode of operation dependent on ReportOnly parameter) of leftover OSD scripting scripts. Change to False to skip search for swxxxx.bat files.

AgeThreshold = File [creation] age in minutes (5 by default) that much be exceeded by leftover script before it's removed. This parameter is used as failsafe -limit which will prevent script from deleting OSD scripts currently running if. If long-running SCRIPTBODY -scripts are used in OSDs, consider increasing threshold.

The Full Script is below and I will do an post mortem later on to show you whats going on..... (I have been meaning to do this for the Preload Script which also has just been updated to version 1.3).

The script is obviously Not Microsoft Supported but it is something that the community has been calling for.

    1: ' SoftGridProfileJanitor 1.0 [20070721]
    2: ' (c) 2007 Kalle Saunamäki (kalle@saunamaki.fi - https://www.virtualapp.net/), All rights reserved
    3: ' 
    4: ' This script clears out leftover ICOs and OSD SCRIPTBODY -scripts in user's SoftGrid profile directory, 
    5: ' optionally only reports on orphaned files but do not delete them.
    6: '  
    7: ' Run the script either with cscript.exe or wscript.exe (more useful for silent operation):
    8: ' wscript.exe //nologo SoftGridProfileJanitor.vbs
    9:  
   10: Option Explicit
   11:  
   12: Dim Silent, ReportOnly, SearchOrphanICOs, SearchLeftoverScripts, AgeThreshold
   13: Dim SoftGridMimePath, SoftgridMimeQueryPath, UserDataPath
   14: ReDim ICOsInUse(0)
   15: Dim WshShell, WshFSO, oExec
   16:  
   17: ' Script parameters
   18: ' ------------------------------------------------
   19:  
   20: ' Change to False to get error/status messages
   21: Silent = True
   22:  
   23: ' Change to False to actually delete orphaned ICOs and sw00xxx.bat scripts.
   24: ' Otherwise, report only (if Silent = False) those that are found
   25: ReportOnly = True
   26:  
   27: ' Change to False to skip search of orphaned ICOs for reporting / deletion
   28: SearchOrphanICOs = True
   29:  
   30: ' Change to False to skip search of orphaned sw00xx.bat files for reporting / deletion
   31: SearchLeftoverScripts = True
   32:  
   33: ' How old in minutes cached script must be before it's considered for deletion,
   34: ' use for failsafe to bypass deletion of scripts that currently runs (default: 5 [minutes])
   35: ' Requires ReportOnly = False and SearchLeftoverScripts = True to be set.
   36: AgeThreshold = 5
   37:  
   38: ' ------------------------------------------------
   39:  
   40: Function ReadSoftGridPath
   41:     Dim ClientPath
   42:  
   43:     On Error Resume Next
   44:     
   45:     ClientPath = WshShell.RegRead("HKLM\SOFTWARE\Softricity\SoftGrid Client\CurrentVersion\Configuration\InstallPath")
   46:     
   47:     On Error Goto 0
   48:     
   49:     If IsEmpty(ClientPath) Then
   50:         ReadSoftGridPath = False
   51:     Else    
   52:         ReadSoftgridPath = True
   53:         SoftGridMimePath = ClientPath & "\sftmime.exe"
   54:     End If
   55:     
   56: End Function
   57:  
   58: Function ReadUserDataPath
   59:  
   60:     On Error Resume Next
   61:     
   62:     UserDataPath = WshShell.RegRead("HKCU\Software\Softricity\SoftGrid Client\CurrentVersion\UserInfo\DataDirectory")
   63:     
   64:     On Error Goto 0
   65:     
   66:     If IsEmpty(UserDataPath) Then
   67:         ReadUserDataPath = False
   68:     Else
   69:         ReadUserDataPath = True
   70:     End If
   71:  
   72: End Function
   73:  
   74: Function MatchAndPurgeIcos
   75:     ' Will purge ICOs no longer associated with applications and/or FTAs
   76:  
   77:     Dim IcoFolderPath,IcoFile
   78:     Dim oIcoFolder, oIcoFiles
   79:     Dim FileToDelete
   80:     ReDim ICOsToRemove(0)
   81:     
   82:     IcoFolderPath = UserDataPath & "\Icon Cache"
   83:     
   84:     If WshFSO.FolderExists(IcoFolderPath) Then
   85:         Set oIcoFolder = WshFSO.GetFolder(IcoFolderPath)
   86:         Set oIcoFiles = oIcoFolder.Files
   87:         
   88:         ' Read in ICO files in user's directory
   89:         
   90:         On Error Resume Next
   91:         
   92:         For Each IcoFile In oIcoFiles
   93:             If Right(UCase(IcoFile.Path),3) = "ICO" Then
   94:                 If UBound(Filter(ICOsInUse,IcoFile.Path)) = -1 Then
   95:                     ' Icon in directory not used by App or FTA
   96:                     ICOsToRemove(UBound(ICOsToRemove)) = IcoFile.Path
   97:                     ReDim Preserve ICOsToRemove(UBound(ICOsToRemove) + 1 )
   98:                     
   99:                     If Silent = False Then
  100:                         WScript.echo "Orphaned icon found: " & IcoFile.Path
  101:                     End If
  102:                     
  103:                 End If
  104:             End If
  105:         Next
  106:         
  107:         If ReportOnly = False Then
  108:             ' Delete orphaned files
  109:             For Each FileToDelete In ICOsToRemove            
  110:                 WshFSO.DeleteFile(FileToDelete)
  111:             Next
  112:         End If
  113:         
  114:         On Error Goto 0
  115:         
  116:         MatchAndPurgeIcos = True
  117:     Else
  118:         MatchAndPurgeIcos = False
  119:     End If
  120:  
  121: End Function
  122:  
  123: Function PurgeScripts
  124:     ' Will purge OSD scripts that might be left behind after execution
  125:     
  126:     Dim oScriptFolder, oScriptFiles    
  127:     Dim ScriptFile
  128:     Dim FileAge
  129:     
  130:     If WshFSO.FolderExists(UserDataPath) Then
  131:         Set oScriptFolder = WshFSO.GetFolder(UserDataPath)
  132:         Set oScriptFiles = oScriptFolder.Files
  133:         
  134:         On Error Resume Next
  135:         
  136:         For Each ScriptFile In oScriptFiles
  137:             If (Right(UCase(ScriptFile.Name),3) = "BAT") And (Left(UCase(ScriptFile.Name),2) = "SW") Then
  138:                     ' Check that creation date goes beyond age threshold
  139:                     FileAge = DateDiff("n",ScriptFile.DateCreated,Now)
  140:                     If FileAge > AgeThreshold Then
  141:                         If Silent = False Then
  142:                             WScript.echo "Orphaned OSD script found: " & ScriptFile.Path
  143:                         End If
  144:                         
  145:                         If ReportOnly = False Then
  146:                             WshFSO.DeleteFile(ScriptFile.Path)
  147:                         End If
  148:                     End If
  149:             End If
  150:         Next
  151:         
  152:         On Error Goto 0
  153:     
  154:         PurgeScripts = True
  155:     Else
  156:         PurgeScripts = False
  157:     End If
  158:     
  159: End Function
  160:  
  161: Function ParseInUseICOs
  162:     Dim FileLine, LineDetails, AppFile, FtaFile
  163:     Dim AppsListTempFile, FtaListTempFile
  164:     Dim ServerAddrStart, ServerAddrEnd
  165:     ReDim GuidList(0)    
  166:     Dim temp
  167:     Dim CodebaseDetected, EncodingChange, BadOSD
  168:     
  169:     AppsListTempFile = WshShell.ExpandEnvironmentStrings("%temp%") & "\~sgprofapp.lst"
  170:     FtaListTempFile = WshShell.ExpandEnvironmentStrings("%temp%") & "\~sgproffta.lst"
  171:     
  172:     ' Query applications
  173:  
  174:     SoftgridMimeQueryPath = SoftgridMimePath & " query obj:app /log " & AppsListTempFile
  175:     Set oExec = WshShell.Exec(SoftgridMimeQueryPath)
  176:     
  177:     Do While oExec.Status = 0
  178:          WScript.Sleep 100
  179:     Loop
  180:     
  181:     ' Query filetypes
  182:     
  183:     SoftgridMimeQueryPath = SoftgridMimePath & " query obj:type /log " & FtaListTempFile
  184:     Set oExec = WshShell.Exec(SoftgridMimeQueryPath)
  185:     
  186:     Do While oExec.Status = 0
  187:          WScript.Sleep 100
  188:     Loop
  189:     
  190:     If (WshFSO.FileExists(AppsListTempFile)) And (WshFSO.FileExists(FtaListTempFile)) Then
  191:     
  192:         Set AppFile = WshFSO.OpenTextFile(AppsListTempFile, 1)
  193:         
  194:         Do Until AppFile.AtEndOfStream
  195:             FileLine = AppFile.Readline
  196:             LineDetails = Split(FileLine , Chr(9))
  197:  
  198:             ICOsInUse(UBound(ICOsInUse)) = LineDetails(3)
  199:             ReDim Preserve ICOsInUse(UBound(ICOsInUse) + 1)            
  200:         Loop
  201:         
  202:         AppFile.Close()
  203:         
  204:         ' Delete temporary file        
  205:         WshFSO.DeleteFile(AppsListTempFile)
  206:         
  207:         Set FtaFile = WshFSO.OpenTextFile(FtaListTempFile, 1)
  208:         
  209:         Do Until FtaFile.AtEndOfStream
  210:             FileLine = FtaFile.Readline
  211:             LineDetails = Split(FileLine , Chr(9))
  212:  
  213:             ICOsInUse(UBound(ICOsInUse)) = LineDetails(3)
  214:             ReDim Preserve ICOsInUse(UBound(ICOsInUse) + 1)            
  215:         Loop
  216:         
  217:         FtaFile.Close()
  218:         
  219:         ' Delete temporary file        
  220:         WshFSO.DeleteFile(FtaListTempFile)        
  221:         
  222:         ParseInUseICOs = True
  223:     Else
  224:         ParseInUseICOs = False
  225:     End If
  226:  
  227: End Function
  228:  
  229:  
  230: ' Main body
  231:  
  232: If Silent = False Then
  233:     WScript.echo "SoftGridProfileJanitor 1.0"
  234:     WScript.echo "(c) 2007 Kalle Saunamäki (kalle@saunamaki.fi) - https://www.virtualapp.net/"
  235:     WScript.echo ""
  236: End If
  237:  
  238: ' Initialize WSH objects
  239:  
  240: Set WshShell = CreateObject("WScript.Shell")
  241: Set WshFSO = CreateObject("Scripting.FileSystemObject")
  242:  
  243: If (ReadSoftGridPath = True) And (ReadUserDataPath = True) Then
  244:     ' Check if SoftGrid Client exists on this machine
  245:     If Not (WshFSO.FileExists(SoftgridMimePath)) Then
  246:         If Silent = False Then
  247:             WScript.echo "Could not found SoftGrid Client from this machine!"
  248:         End If
  249:     Else
  250:         If WshFSO.FolderExists(UserDataPath) Then
  251:             
  252:             ' (Optionally) purge leftover ICOs
  253:             If SearchOrphanICOs = True Then
  254:                 If ParseInUseICOs = True Then
  255:                     If MatchAndPurgeIcos = False Then
  256:                         WScript.echo "Could not query cached ICOs!"
  257:                     End If
  258:                 Else
  259:                     If Silent = False Then
  260:                         WScript.echo "Could not query application/FTA information from client!"
  261:                     End If
  262:                 End If
  263:             End If
  264:             
  265:             ' (Optionally) purge leftover scripts
  266:             If SearchLeftoverScripts = True Then
  267:                 If PurgeScripts = False Then
  268:                     If Silent = False Then
  269:                         WScript.echo "Could not remove leftover scripts!"
  270:                     End If                
  271:                 End If            
  272:             End If
  273:  
  274:         Else        
  275:             If Silent = False Then
  276:                 WScript.echo "SoftGrid data directory not found!"
  277:             End If
  278:         End If
  279:     End If
  280: Else
  281:     If Silent = False Then
  282:         WScript.echo "SoftGrid client or user SoftGrid profile not found!"
  283:     End If    
  284: End If