Wie kann ich in PowerShell prüfen, ob eine Anwendung eine Datei sperrt?PowerShell-Skript zum Überprüfen einer Anwendung, die eine Datei sperrt?
Ich möchte überprüfen, welcher Prozess/Anwendung die Datei verwendet, damit ich es schließen kann.
Wie kann ich in PowerShell prüfen, ob eine Anwendung eine Datei sperrt?PowerShell-Skript zum Überprüfen einer Anwendung, die eine Datei sperrt?
Ich möchte überprüfen, welcher Prozess/Anwendung die Datei verwendet, damit ich es schließen kann.
Sie können dies mit der SysInternals tool handle.exe tun. Probieren Sie etwas wie folgt aus:
PS> $handleOut = handle
PS> foreach ($line in $handleOut) {
if ($line -match '\S+\spid:') {
$exe = $line
}
elseif ($line -match 'C:\\Windows\\Fonts\\segoeui\.ttf') {
"$exe - $line"
}
}
MSASCui.exe pid: 5608 ACME\hillr - 568: File (---) C:\Windows\Fonts\segoeui.ttf
...
Sie können die openfiles command entweder über die normale Befehlszeile oder über PowerShell verwenden.
Das integrierte Tool "openfiles" kann für Dateifreigaben oder für lokale Dateien verwendet werden. Für lokale Dateien müssen Sie das Tool einschalten und den Computer neu starten (nur für die erstmalige Verwendung). Ich glaube, dass der Befehl diese Funktion aktivieren ist:
openfiles /local on
Zum Beispiel (funktioniert unter Windows Vista x64 ):
openfiles /query | find "chrome.exe"
die erfolgreich Datei zurückgibt Griffe mit Chrome verbunden. Sie können auch einen Dateinamen eingeben, um den Prozess zu sehen, der gerade auf diese Datei zugreift.
Von dem, was ich sehe, dass Befehl einfach aufzählt Dateien, die von von einem Benutzer geöffnet werden remote über SMB-Aktien. Es wird Ihnen nichts über den Prozess erzählen, der es benutzt. – Joey
Sie können es nicht von dem Link erzählen, aber es sieht so aus, als ob Johannes recht hat. Es funktioniert nicht auf Vista x64 für mich - sagt "INFO: Keine freigegebenen geöffneten Dateien gefunden." –
Joe/Johannes: Erstens, haben Sie die globale "Liste der verwalteten Objekte" aktiviert (ich denke, die Syntax ist "openfiles/local on" IIRC)? Als nächstes übergeben Sie das Argument "/ query", wie im obigen Beispiel (für Vista erforderlich)? – Garrett
ich eine schöne Lösung bei Locked file detection gesehen haben, die nur Powershell und .NET Framework-Klassen verwendet:
function TestFileLock {
## Attempts to open a file and trap the resulting error if the file is already open/locked
param ([string]$filePath)
$filelocked = $false
$fileInfo = New-Object System.IO.FileInfo $filePath
trap {
Set-Variable -name filelocked -value $true -scope 1
continue
}
$fileStream = $fileInfo.Open([System.IO.FileMode]::OpenOrCreate,[System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
if ($fileStream) {
$fileStream.Close()
}
$obj = New-Object Object
$obj | Add-Member Noteproperty FilePath -value $filePath
$obj | Add-Member Noteproperty IsLocked -value $filelocked
$obj
}
Wenn Sie die obige Funktion etwas ändern wie darunter gibt True oder False zurück (Sie müssen mit vollen Admin-Rechten ausführen) eg Verbrauch:
PS> TestFileLock "c: \ pagefile.sys"
function TestFileLock {
## Attempts to open a file and trap the resulting error if the file is already open/locked
param ([string]$filePath)
$filelocked = $false
$fileInfo = New-Object System.IO.FileInfo $filePath
trap {
Set-Variable -name Filelocked -value $true -scope 1
continue
}
$fileStream = $fileInfo.Open([System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
if ($fileStream) {
$fileStream.Close()
}
$filelocked
}
This gibt an, ob die Datei gesperrt ist oder nicht, gibt aber nicht die Anwendung, die die Datei sperrt – CJBS
Zusätzlich: Es wird * eine * neue * Datei erstellen, wenn sie nicht bereits existiert – monojohnny
Dies könnte Ihnen helfen: Use PowerShell to find out which process locks a file. Es analysiert die System.Diagnostics.ProcessModuleCollection Module Eigenschaft jeden Prozess und es sieht für den Dateipfad der gesperrten Datei:
$lockedFile="C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}}
Wäre die perfekte Antwort für mich gewesen, scheint aber, dass dies nur für dlls funktionieren würde und nicht für irgendwelche Dateien, wie gesperrte Textdateien. –
Ich mag, was die Eingabeaufforderung (CMD) hat, und es kann in Powershell verwendet werden auch:
tasklist /m <dllName>
Es genügt zu bemerken, dass Sie nicht den vollständigen Pfad der DLL-Datei eingeben. Nur der Name ist gut genug.
Leider zeigt dies nur DLL-Dateien ... – KERR
Sie können eine Lösung mit Sysinternal 's Handle Dienstprogramm finden.
Ich hatte den Code (etwas) ändern mit Powershell arbeiten 2.0:
#/* http://jdhitsolutions.com/blog/powershell/3744/friday-fun-find-file-locking-process-with-powershell/ */
Function Get-LockingProcess {
[cmdletbinding()]
Param(
[Parameter(Position=0, Mandatory=$True,
HelpMessage="What is the path or filename? You can enter a partial name without wildcards")]
[Alias("name")]
[ValidateNotNullorEmpty()]
[string]$Path
)
# Define the path to Handle.exe
# //$Handle = "G:\Sysinternals\handle.exe"
$Handle = "C:\tmp\handle.exe"
# //[regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\b(\d+)\b)\s+type:\s+(?<Type>\w+)\s+\w+:\s+(?<Path>.*)"
# //[regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+\w+:\s+(?<Path>.*)"
[regex]$matchPattern = "(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+(?<User>\.+)\s+\w+:\s+(?<Path>.*)"
$data = &$handle -u $path
$MyMatches = $matchPattern.Matches($data)
# //if ($MyMatches.value) {
if ($MyMatches.count) {
$MyMatches | foreach {
[pscustomobject]@{
FullName = $_.groups["Name"].value
Name = $_.groups["Name"].value.split(".")[0]
ID = $_.groups["PID"].value
Type = $_.groups["Type"].value
User = $_.groups["User"].value.trim()
Path = $_.groups["Path"].value
toString = "pid: $($_.groups["PID"].value), user: $($_.groups["User"].value), image: $($_.groups["Name"].value)"
} #hashtable
} #foreach
} #if data
else {
Write-Warning "No matching handles found"
}
} #end function
Beispiel:
PS C:\tmp> . .\Get-LockingProcess.ps1
PS C:\tmp> Get-LockingProcess C:\tmp\foo.txt
Name Value
---- -----
ID 2140
FullName WINWORD.EXE
toString pid: 2140, user: J17\Administrator, image: WINWORD.EXE
Path C:\tmp\foo.txt
Type File
User J17\Administrator
Name WINWORD
PS C:\tmp>
Schön, danke fürs Schreiben dieser einfachen Funktion! – Denis
Danke, ich kann einfach handle [Dateiname] verwenden, um es einfacher zu machen. –
Wo ist der Spaß dabei? :-) Aber ja, das wäre viel einfacher. –
:(immer noch Probleme mit ... Es ist nicht so leistungsfähig zu zeigen, wenn Dateien (dh Textdateien) durch einen bestimmten Prozess geöffnet werden. –