So verwalten Sie geöffnete Datei-Handles mit PowerShell

Inhalt

Kommandozeilen-Leute

Einer der frustrierendsten Fehler, mit denen ein Endbenutzer oder IT-Administrator umgehen kann, sind gesperrte Dateien in Windows.. Wenn Sie einen Ordner löschen, Sie verschieben eine Datei oder bearbeiten eine Einstellung und Sie erhalten eine Fehlermeldung "Datei gesperrt", besser schnell und effizient damit umgehen.

Microsoft hat PowerShell als Ersatz-Shell eingeführt, aber es hat viel mehr Funktionalität und es ist eine komplexe und leistungsfähige Sprache. Sehen wir uns in diesem Beitrag an, wie Sie mit PowerShell mit gesperrten Dateien umgehen können.

Das Problem mit gesperrten Dateien

Wie genau sperrt man eine Datei?? Während des normalen Gebrauchs, eine Prozedur erstellt viele Ressourcenkennungen als eine Datei. Dabei, Prozesse sperren die Datei oft, um ungewollte Konfigurationsänderungen oder andere Beschädigungen zu verhindern. Das Problem besteht oft darin, dass schwer zu bestimmen ist, welche Prozedur die Datei gesperrt hat und, später, wie man diese Dateisperre aufhebt.

Unglücklicherweise, Es gibt kein integriertes Cmdlet, um eine Datei zu testen und herauszufinden, ob sie gesperrt ist oder nach welchem ​​Verfahren. So, Sie müssen Ihre eigenen Funktionen erstellen oder andere nützliche Tools verpacken, die Ihnen helfen, mehr über diese Dateien zu erfahren.

Gesperrte Dateien testen

Innerhalb von Windows, Sie können testen, ob eine einzelne Datei gesperrt ist. Mit folgendem Codeblock, Sie können testen, ob eine bestimmte Datei gesperrt ist. das $Item Die Variable muss auf einen vollständigen Dateipfad gesetzt werden. Beim Testen, ob die Datei zum Schreiben geöffnet werden kann, wie sieht es bei ihm aus [System.IO.File]::Open($Item,'Open','Write') Befehl, Sie können feststellen, ob die Datei gesperrt ist.

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

Ich sagte, Windows hat keine eingebaute Funktion, aber es gibt einen Fall, in dem eine Funktion existiert. Wenn Sie eine Remote- oder sogar eine administrative Freigabe haben (Was c$), dann kannst du das benutzen Get-SMBOpenFile Cmdlet, um über diese geöffneten Dateien zu berichten.

PS C:> Get-SMBOpenFile

FileId       SessionId    Path  ShareRelativePath
------       ---------    ----  -----------------
154618822665 154618822657 C:

PS C:> 

Der Nachteil ist, dass dies nur für Dateien funktioniert, auf die aus der Ferne zugegriffen wird. Es werden keine gesperrten Dateien gemeldet, die auf Ihrem lokalen System verwendet werden, In den meisten Fällen ist dies also keine praktikable Lösung. Schließen, Sie können geöffnete Dateien, die an die zurückgegeben werden, weiterleiten Close-SMBOpenFile Befehl.

Get-SMBOpenFile | Close-SMBOpenFile

OpenFiles-Dienstprogramm

Windows verfügt über ein integriertes Dienstprogramm namens openfiles was helfen kann, aufzulisten, welche Dateien verwendet werden, und sie zu trennen. Auf den ersten Blick, sieht perfekt aus für deine bedürfnisse! Sie können dies sogar in eine PowerShell-Funktion einschließen, um das Überprüfen und Trennen von Dateien zu erleichtern..

Öffnen Sie eine administrative PowerShell-Eingabeaufforderung und führen Sie den Befehl aus openfiles /query. Sofort, Sie sollten eine Fehlermeldung erhalten, die besagt, dass das globale Flag “Sie sollten eine Fehlermeldung erhalten, die besagt, dass das globale Flag” Sie sollten eine Fehlermeldung erhalten, die besagt, dass das globale Flag.

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.

Diese Liste von Objekten verwaltet wirklich die Liste der verwendeten Bezeichner und ermöglicht openfiles um diese Informationen zu konsultieren. Um dies zu aktivieren, eintragen openfiles /local on und starte dann deinen Computer neu. Der Nachteil bei der Aktivierung dieser Funktion besteht darin, dass die Leistung geringfügig beeinträchtigt wird, das abhängig von Ihrem System, Dieses Tool ist möglicherweise nicht die Verwendung wert. Nachdem ich dies gesagt habe, Mal sehen, wie wir dies in PowerShell zum Laufen bringen können.

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.

Mit den obigen Beispielen, Sie können sehen, wie Sie CSV-Ausgaben importieren von openfiles und PowerShell. Mit diesen Informationen, können disconnect eine Datei zum Entsperren. Aufgrund der Leistungseinbußen können Sie beim Aktivieren der maintain objects list Kapazität, ist es für deine Bedürfnisse vielleicht nicht wert. Darum, andere Lösungen können erforderlich sein.

Die Anwendung des Griffs

Sysinternals ist bekannt für die vielen nützlichen und fast unverzichtbaren IT-Tools, die es herstellt. Lange Zeit, Microsoft hat Sysinternals erworben und Sie können diese gut unterstützten Tools selbst herunterladen und verwenden. Bequem, es gibt eine Anwendung namens handles das bietet genau das was du suchst.

Zuerst, Du solltest descargar die Anwendung, Entpacken Sie die Dateien und legen Sie die ausführbaren Dateien an einem Ort ab, der Ihre Path-Umgebungsvariable enthält. Dabei, Sie können ganz einfach auf die App verweisen, wo Sie sie benötigen. Mit einer einfachen Abfrage nach offenen Dateien, Sie können sehen, dass Sie viele Ergebnisse erzielen (zum leichteren Lesen abgeschnitten).

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
...

Du scheinst zu bekommen was du willst, mindestens eine Möglichkeit herauszufinden, welche Dateien verwendet werden, und Sie können sie mit Ihrem gesperrten Dateicode von zuvor testen. Aber, Wie machen Sie dies einfacher zu verwenden?? Der folgende Code liest jede Prozedur und ruft nur die gesperrten Dateien ab. Der Nachteil ist, dass dies eine Weile dauert, da es viele Prozesse gibt.

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

Trotz dieses, als letztes, Was Sie erhalten, ist eine umsetzbare Sammlung von Dateien, nach Verfahren aufgelistet, von denen Sie wissen, dass sie in Gebrauch sind und weiter gefiltert werden können. Wenn Sie feststellen, dass Sie einen von ihnen schließen müssen, du kannst folgendes tun (als Administrator):

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.

Sie können all dies weiter in eine Funktion packen, um das Analysieren und Suchen nach Bedarf noch einfacher zu machen.. Es gibt viele Alternativen, insbesondere bei der Kombination mehrerer Methoden in einer Lösung, die zu Ihrer Umgebung passt.

Fazit

Der Umgang mit gesperrten Dateien kann eine Herausforderung sein, vor allem, wenn du aufhörst, was du schnell tun musst. Es gibt mehrere Alternativen, um diese Dateien zu finden und zu entsperren, aber es braucht ein bisschen Arbeit, da Windows keine wirklich umfassende integrierte Methode hat, um mit diesen gesperrten Dateien umzugehen. Die beschriebenen Lösungen sollen das Problem kurz halten und Sie zu viel wichtigeren Aufgaben übergehen lassen.

Abonniere unseren Newsletter

Wir senden Ihnen keine SPAM-Mail. Wir hassen es genauso wie du.