martedì 15 giugno 2021

Come gestire gli handle di file aperti con PowerShell

Julia Tim / Shutterstock Uno degli errori più frustranti che un utente finale o un amministratore IT può affrontare è quello del blocco file all’interno di Windows. Quando elimini una cartella, sposti un file o modifichi una configurazione e incontri un messaggio di errore relativo al file bloccato, è meglio gestirlo in modo rapido ed efficiente.

Microsoft ha introdotto PowerShell come shell sostitutiva, ma ha molte più funzionalità di quella ed è un linguaggio complesso e capace. Diamo un’occhiata in questo articolo su come utilizzare PowerShell per gestire i file bloccati.

The Locked File Problem Come funziona esattamente un file bloccarsi? Durante il normale utilizzo, un processo crea molti handle per le risorse come un file. In questo modo, i processi spesso bloccano il file per impedire modifiche involontarie alla configurazione o altri danneggiamenti. Il problema spesso è che è difficile determinare quale processo ha bloccato il file e, successivamente, come rimuovere quel blocco dal file.

Sfortunatamente, non esiste un cmdlet integrato per testare un file e stabilire se è bloccato o da quale processo. Pertanto, è necessario creare le proprie funzioni o includere altri strumenti utili esistenti per aiutare a scoprire di più su questi file.

Test per file bloccati In Windows, puoi verificare se un singolo file è bloccato. Utilizzando il seguente blocco di codice, puoi verificare se un determinato file è bloccato. La variabile $ Item necessita da impostare su un percorso file completo. Testando per vedere se il file può essere aperto per la scrittura, come visto con il :: Open ($ Item, ‘Open’, ‘Write’) , puoi sapere se il file è bloccato.

Se (:: Exists ($ Item)) {Try {$ FileStream = :: 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 incorporata, ma c’è un caso in cui esiste una funzione. Se si dispone di una condivisione remota o anche di condivisioni amministrative (come c $ ), quindi è possibile utilizzare Get-SMBOpenFile cmdlet per creare report su quei file aperti.

PS C: > Get-SMBOpenFile FileId SessionId Path ShareRelativePath – —– ——— —- —————– 154618822665 154618822657 C: PS C: > Lo svantaggio è che funziona solo per i file a cui si accede in remoto. Tutti i file bloccati in uso sul sistema locale non verranno segnalati, quindi per la maggior parte dei casi questa non è una soluzione praticabile. Per chiudere, puoi reindirizzare i file aperti restituiti al Close-SMBOpenFile comando.

Get-SMBOpenFile | Close-SMBOpenFile

Utilità OpenFiles Windows ha un’utilità incorporata denominata openfiles che può aiutare a elencare i file in uso e scollegarli. A prima vista sembra perfetto per le tue esigenze! Puoi persino racchiuderlo in una funzione PowerShell per facilitare l’interrogazione e la disconnessione dei file.

Apri un prompt di PowerShell amministrativo ed esegui il comando openfiles / query . Immediatamente, dovresti ricevere un messaggio di errore che indica che il flag globale “mantieni elenco oggetti” deve essere attivo.

PS C:/> openfiles / query INFO: Il sistema Il flag globale ‘mantieni l’elenco degli oggetti’ deve essere abilitato per vedere i file aperti locali. Vedi Openfiles /? per maggiori informazioni. File aperti in remoto tramite punti di condivisione locali: —————————————— — INFO: Nessun file aperto condiviso trovato. Questo elenco di oggetti è ciò che effettivamente mantiene l’elenco degli handle che sono in uso e abilita openfiles per richiedere tali informazioni. Per attivarlo, inserisci openfiles / local on , quindi riavvia il computer. Lo svantaggio dell’attivazione di questa funzione è che si verifica un leggero calo delle prestazioni, che a seconda del sistema potrebbe non valere l’utilità di utilizzare questo strumento. Detto questo, vediamo come possiamo farlo funzionare all’interno di PowerShell.

PS C: > openfiles / Query / fo csv / nh File aperti da remoto tramite punti di condivisione locali: ——————————————— “ID”, ” Accesso da “,” Tipo “,” Apri file (percorso eseguibile) “” 608 “,” utente “,” Windows “,” C: “PS C: > openfiles / Query / fo csv | Seleziona-Oggetto-Salta 4 | ConvertFrom-CSV ID accessibile per tipo Apri file (percorso eseguibile) – ———– —- ——————- ——– 608 utente Windows C: PS C: > openfiles / disconnect / id 608 SUCCESSO: La connessione al file aperto “C: ” è stata terminata. Con gli esempi precedenti, puoi vedere come per importare l’output CSV di file aperti in PowerShell. Utilizzando queste informazioni, puoi quindi disconnetterti un file per sbloccarlo. A causa del calo delle prestazioni che potresti incorrere con l’abilitazione dell’elenco degli oggetti di mantenimento , potrebbe non essere utile per le tue esigenze. Per questo motivo, potrebbero essere necessarie altre soluzioni.

The Handle Application Sysinternals è noto per i molti strumenti IT utili e quasi essenziali che producono. Qualche tempo fa, Sysinternals è stato acquisito da Microsoft e puoi scaricare e utilizzare questi strumenti ben supportati per te stesso. Convenientemente, c’è un’applicazione denominata handle che fornisce esattamente quello che stai cercando!

Innanzitutto, devi per scaricare l’applicazione, decomprimere i file e inserire gli eseguibili in una posizione inclusa nella variabile d’ambiente Path. In questo modo, puoi facilmente fare riferimento all’applicazione ovunque ti serva. Utilizzando una semplice query per i file aperti, puoi vedere che ottieni molti risultati (troncati per leggibilità).

PS C:/> handle 64 -NoBanner … — ————————————————– ————————- RuntimeBroker.exe pid: 9860 Utente 48: File C: Windows System 32 188: Sezione BaseNamedObjects __ ComCatalogCache__ 1EC: Sezione BaseNamedObjects __ ComCatalogCache__ —————- ————————————————– ———— chrome.exe pid: 4628 Utente 78: File C: Programmi (x 86) Google Chrome Application 78. 0. 3904. 108 1C4: Sezione Sessions 1 BaseNamedObjects windows_shell_global_counters … Sembra che tu abbia quello che vuoi, almeno un modo per scoprire quali file vengono utilizzati, e puoi testarli usando il tuo codice di file bloccato da prima. Ma come puoi renderlo più facile da usare? Il codice seguente legge ogni processo e recupera solo i file bloccati. Lo svantaggio è che questo richiede un po ‘di tempo perché ci sono molti processi.

$ Processes = Get-Process $ results = $ Processes | Oggetto Foreach {$ handle = (handle 64 -p $ _. ID -NoBanner) | Where-Object {$ _ -Match “File”} | Foreach-Object {[PSCustomObject] @ {“Hex” = ((($ _ -Split “”) .Where ({$ _ -NE “”}) [0]). Split (“:” ) [0]). Trim () “File” = (($ _ -Split “”) [-1]). Trim ()}} If ($ handle) {[PSCustomObject] @ {“Name” = $ _. Name “PID” = $ _. ID “Handles” = $ handle}}} In definitiva, però, quello che ottieni è un raccolta di file utilizzabili, elencati per processo, che sai essere in uso e che possono essere ulteriormente filtrati. Se scopri che devi chiuderne uno, puoi fare quanto segue (come amministratore):

PS C: > $ risultati | >> Where-Object Name -EQ ‘Notepad’ | >> Where-Object {$ _. Handles.File -Match “test.txt”} Nome PID Handles —- — ——- Blocco note 12028 {@ {Hex = 44; File = C: test.txt} PS C: > handle 64 -p 12028 -c 44 -y -nobanner 44: File (RD) C: test.txt Handle chiuso. Puoi ulteriormente racchiudere tutto questo in una funzione per farlo ancora più facile da analizzare e cercare se necessario. Esistono molte possibilità, soprattutto combinando i vari metodi in una soluzione adatta al proprio ambiente.

Conclusione Gestire i file bloccati può essere una sfida, soprattutto quando interrompe ciò che devi fare rapidamente. Esistono diversi modi per trovare e sbloccare quei file, ma richiede un po ‘di lavoro poiché Windows non ha un metodo integrato veramente completo per gestire quei file bloccati. Le soluzioni descritte dovrebbero semplificare il lavoro di qualunque sia il problema e consentirti di passare a compiti molto più importanti!