使用 Powershell 和 Openfiles 关闭 Windows Share 中的锁定文件

Ren*_*yes 5 powershell windows-server-2008 file-sharing

我使用了很多文件夹共享,但是有一些其他进程打开了一堆锁定的文件。

我需要关闭这些文件。到目前为止,我一直在使用 MMC - 系统工具 - 共享文件夹 - 打开文件。

如果我可以使用 PowerShell 过滤由OpenFiles.exe检索到的列表/表,并且一旦我获得文件 ID,使用net file /close或其他一些具有类似效果的 PS 本机方法将其关闭,那将会方便得多。

我是 PowerShell 的新手,所以我想知道是否有办法创建一个 PS 脚本来接收文件的路径,然后使用文件 ID 来关闭该文件?

Art*_*y05 5

Get-SmbOpenFileClose-SmbOpenFile将为您完成工作。

登录到您的文件服务器,启动 PowerShell。使用 Get-SmbOpenFile 显示文件服务器上所有打开的文件。这些文件将与下表标题一起显示

FileId                  SessionId               Path           ShareRelativePath      ClientComputerName     ClientUserName
Run Code Online (Sandbox Code Playgroud)

使用 Close-SmbOpenFile 关闭文件。

Close-SmbOpenFile -FileId 4415226383589
Run Code Online (Sandbox Code Playgroud)

如果您知道 Excel 文件是问题所在,您可以缩小对所有带有 .XLSX 扩展名的打开文件的搜索范围。

Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX"
Run Code Online (Sandbox Code Playgroud)

在结果中找到您的问题文件后,您可以通过 fileID 关闭该文件。

如果要关闭文件服务器上所有打开的文件:

Get-SmbOpenFile | Close-SmbOpenFile
Run Code Online (Sandbox Code Playgroud)

如果您想关闭一个或多个已打开且与文件扩展名“.XLSX”匹配的文件。

Get-SmbOpenFile | Where-Object -Property sharerelativepath -match ".XLSX" | Close-SmbOpenFile -Force
Run Code Online (Sandbox Code Playgroud)

****注意**** 根据 TechNet 文章“ Close-SMBOpenFile cmdlet强制关闭由服务器消息块 (SMB) 服务器的一个客户端打开的文件应谨慎使用此 cmdlet,因为它如果客户端在关闭文件之前没有将所有文件修改刷新回服务器,则可能会导致正在关闭文件的客户端的数据丢失。”

有关 CMDlet 的更多信息

Get-SmbOpenFile https://technet.microsoft.com/en-us/library/jj635701(v=wps.620).aspx

Close-SmbOpenFile https://technet.microsoft.com/en-us/library/jj635721(v=wps.620).aspx


neh*_*art 1

您是否需要同时使用openfiles.exe net file?下面是一个仅使用并将其包装在 PowerShell 脚本中的
函数。net file

要使用它,您可以复制整个代码,并将其粘贴到 PowerShell 会话中。顺便说一句,您需要管理员权限才能使用net fileopenfiles

将其粘贴到会话中后,您将能够使用该功能Close-OpenFile。使用方法非常简单。您可以通过管道将文件路径输入到函数中,或者将文件路径指定为参数。

如果您按原样粘贴,您实际上可以通过查看Get-Help Close-OpenFile -Example示例来获得帮助。为了您的方便,以下是相同的示例。

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

# Method 2 : Parameter
Close-OpenFile @("file\path\1", "file\path\2")
Close-OpenFile "file\path\2"
Run Code Online (Sandbox Code Playgroud)

现在,假设您想在每次打开 PowerShell 时使用它。我在本答案的末尾提供了执行此操作的基本方法(还有其他方法可以执行此操作)。

<#
.Synopsis
   Closes Files Opened in Network Share
.EXAMPLE
   @("file\path\1", "file\path\2") | Close-OpenFile
   Attempts to close "file\path\1" and "file\path\2" if they are open.
.EXAMPLE
   Close-OpenFile @("file\path\1", "file\path\2")
   Attempts to close "file\path\1" and "file\path\2" if they are open.
.EXAMPLE
   "file\path\1" | Close-OpenFile
   Attempts to close "file\path\1" if it is open.
.EXAMPLE
   Close-OpenFile "file\path\2"
   Attempts to close "file\path\2" 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" }
}
Run Code Online (Sandbox Code Playgroud)

下面说明了每次打开 PowerShell 时使用此功能的基本方法。

  1. 导航至$env:homepath\Documents\WindowsPowerShell(如果没有,请创建它)。
    这通常会解析为C:\Users\<username>\Documents\WindowsPowerShell.
  2. profile.ps1创建一个名为(或)的文件Microsoft.PowerShell_profile.ps1
  3. 复制并粘贴整个Close-OpenFiles函数并保存。