Como gerenciar identificadores de arquivo aberto com PowerShell

Um dos erros mais frustrantes que um usuário final ou administrador de TI pode enfrentar é o de arquivos bloqueados no Windows. Quando você exclui uma pasta, move um arquivo ou altera uma configuração e encontra uma mensagem de erro relacionada ao arquivo bloqueado, é melhor lidar com isso de maneira rápida e eficiente.

A Microsoft introduziu o PowerShell como um shell de substituição, mas tem muito mais funcionalidade do que isso e é uma linguagem complexa e capaz. Vamos dar uma olhada em como usar o PowerShell para gerenciar arquivos bloqueados neste artigo.

índice

  1. O problema do arquivo bloqueado
  2. Encontrar arquivos bloqueados
  3. Get-SMBOpenFile
  4. Utilitário OpenFiles
  5. A aplicação do punho.
  6. Conclusão

O problema do arquivo bloqueado

Como exatamente um arquivo é bloqueado? Durante o uso normal, um processo cria muitos identificadores de recursos como um arquivo. Dessa forma, os processos geralmente bloqueiam o arquivo para evitar alterações de configuração inadvertidas ou outros danos. O problema geralmente é que é difícil determinar qual processo bloqueou o arquivo e, posteriormente, como remover esse bloqueio do arquivo.

Infelizmente, não há cmdlet interno para testar um arquivo para determinar se ele está bloqueado ou por qual processo. Portanto, você deve criar suas próprias funções ou incluir outras ferramentas úteis existentes para ajudá-lo a obter mais informações sobre esses arquivos.

Encontrar arquivos bloqueados

No Windows, você pode verificar se um único arquivo está bloqueado. Com o bloco de código a seguir, você pode verificar se um arquivo específico está bloqueado. A variável $Item deve ser definida para um caminho de arquivo totalmente qualificado. Teste para ver se o arquivo pode ser aberto para escrita, como visto com o comando [System.IO.File]::Open($Item,'Open','Write') , você pode dizer se o arquivo 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 } }

Get-SMBOpenFile

Eu disse que o Windows não tem uma função embutida, mas há um caso em que existe uma função. Se você tiver um compartilhamento remoto ou mesmo um compartilhamento administrativo (como c$ ), poderá usar o cmdlet Get-SMBOpenFile para relatar esses arquivos abertos.

 PS C:> Get-SMBOpenFile FileId SessionId Path ShareRelativePath ------ --------- ---- ----------------- 154618822665 154618822657 C: PS C:>

A desvantagem é que só funciona para arquivos acessados ​​remotamente. Quaisquer arquivos bloqueados em uso no sistema local não serão relatados, portanto, na maioria dos casos, essa não é uma solução viável. Para fechar, você pode redirecionar os arquivos abertos retornados para o comando Close-SMBOpenFile .

Get-SMBOpenFile | Close-SMBOpenFile

Utilitário OpenFiles

O Windows tem um utilitário interno chamado openfiles que pode ajudá-lo a listar quais arquivos estão em uso e colocá-los offline. À primeira vista, parece perfeito para suas necessidades! Você pode até envolvê-lo em uma função do PowerShell para facilitar a consulta e desconectar arquivos.

Abra um prompt administrativo do PowerShell e execute o comando openfiles /query . Imediatamente, você deve receber uma mensagem de erro indicando que o sinalizador global "manter lista de objetos" deve estar ativado.

 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.

Essa lista de objetos é o que realmente mantém a lista de identificadores em uso e permite que os openfiles consultem essas informações. Para ativá-lo, digite openfiles /local on e reinicie o computador. A desvantagem de habilitar esse recurso é que há um pequeno impacto no desempenho, que dependendo do seu sistema pode não valer a pena usar essa ferramenta. Com isso dito, vamos ver como podemos fazê-lo funcionar no 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.

Usando os exemplos acima, você pode ver como importar a saída CSV de openfiles para o PowerShell. Com essas informações, você pode disconnect um arquivo para desbloqueá-lo. Devido à degradação do desempenho, você pode experimentar habilitar o recurso de maintain objects list , pode não ser útil para suas necessidades. Por esta razão, outras soluções podem ser necessárias.

A aplicação do punho.

A Sysinternals é conhecida pelas muitas ferramentas de TI úteis e quase essenciais que produz. Algum tempo atrás, a Microsoft adquiriu a Sysinternals e você mesmo pode baixar e usar essas ferramentas bem suportadas. Convenientemente, há um aplicativo chamado handles que fornece exatamente o que você está procurando.

Primeiro, você precisa baixar o aplicativo, descompactar os arquivos e colocar os executáveis ​​em um local incluído na variável de ambiente Path. Dessa forma, você pode facilmente consultar o aplicativo onde precisar. Com uma consulta simples para arquivos abertos, você pode ver que obtém muitos resultados (truncados para facilitar a leitura).

 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 você consegue o que deseja, pelo menos uma maneira de descobrir quais arquivos estão sendo usados, e você pode testá-los usando seu código de arquivo bloqueado anteriormente. Mas como você pode torná-lo mais fácil de usar? O código a seguir lê cada processo e recupera apenas os arquivos bloqueados. A desvantagem é que isso leva algum tempo, pois há muitos processos.

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

Em última análise, porém, o que você obtém é uma coleção de arquivos utilizáveis, listados por processo, que você sabe que estão em uso e podem ser filtrados ainda mais. Se você achar que precisa fechar um, você pode fazer o seguinte (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 (RD) C:test.txt Handle closed.

Você pode empacotar tudo isso em uma única função para tornar a análise e a pesquisa ainda mais fáceis, se necessário. São muitas as possibilidades, principalmente ao combinar os diversos métodos em uma solução adequada ao seu ambiente.

Conclusão

Lidar com arquivos bloqueados pode ser um desafio, principalmente quando interrompe o que precisa ser feito rapidamente. Existem várias maneiras de encontrar e desbloquear esses arquivos, mas isso requer algum trabalho, pois o Windows não possui um método interno realmente abrangente para lidar com esses arquivos bloqueados. As soluções descritas devem simplificar o trabalho de qualquer que seja o problema e permitir que você passe para tarefas muito mais importantes.

  • Google "The Fresh Prince of Bel-Air" para um divertido Easter Egg – Geek Review
  • Como testar a velocidade do disco e a RAM do seu servidor Linux

descubra mais conteúdo

O que é um amplificador integrado?

Google Pixel Watch também tem detecção de queda, mas não até o próximo ano

As melhores xícaras de café aquecidas de 2022

Como automatizar seu iPhone com base na hora, atividade ou localização

"Isso deve ter sido antes do meu tempo"

Por que a NASA enviou Snoopy para a Lua? – Revisão Geek

Deixe uma resposta Cancelar resposta

Como listar arquivos no CMD?

Use a linha de comando dir para exibir a lista completa de arquivos em um diretório específico. Para exibir a lista de arquivos com alguns atributos, use o comando dir. A data e hora da criação. O tipo, se for exibido, é um diretório, caso contrário, é um arquivo.

Como fazer uma lista de arquivos em uma pasta?

Passos a seguir

  1. Acesse seu servidor pela Área de Trabalho Remota. No caso de ser um PC, você pode simplesmente ir para a próxima etapa. Informação adicional.
  2. Abra o console de comando do Windows. Informação adicional.
  3. Acesse o diretório a partir do qual deseja criar a lista .
  4. Execute o comando: dir /b > list .txt.

Como pesquisar arquivos no PowerShell?

Use o cmdlet Get-ChildItem com a opção -Recurse no PowerShell para localizar arquivos recursivamente. O cmdlet Get-ChildItem exibe uma lista de arquivos e diretórios no local especificado.

Como você obtém uma lista de todos os comandos disponíveis para o PowerShell?

Para obter esta lista de comandos , é necessário escrever “Get-Command” seguido de um parâmetro específico, com o qual serão obtidas as informações sobre o cmdlet em questão.

Ir arriba