Загрузка данных


# Универсальная очистка кэша Firefox для всех профилей всех пользователей.
# Сопоставление по SID, а не по имени папки.

Start-Sleep -Seconds 5   # даём процессам Firefox дозавершиться

$mutex = New-Object System.Threading.Mutex($false, 'Global\FFCacheClean')
if (-not $mutex.WaitOne(60000)) { exit 0 }

try {
    # SID пользователей, у которых Firefox ещё запущен
    $activeSids = @{}
    Get-CimInstance Win32_Process -Filter "Name='firefox.exe'" -ErrorAction SilentlyContinue |
        ForEach-Object {
            $r = Invoke-CimMethod -InputObject $_ -MethodName GetOwnerSid -ErrorAction SilentlyContinue
            if ($r -and $r.Sid) { $activeSids[$r.Sid] = $true }
        }

    $cacheNames = @('cache2','startupCache','jumpListCache','thumbnails','OfflineCache')

    function Clear-ProfileDir([string]$dir) {
        if (-not (Test-Path -LiteralPath $dir)) { return }
        foreach ($n in $cacheNames) {
            $t = Join-Path $dir $n
            if (Test-Path -LiteralPath $t) {
                Write-Verbose "Удаляю $t"
                Remove-Item -LiteralPath $t -Recurse -Force -ErrorAction SilentlyContinue
            }
        }
    }

    $profiles = Get-CimInstance Win32_UserProfile |
        Where-Object { -not $_.Special -and $_.LocalPath -and (Test-Path -LiteralPath $_.LocalPath) }

    foreach ($up in $profiles) {
        if ($activeSids.ContainsKey($up.SID)) { continue }

        $userHome  = $up.LocalPath
        $localFF   = Join-Path $userHome 'AppData\Local\Mozilla\Firefox'
        $roamingFF = Join-Path $userHome 'AppData\Roaming\Mozilla\Firefox'

        # Стандартные расположения
        foreach ($root in @((Join-Path $localFF 'Profiles'), (Join-Path $roamingFF 'Profiles'))) {
            if (Test-Path -LiteralPath $root) {
                Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |
                    ForEach-Object { Clear-ProfileDir $_.FullName }
            }
        }

        # Нестандартные профили из profiles.ini
        $ini = Join-Path $roamingFF 'profiles.ini'
        if (Test-Path -LiteralPath $ini) {
            $isRel = $true
            Get-Content -LiteralPath $ini -ErrorAction SilentlyContinue | ForEach-Object {
                if ($_ -match '^\[.+\]') { $isRel = $true }
                elseif ($_ -match '^IsRelative=(\d)') { $isRel = ($Matches[1] -eq '1') }
                elseif ($_ -match '^Path=(.+)$') {
                    $p = $Matches[1].Trim() -replace '/', '\'
                    if ($isRel) {
                        Clear-ProfileDir (Join-Path $localFF $p)
                        Clear-ProfileDir (Join-Path $roamingFF $p)
                    } else {
                        Clear-ProfileDir $p
                    }
                }
            }
        }
    }
}
finally {
    $mutex.ReleaseMutex()
}