Um dos erros mais frustrantes com que um usuário final ou administrador de TI pode lidar é o bloqueio de arquivos no Windows.. Quando você apaga uma pasta, você move um arquivo ou edita uma configuração e encontra uma mensagem de erro de arquivo bloqueado, melhor lidar com isso de forma rápida e eficiente.
A Microsoft apresentou o PowerShell como um shell substituto, mas tem muito mais funcionalidade do que isso e é uma linguagem complexa e capaz. Vamos ver neste post como você pode usar o PowerShell para lidar com arquivos bloqueados.
O problema do arquivo bloqueado
Como exatamente você bloqueia um arquivo? Durante o uso normal, um procedimento cria muitos identificadores de recursos como um arquivo. Ao fazer isso, processos muitas vezes bloqueiam o arquivo para evitar alterações de configuração indesejadas ou outro tipo de corrupção. O problema geralmente é que é difícil determinar qual procedimento bloqueou o arquivo e, subseqüentemente, como limpar aquele bloqueio de arquivo.
Infelizmente, não há cmdlet embutido para testar um arquivo e descobrir se ele está bloqueado ou por qual procedimento. Por isso, você precisa criar suas próprias funções ou empacotar outras ferramentas úteis para ajudá-lo a aprender mais sobre esses arquivos.
Teste de arquivos bloqueados
Dentro de Windows, você pode testar para ver se um arquivo individual está bloqueado. Com o seguinte bloco de código, você pode testar para ver se um determinado arquivo está bloqueado. a $Item
A variável deve ser definida para um caminho de arquivo completo. Ao testar para ver se o arquivo pode ser aberto para gravação, como fica com ele [System.IO.File]::Open($Item,'Open','Write')
comando, 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 integrada, mas há um caso em que existe uma função. Se você tiver um compartilhamento remoto ou mesmo administrativo (O que c$
), então você pode usar o Get-SMBOpenFile
cmdlet para relatar sobre os arquivos abertos.
PS C:> Get-SMBOpenFile
FileId SessionId Path ShareRelativePath
------ --------- ---- -----------------
154618822665 154618822657 C:
PS C:>
A desvantagem é que isso só funciona para arquivos que são acessados remotamente. Nenhum arquivo bloqueado em uso em seu sistema local será relatado, então, na maioria dos casos, esta não é uma solução viável. Para fechar, você pode canalizar arquivos abertos retornados ao Close-SMBOpenFile
comando.
Get-SMBOpenFile | Close-SMBOpenFile
Utilitário OpenFiles
O Windows tem um utilitário integrado chamado openfiles
o que pode ajudar a listar quais arquivos estão em uso e desconectá-los. A primeira vista, parece perfeito para suas necessidades! Você pode até envolver isso dentro de uma função do PowerShell para tornar mais fácil verificar e desconectar arquivos..
Abra um prompt administrativo do PowerShell e execute o comando openfiles /query
. De imediato, você deve receber uma mensagem de erro que indica que a bandeira global “manter lista de objetos” deve ser habilitado.
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 é o que realmente mantém a lista de identificadores que estão em uso e permite openfiles
consultar essa informação. Para ativar este, entra openfiles /local on
e reinicie o seu computador. A desvantagem de ativar esse recurso é que há um pequeno impacto no desempenho, que dependendo do seu sistema, esta ferramenta pode não valer a pena usar. Tendo dito isto, vamos ver como podemos fazer isso funcionar dentro do 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.
Com os exemplos acima, você pode ver como importar a saída CSV de openfiles
e PowerShell. Com essa informação, poderia disconnect
um arquivo para desbloquear. Devido ao impacto no desempenho que você pode incorrer ao ativar o maintain objects list
capacidade, pode não valer a pena para suas necessidades. É por isto que, outras soluções podem ser necessárias.
A aplicação da alça
A Sysinternals é conhecida pelas muitas ferramentas de TI úteis e quase essenciais que fabrica. Faz tempo, A Microsoft adquiriu a Sysinternals e você pode baixar e usar essas ferramentas bem suportadas por conta própria. Convenientemente, existe um aplicativo chamado handles
que fornece exatamente o que você está procurando.
Primeiro, você deve descargar a aplicação, descompacte os arquivos e coloque os executáveis em um local que inclua sua variável de ambiente Path. Ao fazer isso, você pode consultar facilmente o aplicativo onde precisar. Com uma consulta simples para arquivos abertos, você pode ver que consegue muitos resultados (truncado 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
...
Você parece conseguir o que quer, pelo menos uma maneira de descobrir quais arquivos estão sendo usados, e você pode testá-los usando o código de arquivo bloqueado de antes. Mas, Como você torna isso mais fácil de usar? O código a seguir lê cada procedimento e recupera apenas os arquivos bloqueados. A desvantagem é que demora um pouco para ser executado, 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
}
}
}
Apesar disto, em última instância, o que você obtém é uma coleção de arquivos acionável, listado por procedimento, que você sabe que estão em uso e podem ser filtrados posteriormente. Se você achar que precisa fechar um deles, 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 (R-D) C:test.txt
Handle closed.
Você pode agrupar tudo isso em uma função para tornar ainda mais fácil analisar e pesquisar conforme necessário.. Existem muitas alternativas, especialmente na combinação de vários métodos em uma solução que se adapta ao seu ambiente.
conclusão
Lidar com arquivos bloqueados pode ser um desafio, especialmente quando você interrompe o que precisa fazer rapidamente. Existem várias alternativas para encontrar e desbloquear esses arquivos, mas dá um pouco de trabalho, pois o Windows não tem um método integrado verdadeiramente abrangente para lidar com esses arquivos bloqueados. As soluções descritas devem manter o problema breve e permitir que você prossiga para tarefas muito mais importantes.
Não existem postagens relacionadas