Fechar arquivo bloqueado no Windows Share usando Powershell e Openfiles

3

Eu trabalho com muitos compartilhamentos de pastas, mas há vários arquivos bloqueados que foram abertos por outro processo.

Eu preciso fechar esses arquivos. Até agora eu tenho usado o MMC - System Tools - Pastas compartilhadas - Open Files.

Seria muito mais conveniente se eu pudesse usar o PowerShell para filtrar a lista / tabela recuperada por OpenFiles.exe e depois de obter o ID do arquivo, feche-o com net file / close , ou algum outro nativo PS significa efeito similar.

Eu sou novo no PowerShell, então gostaria de saber se existe uma maneira de criar um script PS que receba o caminho do arquivo e, em seguida, use o ID do arquivo para fechar esse arquivo?

    
por Renato Reyes 03.09.2015 / 17:24

3 respostas

3

Get-SmbOpenFile e Close-SmbOpenFile farão o trabalho por você.

Conectado ao seu servidor de arquivos, inicie o PowerShell. Use Get-SmbOpenFile para exibir todos os arquivos abertos no seu servidor de arquivos. Os arquivos serão exibidos junto com os seguintes cabeçalhos de tabela

FileId                  SessionId               Path           ShareRelativePath      ClientComputerName     ClientUserName

Use Close-SmbOpenFile para fechar um arquivo.

Close-SmbOpenFile -FileId 4415226383589

Se você sabe que um arquivo Excel é o problema, você pode restringir a pesquisa de todos os arquivos abertos com uma extensão .XLSX.

Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX"

Depois de encontrar seu arquivo de problema nos resultados, você pode fechar o arquivo pelo fileID.

Se você quiser fechar todos os arquivos abertos no seu servidor de arquivos:

Get-SmbOpenFile | Close-SmbOpenFile

Se você deseja fechar um ou mais arquivos que estão abertos e que correspondem à extensão de arquivo ".XLSX".

Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX" | Close-SmbOpenFile -Force

**** NOTA **** De acordo com o artigo do TechNet "O cmdlet Close-SMBOpenFile fecha à força um arquivo que é aberto por um dos clientes do Servidor SMB (Server Message Block). Esse cmdlet deve ser usado com cuidado, pois pode resultar em perda de dados para o cliente para o qual o arquivo está sendo fechado se o cliente não tiver liberado todas as modificações do arquivo de volta ao servidor antes que o arquivo seja fechado. "

Para mais informações sobre os CMDlets

Get-SmbOpenFile link

Close-SmbOpenFile link

    
por 28.07.2017 / 22:08
1

Existe uma razão pela qual você precisa usar openfiles.exe e net file ?
Abaixo está uma função que usa apenas net file e o envolve em um Script do PowerShell.

Para usá-lo, você pode copiar o código inteiro e colá-lo em uma sessão do PowerShell. Como observação, você precisa de privilégios de administrador para usar net file e openfiles .

Depois de colá-lo na sua sessão, você poderá usar a função Close-OpenFile . O uso é muito simples. Você pode canalizar os caminhos de arquivo para a função ou especificar os caminhos de arquivo como um parâmetro.

Se você colou como está, você pode obter ajuda usando Get-Help Close-OpenFile -Example para ver exemplos. Abaixo estão os mesmos exemplos para sua conveniência.

# Method 1 : Pipeline
@("file\path", "file\path") | Close-OpenFile
"file\path" | Close-OpenFile

# Method 2 : Parameter
Close-OpenFile @("file\path", "file\path")
Close-OpenFile "file\path"

Agora, suponha que você queira usar isso toda vez que abrir o PowerShell. Eu forneci uma maneira básica de fazer isso (existem outras maneiras de fazer isso) no final desta resposta.

<#
.Synopsis
   Closes Files Opened in Network Share
.EXAMPLE
   @("file\path", "file\path") | Close-OpenFile
   Attempts to close "file\path" and "file\path" if they are open.
.EXAMPLE
   Close-OpenFile @("file\path", "file\path")
   Attempts to close "file\path" and "file\path" if they are open.
.EXAMPLE
   "file\path" | Close-OpenFile
   Attempts to close "file\path" if it is open.
.EXAMPLE
   Close-OpenFile "file\path"
   Attempts to close "file\path" if it is open.
#>
function Close-OpenFile {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [String[]]$filesToClose
    )
    Begin {
        $netFile = net file
        if($netFile.length -lt 7) { Throw "No Files are Open" }
        $netFile = $netFile[4..($netFile.length-3)]
        $netFile = $netFile | ForEach-Object {
            $column = $_ -split "\s+", 4
            New-Object -Type PSObject -Property @{
                ID = $column[0]
                FilePath = $column[1]
                UserName = $column[2]
                Locks = $column[3]
            }
        }
        $count = 0
    } Process {
        ForEach ($file in $filesToClose) {
            ForEach ($openFile in $netFile) {
                if($openFile.FilePath -eq $file) {
                    $count++
                    net file $openfile.ID /close > $null
                }
            }
        }
    } End { Write-Output "Closed $count Files" }
}

Abaixo ilustra uma maneira básica de ter essa função toda vez que você abrir o PowerShell.

  1. Navegue para $env:homepath\Documents\WindowsPowerShell (crie-o se você não o tiver).
    Isso normalmente resolve para C:\Users\<username>\Documents\WindowsPowerShell .
  2. Crie um arquivo chamado profile.ps1 (ou Microsoft.PowerShell_profile.ps1 ).
  3. Copie e cole toda a função Close-OpenFiles e salve-a.
por 07.09.2015 / 10:16
0

Aqui está um rápido e sujo usando CMD e OpenFiles.exe. Tenho certeza de que isso pode ser traduzido rapidamente para PoSH, se necessário. Salve isso como CloseFile.cmd e coloque-o em uma pasta no seu caminho.

    @echo off
    if "%1" == "" goto SYNTAX
    if "%2" == "" goto SYNTAX
    goto RUNIT

    :SYNTAX
        echo Use:
        echo    CloseFile.cmd ^<server^> ^<file^>
        goto :EOF

    :RUNIT
        set _server=%1
        set _file=%2
        openfiles /query /s %_server% /fo csv | findstr /i /c:"%_file%" > _filelist.txt
        for /f "tokens=1,4 delims=," %%a in (_filelist.txt) do (
            openfiles /disconnect /s %_server% /op %%b /id %%a
        )

        if exist _filelist.txt del _filelist.txt
    
por 10.11.2016 / 16:38