# =====================================================================
# Chrome – Inventario completo de extensiones y copia de seguridad
# Perfila todos los usuarios de Windows y todos los canales de Chrome.
# Exporta: JSON + CSV de extensiones por perfil. Copia carpetas de
# extensiones y marcadores (Bookmarks/Bookmarks.bak) de cada perfil.
# =====================================================================
$ErrorActionPreference = 'SilentlyContinue'
# Carpeta de salida
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$BackupRoot = Join-Path $env:USERPROFILE "Desktop\Chrome_Backup_$timestamp"
New-Item -ItemType Directory -Path $BackupRoot -Force | Out-Null
# Raíces de perfiles de Windows (robusto: del Registro + usuario actual)
$profileRoots = @()
$profileRoots += (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' |
ForEach-Object { (Get-ItemProperty $_.PSPath).ProfileImagePath } |
Where-Object { $_ -and (Test-Path $_) } | Select-Object -Unique)
$profileRoots += (Split-Path $env:LOCALAPPDATA -Parent) # usuario que ejecuta
$profileRoots = $profileRoots | Sort-Object -Unique
# Canales de Chrome
$chromeProducts = @('Chrome','Chrome Beta','Chrome Dev','Chrome SxS')
# Auxiliar: aplanar coincidencias de content_scripts
function Get-CSMatches {
param([object]$Manifest)
$matches = @()
if ($Manifest.content_scripts) {
foreach ($cs in $Manifest.content_scripts) {
if ($cs.matches) { $matches += $cs.matches }
}
}
return ($matches -join ', ')
}
# Exporta un perfil concreto
function Export-ChromeProfile {
param(
[string]$UserDataPath, # ...\User Data
[string]$ProfileName, # Default | Profile 1 | ...
[string]$UserName, # nombre de carpeta de usuario Windows
[string]$Channel # Chrome | Chrome Beta | ...
)
$profilePath = Join-Path $UserDataPath $ProfileName
if (!(Test-Path $profilePath)) { return }
$safeTag = ($UserName + '_' + $Channel + '_' + $ProfileName) -replace '[^\w\-\.]','_'
$outDir = Join-Path $BackupRoot $safeTag
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
# ---- Inventario de extensiones (JSON + CSV) ----
$extDir = Join-Path $profilePath 'Extensions'
$extRows = @()
if (Test-Path $extDir) {
foreach ($ext in Get-ChildItem $extDir -Directory) {
$extId = $ext.Name
# última versión instalada (ordena por número de versión si es posible)
$ver = Get-ChildItem $ext.FullName -Directory |
Sort-Object { try { [version]$_.Name } catch { $_.Name } } -Descending |
Select-Object -First 1
if ($ver) {
$manifestPath = Join-Path $ver.FullName 'manifest.json'
$mf = $null
if (Test-Path $manifestPath) {
try { $mf = Get-Content $manifestPath -Raw | ConvertFrom-Json } catch {}
}
$extRows += [PSCustomObject]@{
WindowsUser = $UserName
ChromeChannel = $Channel
Profile = $ProfileName
ExtensionId = $extId
Name = if ($mf) { $mf.name } else { $null }
Description = if ($mf) { $mf.description } else { $null }
Version = if ($mf) { $mf.version } else { $ver.Name }
ManifestVersion = if ($mf) { $mf.manifest_version } else { $null }
Permissions = if ($mf -and $mf.permissions) { ($mf.permissions -join ', ') } else { $null }
HostPermissions = if ($mf -and $mf.host_permissions) { ($mf.host_permissions -join ', ') } else { $null }
ContentScriptsMatch = if ($mf) { Get-CSMatches -Manifest $mf } else { $null }
BackgroundType = if ($mf -and $mf.background) {
if ($mf.background.service_worker) { 'service_worker' }
elseif ($mf.background.scripts) { 'scripts' }
else { 'other' }
} else { $null }
HomepageURL = if ($mf) { $mf.homepage_url } else { $null }
UpdateURL = if ($mf) { $mf.update_url } else { $null }
Path = $ver.FullName
}
}
}
if ($extRows.Count -gt 0) {
$extRows | ConvertTo-Json -Depth 6 | Out-File (Join-Path $outDir 'Extensions.json') -Encoding UTF8
$extRows | Export-Csv (Join-Path $outDir 'Extensions.csv') -NoTypeInformation -Encoding UTF8
}
# Copia completa de las carpetas de extensiones
$destExt = Join-Path $outDir 'Extensions_Files'
New-Item -ItemType Directory -Path $destExt -Force | Out-Null
# Robocopy maneja rutas largas y bloqueos mejor que Copy-Item
$null = robocopy $extDir $destExt /E /R:0 /W:0 /NFL /NDL /NP /NJH /NJS
}
# ---- Marcadores ----
$bm = Join-Path $profilePath 'Bookmarks'
if (Test-Path $bm) { Copy-Item $bm (Join-Path $outDir 'Bookmarks.json') -Force }
$bmBak = Join-Path $profilePath 'Bookmarks.bak'
if (Test-Path $bmBak) { Copy-Item $bmBak (Join-Path $outDir 'Bookmarks.bak') -Force }
# Preferencias del perfil (útil para contexto de extensiones)
$prefs = Join-Path $profilePath 'Preferences'
if (Test-Path $prefs) { Copy-Item $prefs (Join-Path $outDir 'Preferences.json') -Force }
}
# Perfila todos los usuarios y canales
$processed = 0
foreach ($root in $profileRoots) {
$userName = Split-Path $root -Leaf
foreach ($product in $chromeProducts) {
$userData = Join-Path $root "AppData\Local\Google\$product\User Data"
if (Test-Path $userData) {
# Perfiles estándar
$profiles = Get-ChildItem $userData -Directory |
Where-Object { $_.Name -match '^(Default|Profile \d+|Guest Profile|System Profile)$' }
# Si no encuentra nada, intenta perfiles con patrón "Profile *" sin restricción
if (!$profiles -or $profiles.Count -eq 0) {
$profiles = Get-ChildItem $userData -Directory |
Where-Object { $_.Name -like 'Profile *' -or $_.Name -eq 'Default' }
}
foreach ($p in $profiles) {
Export-ChromeProfile -UserDataPath $userData -ProfileName $p.Name -UserName $userName -Channel $product
$processed++
}
}
}
}
# Si nada se procesó, deja evidencia explícita
if ($processed -eq 0) {
"No se encontraron perfiles de Chrome en los usuarios detectados:
$($profileRoots -join [Environment]::NewLine)" |
Out-File (Join-Path $BackupRoot 'SIN_RESULTADOS.txt') -Encoding UTF8
}
Write-Host "Listo. Carpeta: $BackupRoot"
Explicación paso a paso
- Cópia el código
- Abre PowerShell como administrador.
- Pulsa Botón derecho para pegar exactamente el bloque de código de arriba.
- Presiona Enter.
- El sistema mira dos zonas del registro: programas de 64 bits y de 32 bits.
- Toma solo el campo
DisplayName (el nombre visible del programa).
- Quita los vacíos, ordena alfabéticamente y deja un nombre por línea.
- Guarda el resultado en el Escritorio con el nombre
Programas_Instalados.txt.
- Abre ese archivo para ver la lista.
```