Come gestire gli handle di file aperti con PowerShell

Contenuti

Gente della linea di comando

Uno degli errori più frustranti che un utente finale o un amministratore IT può affrontare sono i file bloccati all'interno di Windows.. Quando elimini una cartella, sposti un file o modifichi un'impostazione e riscontri un messaggio di errore di file bloccato, affrontarlo meglio in modo rapido ed efficiente.

Microsoft ha introdotto PowerShell come shell sostitutiva, ma ha molte più funzionalità di così ed è un linguaggio complesso e capace. Vediamo in questo post come puoi usare PowerShell per gestire i file bloccati.

Il problema dei file bloccati

Come si blocca esattamente un file?? Durante il normale utilizzo, una procedura crea molti identificatori di risorse come un unico file. Così facendo, i processi spesso bloccano il file per prevenire modifiche alla configurazione indesiderate o altri danneggiamenti. Il problema è spesso che è difficile determinare quale procedura ha bloccato il file e, successivamente, come cancellare quel blocco file.

Sfortunatamente, non esiste un cmdlet integrato per testare un file e scoprire se è bloccato o con quale procedura. Perché, devi creare le tue funzioni o impacchettare altri strumenti utili là fuori per aiutarti a saperne di più su questi file.

Test dei file bloccati

All'interno di Windows, puoi verificare se un singolo file è bloccato. Con il seguente blocco di codice, puoi verificare se un determinato file è bloccato. il $Item La variabile deve essere impostata su un percorso file completo. Durante il test per vedere se il file può essere aperto per la scrittura, come sta con lui [System.IO.File]::Open($Item,'Open','Write') comando, puoi sapere se il file è bloccato.

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
  }
}

Get-SMBOpenFile

Ho detto che Windows non ha una funzione integrata, ma c'è un caso in cui esiste una funzione. Se hai una condivisione remota o addirittura amministrativa (Che cosa c$), allora puoi usare il Get-SMBOpenFile cmdlet per segnalare quei file aperti.

PS C:> Get-SMBOpenFile

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

PS C:> 

Il rovescio della medaglia è che funziona solo per i file a cui si accede da remoto. Nessun file bloccato in uso sul tuo sistema locale verrà segnalato, quindi nella maggior parte dei casi questa non è una soluzione praticabile. Chiudere, puoi reindirizzare i file aperti restituiti al Close-SMBOpenFile comando.

Get-SMBOpenFile | Close-SMBOpenFile

Utilità OpenFiles

Windows ha un'utilità integrata chiamata openfiles che può aiutare a elencare quali file sono in uso e disconnetterli. A prima vista, sembra perfetto per le tue esigenze! Puoi anche racchiuderlo all'interno di una funzione PowerShell per semplificare il controllo e la disconnessione dei file..

Apri un prompt amministrativo di PowerShell ed esegui il comando openfiles /query. Subito, dovresti ricevere un messaggio di errore che indica che il flag globale “dovresti ricevere un messaggio di errore che indica che il flag globale” dovresti ricevere un messaggio di errore che indica che il flag globale.

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.

Questo elenco di oggetti è ciò che mantiene veramente l'elenco degli identificatori che sono in uso e consente openfiles per consultare tali informazioni. Per attivare questo, entra openfiles /local on e quindi riavvia il computer. Lo svantaggio dell'attivazione di questa funzione è che c'è un leggero impatto sulle prestazioni, che a seconda del tuo sistema, questo strumento potrebbe non valere la pena di usarlo. Avendo detto questo, vediamo come possiamo farlo funzionare all'interno di 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 gli esempi sopra, puoi vedere come importare l'output CSV da openfiles e PowerShell. Con queste informazioni, Maggio disconnect un file da sbloccare. A causa dell'impatto sulle prestazioni che potresti incorrere quando abiliti il maintain objects list capacità, potrebbe non valerne la pena per le tue esigenze. È per questo, potrebbero essere necessarie altre soluzioni.

L'applicazione della maniglia

Sysinternals è noto per i numerosi strumenti IT utili e quasi essenziali che produce. A lungo, Microsoft ha acquisito Sysinternals e puoi scaricare e utilizzare tu stesso questi strumenti ben supportati. convenientemente, c'è un'applicazione chiamata handles che fornisce esattamente quello che stai cercando.

Primo, dovresti scarica l'applicazione, decomprimi i file e metti gli eseguibili in una posizione che ha incluso la tua variabile d'ambiente Path. Così facendo, puoi facilmente fare riferimento all'app dove ne hai bisogno. Con una semplice query per i file aperti, puoi vedere che ottieni molti risultati (troncato per una facile lettura).

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
...

Sembra che tu ottenga quello che vuoi, almeno un modo per scoprire quali file vengono utilizzati, e puoi testarli usando il tuo codice file bloccato da prima. Ma, Come lo rendi più facile da usare?? Il codice seguente legge ogni procedura e recupera solo i file bloccati. Il rovescio della medaglia è che richiede un po' di tempo per l'esecuzione poiché ci sono molti processi.

$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
        }
    }
}

Nonostante questo, come ultima opzione, quello che ottieni è una raccolta di file utilizzabili, elencati per procedura, che sai sono in uso e possono essere ulteriormente filtrati. Se trovi che devi chiuderne uno, puoi fare quanto segue (come amministratore):

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.

Puoi ulteriormente racchiudere tutto questo in un'unica funzione per rendere ancora più semplice l'analisi e la ricerca secondo necessità.. Ci sono molte alternative, soprattutto nel combinare diversi metodi in una soluzione che si adatta al tuo ambiente.

conclusione

Gestire file bloccati può essere difficile, soprattutto quando interrompi ciò che devi fare in fretta. Esistono diverse alternative per trovare e sbloccare questi file, ma ci vuole un po' di lavoro poiché Windows non ha un metodo integrato veramente completo per gestire quei file bloccati. Le soluzioni descritte dovrebbero mantenere il problema breve e consentirti di passare a compiti molto più importanti.

Iscriviti alla nostra Newsletter

Non ti invieremo posta SPAM. Lo odiamo quanto te.