Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #requires -version 2
- <#
- Written by David Ott
- Read and understand everything - key items are marked with ##### (5 hash tags) - these are items you have to edit, or just things to pay
- attention to. Do not use this script in production until it has been tested!
- I wrote this script to clean up Citrix Profile Management Stores. The script will clean up old items in domstore/recent, remove oice_15*
- junk folders from appdata, and remove exclusions from the profile (based on a .csv file)
- It requres powershell v2 or above, an account with at least modify
- rights to the profile store (so it can delete things), and a .csv file with exclusions/sync directories/folders ($excludes variable)
- CSV format:
- The first row = headers = do not change these
- $Recycle.Bin, below is an example of an excluded folder with nothing to sync below it
- AppData\Roaming\Microsoft\Excel,"XLSTART,Excel*.xlb" below is an example of a directory which is excluded but items under it are synced
- It gets a little tricky when you have an excluded folder such as
- Appdata\LocalLow
- but have directories\files multiple levels down that need to sync like
- Appdata\LocalLow\Google\GoogleEarth\*.kml
- Appdata\LocalLow\Sun\Java\Deployment\ext
- Appdata\LocalLow\Sun\Java\Deployment\security
- Appdata\LocalLow\Sun\Java\Deployment\deployment.properties
- you have to break it up like below
- ### example below ###
- Folder,Exclude
- $Recycle.Bin,
- AppData\Roaming\Microsoft\Excel,"XLSTART,Excel*.xlb"
- AppData\LocalLow,"Google,Sun"
- AppData\LocalLow\Google,GoogleEarth
- AppData\LocalLow\Google\GoogleEarth,*.kml
- AppData\LocalLow\Sun,Java
- AppData\LocalLow\Sun\Java,Deployment
- AppData\LocalLow\Sun\Java\Deployment,"ext,security,deployment.properties"
- Last thing - this script will run silent unless something throws an error for some reason
- if you want to see the deletions happen look for #-verbose throughout the script and delete the #
- #>
- <##### define what you concider to be old files in domstore and recent #####>
- <##### ie: if you want it to be anything older than 3 months - change the -1 to -3 #####>
- $old = [datetime]::Today.AddMonths(-1)
- <#### This is the .csv file you created that holds your excluded/synchronized dirs/files #####>
- $excludes = Import-Csv C:\Excludes.csv
- <##### change "\\server\share" to the root of your profile store #####>
- $profiles = (gci \\server\share | ?{$_.psiscontainer -eq $true}).FullName | sort
- <##### adjust this path portion to match your environment - in my environment under each profile there is a folder
- v2x64 and then under that is where UPM_Profile resides. If in your environment it is any different set that path in the
- variable below - ie: if your path under each profile is just UPM_Profile - adjust $profpath to equal "UPM_Profile" - just
- make sure there is no leading or trailing "\" #####>
- $profpath = "v2x64\UPM_Profile"
- ##### here is where the magic starts to happen
- foreach ($profile in $profiles) {
- ##### sets profile root - ie: \\server\share\user\UPM_Profile
- $profroot = Join-Path $profile $profpath
- ##### sets the domstore path
- $domstore = Join-Path $profroot "\AppData\Local\Microsoft\Internet Explorer\DOMStore"
- ##### sets the recent path
- $recent = Join-Path $profroot "AppData\Roaming\Microsoft\Windows\Recent"
- ##### sets the appdata path
- $appd = Join-Path $profroot "AppData"
- <##### looks in appdata (if it exists) for any oice_15* folders (you may need to adjust this depending on the version of office) and then for each
- one it removes the directory #####>
- if (Test-Path $appd) {
- gci $appd | ?{($_.psiscontainer -eq $true) -and ($_.name -like "oice_15*")} | select -expand fullname | %{
- ri $_ -Recurse -Force #-Verbose
- }
- }
- <##### this part cleans domstore of files that are older than the $old variable set at the beginning of this script #####>
- if (Test-Path $domstore) {
- <##### if the domstore directory exists - gets a list of all files (not folders) which were last written before $old excluding
- container.dat #####>
- $files = gci $domstore -Recurse -Force | ?{$_.psiscontainer -eq $false -and $_.LastWriteTime -le $old -and $_.Name -ne "container.dat"}
- <##### if there are files older than $old - delete them #####>
- if (($files | Measure-Object).count -gt "0") {
- $files | ri -Force #-Verbose
- }
- <##### if there are folders under domstore - checks to see if any of them are empty - if so deletes the empty folders #####>
- if ((gci $domstore -Force | ?{$_.psiscontainer -eq $true} | Measure-Object).count -ge "1"){
- (gci $domstore -Force | ?{$_.psiscontainer -eq $true}).FullName | %{
- if ((gci $_ -Recurse -Force | ?{$_.psiscontainer -eq $false} | Measure-Object).count -eq "0") {
- ri $_ -Recurse -Force #-Verbose
- }
- }
- }
- }
- <##### cleans out recent of old shortcuts (older than $old) if the recent folder exists #####>
- if (Test-Path $recent) {
- <##### tries to get a list of all .lnk files older than $old - if it cannot (path too long) it will map a drive (Y:\) in order to shorten
- the path - if Y: is used on your system select a different drive letter - ctrl+h and replace any Y" with your drive letter followed by ":"
- as this script will map a drive as needed in a couple places
- ie: X: #####>
- try {
- $rfiles = gci $recent -Force -ErrorAction stop | ?{$_.psiscontainer -eq $false -and $_.LastWriteTime -le $old -and $_.Name -like "*.lnk"}
- } catch {
- <##### if the above command fails - maps a drive to shorten the path and gets a list of .lnk files #####>
- & net use Y: $recent
- Start-Sleep -Milliseconds 500
- $rfiles = gci Y:\ -Force | ?{$_.psiscontainer -eq $false -and $_.LastWriteTime -le $old -and $_.Name -like "*.lnk"}
- }
- <##### if any files are found older than $old - deletes them #####>
- if (($rfiles | Measure-Object).count -gt "0") {
- $rfiles | ri -Force #-Verbose
- }
- <##### If the drive was mapped - unmaps the drive #####>
- if (Test-Path "Y:\") {
- & net use Y: /d /y
- }
- }
- <##### processes excluded folders from the .csv file #####>
- foreach ($exclude in $excludes) {
- <##### adds the excluded folder path to the profile path #####>
- $folder = join-path $profroot $exclude.Folder
- <##### checks to see if there are any exclusions to the excluded folder (sync directories/files - yeah I should have named it better)
- if there are it sets them as the $exclusions variable #####>
- if ($exclude.Exclude.Length -gt "0") {
- $exclusions = $exclude.Exclude -split ","
- } else {
- $exclusions = $null
- }
- <##### If the excluded folder exists and there are items under it that should sync #####>
- if ((Test-Path $folder) -and ($exclusions -ne $null)) {
- <##### tries to get items under the folder - excluding sync items - and remove them #####>
- try {
- gci $folder -Force -Exclude $exclusions -ErrorAction Stop | ri -Recurse -Force -ErrorAction Stop #-Verbose
- } catch {
- <##### if the path is too long map a drive to shorten the path - get everything other than sync items and delete them - when done
- remove the network drive #####>
- & net use Y: (split-path $folder -Parent)
- gci (join-path "Y:\" (Split-Path $folder -Leaf)) -Force -Exclude $exclusions | ri -Recurse -Force #-Verbose
- & net use Y: /d /y
- }
- <##### else if there is an excluded folder and there are no items to worry about syncing below #####>
- } elseif (Test-Path $folder) {
- <##### tries to remove the folder and everything below it #####>
- try {
- ri $folder -Recurse -Force -ErrorAction Stop #-Verbose
- } catch {
- <##### if that fails - map a drive - then remove everything - and delete the network drive #####>
- & net use Y: (Split-Path $folder -parent)
- ri (Join-Path "Y:\" (Split-Path $folder -Leaf)) -Recurse -Force
- & net use Y: /d /y
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement