¿Cómo administrar identificadores de archivos abiertos con PowerShell?

Uno de los errores más frustrantes con los que puede lidiar un usuario final o un administrador de TI es el de los archivos bloqueados dentro de Windows.

Cuando eliminas una carpeta, mueves un archivo o editas una configuración y encuentras un mensaje de error de archivo bloqueado, es mejor lidiar con eso de manera rápida y eficiente.

Microsoft introdujo PowerShell como shell de reemplazo, pero tiene muchas más funciones que eso y es un lenguaje complejo y capaz. Veamos en este artículo cómo puede utilizar PowerShell para tratar con archivos bloqueados.

El problema del archivo bloqueado

¿Cómo se bloquea exactamente un archivo? Durante el uso normal, un proceso crea muchos identificadores de recursos.

Al hacerlo, los procesos a menudo bloquean el archivo para evitar que se produzcan cambios de configuración no deseados u otros daños.

El problema a menudo es que es difícil determinar qué proceso ha bloqueado el archivo y posteriormente, cómo eliminar ese bloqueo del archivo.

Desafortunadamente, no existe un cmdlet incorporado para probar un archivo y saber si está bloqueado o por qué proceso.

Por lo tanto, debes crear tus propias funciones o empaquetar otras herramientas útiles que existen para ayudarte a obtener más información sobre estos archivos.

Prueba de archivos bloqueados

Dentro de Windows, puedes probar para ver si un archivo individual está bloqueado. Usando el siguiente bloque de código, puedes probar para ver si un archivo determinado está bloqueado.

La variable $Item debe establecerse en una ruta de archivo completa.

Al probar, para ver si el archivo se puede abrir para escribir, como se ve con el comando [System.IO.File]::Open($Item,'Open','Write') puedes saber si el archivo está bloqueado.

If ([System.IO.File]::Exists($Item)) {
  Try {
      $FileStream = [System.IO.File]::Open($Item,'Open','Write')

      $FileStream.Close()
      $FileStream.Dispose()

      $IsLocked = $False
  } Catch [System.UnauthorizedAccessException] {
      $IsLocked = 'AccessDenied'
  } Catch {
      $IsLocked = $True
  }
}

Obtener SMBOpenFile

Dije que Windows no tiene una función integrada, pero si que existe un caso en el que hay una función.

Si tienes un recurso compartido remoto o incluso recursos compartidos administrativos (como c$), puedes usar el cmdlet Get-SMBOpenFile para informar sobre esos archivos abiertos.

PS C:> Get-SMBOpenFile

FileId       SessionId    Path  ShareRelativePath
------       ---------    ----  -----------------
154618822665 154618822657 C:

PS C:> 

La desventaja es que esto solo funciona para archivos a los que se accede de forma remota.

Cualquier archivo bloqueado que esté en uso en tu sistema local no se informará, por lo que en la mayoría de los casos, esta no es una solución viable.

Para cerrar, puedes canalizar los archivos abiertos devueltos al comando Close-SMBOpenFile.

Get-SMBOpenFile | Close-SMBOpenFile

Utilidad OpenFiles

Windows tiene una utilidad incorporada llamada openfiles que puede servir de ayuda a enumerar qué archivos están en uso y desconectarlos.

¡A primera vista, parece perfecto para tus necesidades! Incluso puedes envolver esto dentro de una función de PowerShell para facilitar la consulta y la desconexión de archivos.

Abre un indicador de PowerShell administrativo y ejecuta el comando openfiles /query. Inmediatamente, deberías recibir un mensaje de error que indica que el indicador global “maintain objects list” debe estar activado.

PS C:/> openfiles /query

INFO: The system global flag 'maintain objects list' needs
      to be enabled to see local opened files.
      See Openfiles /? for more information.


Files opened remotely via local share points:
---------------------------------------------

INFO: No shared open files found.

Esta lista de objetos es lo que realmente mantiene la lista de identificadores que están en uso y openfiles permite consultar esa información.

Para activarlo, ingresa openfiles /local on y luego reinicia la computadora. La desventaja de activar esta función es que hay un ligero impacto en el rendimiento, dependiendo de tu sistema, puede que no valga la pena usar esta herramienta.

Dicho esto, veamos cómo podemos hacer que esto funcione dentro de PowerShell.

PS C:> openfiles /Query /fo csv /nh

Files opened remotely via local share points:
---------------------------------------------
"ID","Accessed By","Type","Open File (Pathexecutable)"
"608","user","Windows","C:"

PS C:> openfiles /Query /fo csv | Select-Object -Skip 4 | ConvertFrom-CSV

ID  Accessed By  Type    Open File (Pathexecutable)
--  -----------  ----    ---------------------------
608 user         Windows C:

PS C:> openfiles /disconnect /id 608

SUCCESS: The connection to the open file "C:" has been terminated.

Con los ejemplos anteriores puede ver cómo importar la salida CSV openfiles a PowerShell. Con esa información, puedes crear un archivo disconnect para desbloquearlo.

Debido al impacto en el rendimiento en el que puede incurrir al habilitar la capacidad maintain objects list es posible que no valga la pena para tus necesidades.

Por eso, es posible que se necesites otras soluciones.

La aplicación Handle

Sysinternals es conocido por las muchas herramientas de TI útiles y casi esenciales que fabrica. Hace algún tiempo, Microsoft adquirió Sysinternals y puedes descargarlo y usar esas herramientas bien compatibles por tu propia cuenta.

¡Hay una aplicación llamada handles que proporciona exactamente lo que estás buscando!

Primero, debes descargar la aplicación, descomprimir los archivos y colocar los ejecutables en una ubicación que hayas incluido la variable ambiental Path. Al hacerlo, puedes hacer referencia fácilmente a la aplicación donde la necesites.

Usando una consulta simple para archivos abiertos, puedes ver que se obtienen muchos resultados (truncados para facilitar la lectura).

PS C:/> handle64 -NoBanner
...
------------------------------------------------------------------------------
RuntimeBroker.exe pid: 9860 User
   48: File          C:WindowsSystem32
  188: Section       BaseNamedObjects__ComCatalogCache__
  1EC: Section       BaseNamedObjects__ComCatalogCache__
------------------------------------------------------------------------------
chrome.exe pid: 4628 User
   78: File          C:Program Files (x86)GoogleChromeApplication78.0.3904.108
  1C4: Section       Sessions1BaseNamedObjectswindows_shell_global_counters
...

Parece que se obtiene lo que deseas, al menos parece una forma de averiguar qué archivos se están utilizando y puede probarlos utilizando el código de archivo bloqueado de antes.

Pero, ¿Cómo hacer que esto sea más fácil de usar?

El siguiente código se encarga de leer cada proceso y recuperar solo los archivos bloqueados. La desventaja es que esto toma un tiempo para ejecutarse ya que hay existen muchos procesos.

$Processes = Get-Process

$results = $Processes | Foreach-Object {
    $handles = (handle64 -p $_.ID -NoBanner) | Where-Object { $_ -Match " File " } | Foreach-Object {
            [PSCustomObject]@{
        "Hex"  = ((($_ -Split " ").Where({ $_ -NE "" })[0]).Split(":")[0]).Trim()
        "File" = (($_ -Split " ")[-1]).Trim()
        }
    }

    If ( $handles ) {
        [PSCustomObject]@{
            "Name"    = $_.Name
            "PID"     = $_.ID
            "Handles" = $handles
        }
    }
}

Sin embargo, en última instancia, lo que obtienes es una colección procesable de archivos, enumerados por proceso que sabe que están en uso y pueden filtrarse aún más.

Si descubres que necesitas cerrar uno de ellos, puedes hacer lo siguiente (como administrador):

PS C:> $results |
>>  Where-Object Name -EQ 'Notepad' |
>>  Where-Object { $_.Handles.File -Match "test.txt" }

Name                      PID Handles
----                      --- -------
Notepad                   12028 {@{Hex=44; File=C:test.txt}


PS C:> handle64 -p 12028 -c 44 -y -nobanner

44: File  (R-D)   C:test.txt

Handle closed.

Puedes envolver todo esto en una función para que sea aún más fácil de analizar y buscar según te sea necesario.

Existen muchas posibilidades, especialmente en la combinación de varios métodos dentro de una solución que se adapte a tu entorno.

Conclusión final

Tratar con archivos bloqueados puede ser un desafío, especialmente cuando detiene lo que necesitas hacer rápidamente.

Existen varias formas de encontrar y desbloquear esos archivos, pero requiere un poco de trabajo ya que Windows no tiene un método incorporado realmente completo para tratar con esos archivos bloqueados.

¡Las soluciones descritas deberían resolver rápidamente cualquier problema y permitirte pasar a tareas mucho más importantes!

Relacionado

Mejores Libros PDF de Programación y Tecnología GRATIS

Los Mejores Libros PDF Gratuitos de Informática. EL sitio perfecto para aprender a programar desde cero para principiantes con las mejores guías gratis. Esta es la mejor lista de libros de programación en PDF en español del mundo. Una completa biblioteca recopilada de cientos y cientos de libros en PDF que no encontrarás en ninguna parte más. Aquí, vas a encontrar libros enfocados hacía programadores. Sobre ¡SEGUIR LEYENDO!

Más de 1.500 Libros PDF en Inglés de Desarrollo Web, Programación, Seguridad, Robótica, Blockchain, Domótica y Mucho Más

La mejor lista de libros sobre lenguajes de programación en inglés de todo Internet. https://ciberninjas.com/zlibrary/ Libros de Python / Libros PHP / Libros Java / Libros Diseño Meta Listas atariarchives.org atariarchives.org pone a disposición en la Web libros, información y software para Atari y otras computadoras clásicas. Bento Bitsavers.org Bookboon: se requiere cookie de TI y programación</. (requiere @email) DZone - Hojas de trucos (gratis) Conceptf1.blogspot.com ¡SEGUIR LEYENDO!

10 Comandos Básicos de PowerShell

PowerShell no necesita presentación: es el marco de gestión de configuración y automatización de tareas elegido para el entorno de Windows. Combina la flexibilidad de un poderoso lenguaje de secuencias de comandos con el poder y la velocidad de la línea de comandos para ayudar a los administradores de TI a orquestar, automatizar y solucionar problemas de funciones de TI comunes. Por eso, los comandos de ¡SEGUIR LEYENDO!

48 Mejores Cursos Gratis de Servicios en la Nube y Servidores

Recopilatorio de cursos enfocados en aprender a manejar servicios o crear servicios dentro de un servidor online o en la nube.

22 Mejores Cursos Gratis de Software Técnico

Recopilatorio de cursos para aprender técnicas de reparación y mantenimiento de software y hardware o estudios de técnico informático.

¿Cómo encontrar software instalado en sistemas Windows remotos con PowerShell?

Si eres un administrador de TI, es muy probable que hayas tenido que instalar software para otros. La administración de puntos finales es un gran negocio en estos días y el mantenimiento del software en cientos o miles de computadoras es común en las grandes organizaciones. ¿Qué pasa si estás en una organización con poco o ningún presupuesto? ¿Tal vez usted o alguien de tu equipo ¡SEGUIR LEYENDO!

¿Cómo implementar paquetes de servicios de SQL Server de forma gratuita con PowerShell?

Como cualquier otra pieza de software, Microsoft SQL Server debe mantenerse actualizado. Microsoft lanza periódicamente paquetes de servicio para SQL Server que deben instalarse. Para instalar un paquete de servicio, puedes conectarte a una consola remota de SQL Server, ejecutar el instalador y hacer clic en el asistente o puede hacerlo de manera sencilla. Cada instalador de Service Pack para SQL Server admite instalaciones silenciosas. Este ¡SEGUIR LEYENDO!

Deja un comentario

Salir de la versión móvil