elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  [APORTE] [PowerShell] Desactivar directivas de caché de escritura en todos los discos conectados.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [APORTE] [PowerShell] Desactivar directivas de caché de escritura en todos los discos conectados.  (Leído 4,979 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 10.018



Ver Perfil
[APORTE] [PowerShell] Desactivar directivas de caché de escritura en todos los discos conectados.
« en: 17 Mayo 2026, 15:41 pm »

El siguiente script, desarrollado en PowerShell, sirve para desactivar las directivas de caché de escritura en todos los discos físicos actualmente conectados, para evitar que cada disco tenga una configuración distinta y asegurarse de que el comportamiento de escritura en disco sea coherente y seguro en todo el sistema, evitando riesgo de pérdida de datos o fallo del disco por un corte de luz. Y sí, uso la palabra evitar, y lo hago en modo afirmativo, ya que en más de 15 años con la caché desactivada y muchos cortes de luz (y un apagón en España) no he sufrido pérdida de datos ni fallos en ninguno de mis discos ni una sola vez. Antes de adquirir el hábito de desactivar la caché, sí tuve muchos problemas con cada corte de luz, pero después de adquirir el hábito, ni uno solo. Por ese motivo recomiendo encarecidamente mantener siempre desactivada la caché de escritura en todos los discos. El disco irá más lento, pero eso que pierdes lo ganas multiplicado en seguridad.



La primera casilla de arriba viene activada por defecto en Windows cuando se detecta un nuevo disco conectado.



El script se ha desarrollado mediante vibe coding con inteligencia artificial, y un poco de edición manual en el código resultante. Lo hice para un amigo y lo comparto tal cual.



Código
  1. #Requires -RunAsAdministrator
  2.  
  3. Set-StrictMode -Version Latest
  4. $ErrorActionPreference = "Stop"
  5.  
  6. #  Disable both write-cache options on ALL connected disk drives
  7. #  Option 1: Turn off write caching on the device  > UserWriteCacheSetting = 0
  8. #  Option 2: Turn off Windows write-cache flushing > CacheIsPowerProtected  = 0
  9.  
  10. [int] $successCount = 0
  11. [int] $failCount    = 0
  12.  
  13. Write-Host ""
  14. Write-Host "============================================================" -ForegroundColor Cyan
  15. Write-Host "  Disable Write-Cache Options - All Physical Disks" -ForegroundColor Cyan
  16. Write-Host "============================================================" -ForegroundColor Cyan
  17. Write-Host ""
  18.  
  19. [System.Object[]] $diskDevices = @(
  20.    Get-PnpDevice -Class DiskDrive -Status OK -ErrorAction SilentlyContinue
  21. )
  22.  
  23. if ($diskDevices.Count -eq 0) {
  24.    Write-Warning "No disk drives found with status OK."
  25.    Write-Host "Press any key to exit..."
  26.    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
  27.    exit 1
  28. }
  29.  
  30. [System.Collections.Hashtable] $driveLetterMap = @{}
  31. [System.Collections.Hashtable] $diskSizeMap = @{}
  32. [System.Collections.Hashtable] $diskLabelMap = @{}
  33.  
  34. function Format-DiskSize {
  35.    param([uint64] $sizeBytes)
  36.    if ($sizeBytes -ge 1TB) { return "$([math]::Round($sizeBytes / 1TB, 2)) TB" }
  37.    elseif ($sizeBytes -ge 1GB) { return "$([math]::Round($sizeBytes / 1GB, 2)) GB" }
  38.    else { return "$([math]::Round($sizeBytes / 1MB, 2)) MB" }
  39. }
  40.  
  41. Get-CimInstance -ClassName Win32_LogicalDisk -ErrorAction SilentlyContinue | ForEach-Object {
  42.    [string] $letter    = $_.DeviceID
  43.    [object] $diskDrive = $_ |
  44.                          Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -ErrorAction SilentlyContinue |
  45.                          Get-CimAssociatedInstance -ResultClassName Win32_DiskDrive     -ErrorAction SilentlyContinue |
  46.                          Select-Object -First 1
  47.    if ($null -ne $diskDrive) {
  48.        [string] $pnpId = $diskDrive.PNPDeviceID.ToUpper()
  49.        if (-not $driveLetterMap.ContainsKey($pnpId)) {
  50.            $driveLetterMap[$pnpId] = $letter
  51.        }
  52.  
  53.        if (-not $diskSizeMap.ContainsKey($pnpId)) {
  54.            $diskSizeMap[$pnpId] = [uint64]$diskDrive.Size
  55.        }        
  56.        if (-not $diskLabelMap.ContainsKey($pnpId)) {
  57.            $diskLabelMap[$pnpId] = [string]$_.VolumeName
  58.        }
  59.    }
  60. }
  61.  
  62. # Sort disk devices by their first drive letter; disks without letter go last
  63. [System.Object[]] $sortedDevices = @(
  64.    $diskDevices | Sort-Object -Property {
  65.        [string] $key = $_.InstanceId.ToUpper()
  66.        if ($driveLetterMap.ContainsKey($key)) { $driveLetterMap[$key] } else { 'ZZ:' }
  67.    }
  68. )
  69.  
  70. Write-Host "Found $($sortedDevices.Count) disk(s). Processing...`n" -ForegroundColor Yellow
  71.  
  72. foreach ($device in $sortedDevices) {
  73.  
  74.    [string] $friendlyName = $device.FriendlyName
  75.    [string] $instanceId   = $device.InstanceId
  76.    [string] $driveLetter = $driveLetterMap[$instanceId.ToUpper()]
  77.    [string] $diskSize    = Format-DiskSize -sizeBytes $diskSizeMap[$instanceId.ToUpper()]
  78.    [string] $diskLabel   = $diskLabelMap[$instanceId.ToUpper()]
  79.    [string] $regPath      = "HKLM:\SYSTEM\CurrentControlSet\Enum\$instanceId\Device Parameters\Disk"
  80.  
  81.    Write-Host "-----------------------------------------------------" -ForegroundColor DarkGray
  82.    Write-Host "  Disk : [$driveLetter] $diskLabel - $friendlyName ($diskSize)" -ForegroundColor White
  83.    Write-Host "  ID   : $instanceId"  -ForegroundColor DarkGray
  84.    if (-not (Test-Path -Path $regPath)) {
  85.        Write-Warning "  Registry path not found - skipping: $regPath"
  86.        $failCount++
  87.        continue
  88.    }
  89.  
  90.    # Option 1: Disable write caching
  91.    #    UserWriteCacheSetting:
  92.    #      0 = System default  |  1 = Force ENABLE  |  2 = Force DISABLE
  93.    try {
  94.        Set-ItemProperty -Path $regPath `
  95.                         -Name  "UserWriteCacheSetting" `
  96.                         -Value 0 `
  97.                         -Type  DWord `
  98.                         -Force
  99.        Write-Host "  [OK] Enable write caching DISABLED (UserWriteCacheSetting = 0)" -ForegroundColor Green
  100.    } catch {
  101.        Write-Warning "  [FAIL] UserWriteCacheSetting - $_"
  102.        $failCount++
  103.    }
  104.  
  105.    # Option 2: Re-enable buffer flushing (uncheck "turn off flushing")
  106.    #    CacheIsPowerProtected:
  107.    #      0 = Flushing ENABLED (checkbox unchecked - safe mode)
  108.    #      1 = Flushing DISABLED (checkbox checked - risky, power-loss danger)
  109.    try {
  110.        Set-ItemProperty -Path $regPath `
  111.                         -Name  "CacheIsPowerProtected" `
  112.                         -Value 0 `
  113.                         -Type  DWord `
  114.                         -Force
  115.        Write-Host "  [OK] Turn off write-cache buffer flushing DISABLED (CacheIsPowerProtected = 0)" -ForegroundColor Green
  116.        $successCount++
  117.    } catch {
  118.        Write-Warning "  [FAIL] CacheIsPowerProtected - $_"
  119.        $failCount++
  120.    }
  121. }
  122.  
  123. #  Summary
  124. Write-Host ""
  125. Write-Host "============================================================" -ForegroundColor Cyan
  126. Write-Host "  Summary" -ForegroundColor Cyan
  127. Write-Host "============================================================" -ForegroundColor Cyan
  128. Write-Host "  Disks processed successfully : $successCount" -ForegroundColor Green
  129. if ($failCount -gt 0) {
  130.    Write-Host "  Disks with errors            : $failCount" -ForegroundColor Red
  131. }
  132. Write-Host ""
  133. Write-Host "  NOTE: A system RESTART is required for changes" -ForegroundColor Yellow
  134. Write-Host "        to take effect on all devices." -ForegroundColor Yellow
  135. Write-Host ""
  136.  
  137. Write-Host "Press any key to exit..."
  138. $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")


« Última modificación: 17 Mayo 2026, 15:48 pm por Eleкtro » En línea



Danielㅤ


Desconectado Desconectado

Mensajes: 1.972


🔵🔵🔵🔵🔵🔵🔵


Ver Perfil
Re: [APORTE] [PowerShell] Desactivar directivas de caché de escritura en todos los discos conectados.
« Respuesta #1 en: 18 Mayo 2026, 02:00 am »

Hola compañero Elektro, interesante lo que has comentado y recomendado, y el script está bueno para realizar más fácil y rápida la configuración.

Importante: Luego de hacer la modificación que indica el compañero, hay que reiniciar la PC.


« Última modificación: 18 Mayo 2026, 02:03 am por Danielㅤ » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines