I recently posted a script for removing unnecessary files and pruning files based on their age, which can be used at logoff to keep profile sizes manageable - Reducing Profile Size with a Profile Clean Up Script.
Andrew Morgan (@andyjmorgan) has kindly translated my very basic VBscript to PowerShell. This can be used as a standalone script or the function (remove-itembyage) could be integrated into your own scripts and has the added benefit of in-built help and the ability to run silently.
Just like the original script, this could be executed at logoff, before the profile is saved back to the network, to perform two actions:
Delete all files of a specific file type in a specified folder, including sub-folders
Delete all files older than X days in a specified folder, including sub-folders
For example, you could use the script to delete all .log or temporary files below %APPDATA% that aren’t required to be roamed, or delete all Cookies older than 90 days to keep the Cookies folder to a manageable size.
Note: the script listing below has the -whatif parameter applied when calling the function, so no deletes will occur unless the parameter is removed.
functionremove-itembyage{<#
.SYNOPSIS
remove items from folders recursively.
.DESCRIPTION
this function removes items older than a specified age from the target folder
.PARAMETER Days
Specifies the ammount of days since the file was last written to you wish to filter on.
.PARAMETER Path
Specifies the path to the folder you wish to search recursively.
.PARAMETER Silent
Instructs the function not to return any output.
.EXAMPLE
PS C:\> remove-itembyage -days 0 -path $recent
This command searches the $recent directory, for any files, then deletes them.
.EXAMPLE
PS C:\> remove-itembyage -days 5 -path $recent
This command searches the $recent directory, for files older than 5 days, then deletes them.
.EXAMPLE
PS C:\> remove-itembyage -days 10 -path $appdata -typefilter "txt,log"
This command searches the $cookies directory, for files older than 10 days and end with txt or log extensions, then deletes them.
.EXAMPLE
PS C:\> remove-itembyage -days 10 -path $cookies -typefilter "txt,log" -silent
This command searches the $cookies directory, for files older than 10 days and end with txt or log extensions, then deletes them without a report.
.NOTES
/user-virtualization/profile-clean-up-script-powershell-edition/ for support information.
.LINK
/user-virtualization/profile-clean-up-script-powershell-edition/
#>[cmdletbinding(SupportsShouldProcess=$True)]param([Parameter(Mandatory=$true,Position=0,HelpMessage="Number of days to filter by, E.G. ""14""")][int]$days,[Parameter(Mandatory=$true,Position=1,HelpMessage="Path to files you wish to delete")][string]$path,[string]$typefilter,[switch]$silent)#check for silent switchif($silent){$ea="Silentlycontinue"}Else{$ea="Continue"}#check for typefilter, creates an array if specified.if(!($typefilter)){$filter="*"}Else{$filter=foreach($itemin$typefilter.split(",")){$item.insert(0,"*.")}}if(test-path$path){$now=get-date$datefilter=$now.adddays(-$days)foreach($fileinget-childitem"$path\*"-recurse-force-include$filter|where{$_.PSIsContainer-eq$false-and$_.lastwritetime-le$datefilter-and$_.name-ne"desktop.ini"}){if(!($silent)){write-host"Deleting: $($file.fullname)"}remove-item-literalPath$file.fullname-force-ea$ea}#end for}#end ifElse{if(!($silent)){write-warning"the path specified does not exist! ($path)"}}#end else}#end function#Get KnownFolder Paths$appdata=$env:appdata$Cookies=(new-object-comshell.application).namespace(289).Self.Path$History=(new-object-comshell.application).namespace(34).Self.Path$recent=(new-object-comshell.application).namespace(8).Self.Path$profile=$env:userprofile#commandsremove-itembyage-days0-path$appdata-typefilter"txt,log"-silent-whatifremove-itembyage-days90-path$cookies-silent-whatifremove-itembyage-days14-path$recent-silent-whatifremove-itembyage-days21-path$history-silent-whatifremove-itembyage-days14-path"$appdata\Microsoft\office\Recent"-silent-whatif
Windows profiles become larger over time - it’s an inescapable fact. This means that if you are using roaming profiles, logons (and logoff) will be longer and longer. It’s not just individual file sizes, but also the number of files stored in a profile that will make the synchronisation process slower.
However, there will still be folders that need to be roamed to maintain the experience that users expect when moving between devices (i.e. consistency). For those folders we can implement some maintenance to keep them at a manageable size - that is remove files that are not needed in a roaming profile (e.g. log files) or delete files older than a specific number of days.
Warning: there’s a reason that Windows doesn’t do this maintenance itself - only each application vendor will have an understanding of whether specific files are required or can be discarded (hence the roaming and local portions of AppData). However, as any experienced Windows admin knows - many vendors either don’t test for or don’t care about roaming scenarios, therefore I strongly recommend testing this approach before production deployment.
As a part of an upcoming version of this configuration, I’ve created a script that will execute at logoff, before the profile is saved back to the network, that will perform two actions:
Delete all files of a specific file type in a specified folder, including sub-folders
Delete all files older than X days in a specified folder, including sub-folders
So for example, you could use the script to delete all .log files below %APPDATA% or delete all Cookies older than 90 days.
The script is extremely simple on purpose and I recommend testing thoroughly before implementing - use at your own risk; however feedback is welcome.
' Profile clean up - remove unneeded or old files before logoff' --------------------------------------------------------------' Original scripts:' http://www.wisesoft.co.uk/scripts/vbscript_recursive_file_delete_by_extension.aspx' http://ss64.com/vb/syntax-profile.html' http://csi-windows.com/toolkit/csigetspecialfolder' Version 2.0; 27/12/2011Option Explicit
OnErrorResumeNext'Avoid file in use issuesDimstrExtensionsToDelete,strAppData,strUserProfile,objFSO,strCookies,strHistory,strRecent,objShellAppSetobjFSO=CreateObject("Scripting.FileSystemObject")SetobjShellApp=CreateObject("Shell.Application")ConstCSIDL_COOKIES="&H21"ConstCSIDL_HISTORY="&H22"ConstCSIDL_RECENT="&H08"ConstCSIDL_NETHOOD="&H13"ConstCSIDL_APPDATA="&H1A"ConstCSIDL_PROFILE="&H28"' Folder to delete files from (files will also be deleted from Subfolders)strUserProfile=objShellApp.NameSpace(cint(CSIDL_PROFILE)).Self.PathstrAppData=objShellApp.NameSpace(cint(CSIDL_APPDATA)).Self.PathstrCookies=objShellApp.NameSpace(cint(CSIDL_COOKIES)).Self.PathstrHistory=objShellApp.NameSpace(cint(CSIDL_HISTORY)).Self.PathstrRecent=objShellApp.NameSpace(cint(CSIDL_RECENT)).Self.PathstrNetHood=objShellApp.NameSpace(cint(CSIDL_NETHOOD)).Self.Path' MainRecursiveDeleteByExtensionstrAppData,"tmp,log"RecursiveDeleteOlder90,strCookiesRecursiveDeleteOlder14,strRecentRecursiveDeleteOlder21,strHistoryRecursiveDeleteOlder21,strNetHoodRecursiveDeleteOlder14,strAppData&"\Microsoft\Office\Recent"'RecursiveDeleteOlder 5, strAppData & "\Sun\Java\Deployment\cache"'RecursiveDeleteOlder 3, strAppData & "\Macromedia\Flash Player"'RecursiveDeleteOlder 14, strUserProfile & "\Oracle Jar Cache"SubRecursiveDeleteByExtension(ByValstrPath,strExtensionsToDelete)' Walk through strPath and sub-folders and delete files of type strExtensionsToDeleteDimobjFolder,objSubFolder,objFile,strExtIfobjFSO.FolderExists(strPath)=TrueThenSetobjFolder=objFSO.GetFolder(strPath)ForEachobjFileinobjFolder.FilesForeachstrExtinSplit(UCase(strExtensionsToDelete),",")IfRight(UCase(objFile.Path),Len(strExt)+1)="."&strExtthenWScript.Echo"Deleting: "&objFile.PathobjFile.Delete(True)ExitForEndIfNextNextForEachobjSubFolderinobjFolder.SubFoldersRecursiveDeleteByExtensionobjSubFolder.Path,strExtensionsToDeleteNextEndIfEndSubSubRecursiveDeleteOlder(ByValintDays,strPath)' Delete files from strPath that are more than intDays oldDimobjFolder,objFile,objSubFolderIfobjFSO.FolderExists(strPath)=TrueThenSetobjFolder=objFSO.GetFolder(strPath)ForeachobjFileinobjFolder.filesIfDateDiff("d",objFile.DateLastModified,Now)>intDaysThenIfUCase(objFile.Name)<>"DESKTOP.INI"Then' Ensure we don't delete desktop.iniWScript.Echo"Deleting: "&objFile.PathobjFile.Delete(True)EndIfEndIfNextForEachobjSubFolderinobjFolder.SubFoldersRecursiveDeleteOlderintDays,objSubFolder.PathNextEndIfEndSub
Adobe released a new security advisory for Reader and Acrobat 9 and X this week to address details of an upcoming fix to these versions for a 0 day vulnerability. Exploits for this vulnerability exist for Reader and Acrobat 9 and are currently active:
Because Office is a core application of most desktop deployments, user interaction with Office and the user experience are important factors in the deployment of Office. From an administration perspective, providing a seamless user experience requires managing the user preferences of an application, independent of the application delivery method.
Mozilla has just released Firefox 8, so it’s time to look at virtualizing the new version. It’s a simple task to virtualize Firefox, as it lends itself well to application virtualization; however getting it right takes a little more effort. Here’s how to successfully sequence Mozilla Firefox 8.x.
In the official Microsoft TechNet forums, a question had been asked about sequencing Google Chrome and the poster states that when using the Chrome Enterprise Installer (a downloadable MSI for deployment inside an organisation), Chrome installs OK during the monitoring phase, but the folder is deleted at the end of monitoring and thus isn’t captured.