de script PowerShell pour vérifier une application qui est un fichier de verrouillage?
-
12-09-2019 - |
Question
Utilisation de PowerShell, comment puis-je vérifier si une application est verrouillage d'un fichier?
Je tiens à vérifier quel processus / application utilise le fichier, afin que je puisse le fermer.
La solution
Vous pouvez le faire avec le outil Sysinternals Handle.exe . Essayez quelque chose comme ceci:
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
...
Autres conseils
Vous devriez pouvoir utiliser le de commande openfiles soit de la ligne de commande régulière ou de PowerShell.
Les openfiles outil intégré peut être utilisé pour les partages de fichiers ou des fichiers locaux. Pour les fichiers locaux, vous devez activer l'outil et redémarrez la machine (encore une fois, juste pour la première utilisation). Je crois que la commande pour activer cette fonction est la suivante:
openfiles /local on
Par exemple (fonctionne sous Windows Vista x64):
openfiles /query | find "chrome.exe"
qui renvoie des descripteurs de fichiers avec succès associé à Chrome. Vous pouvez également passer un nom de fichier pour voir le processus actuellement accès à ce fichier.
Cela pourrait vous aider à: Utilisez PowerShell pour savoir quel processus verrouille un fichier . Il analyse la propriété Modules System.Diagnostics.ProcessModuleCollection de chaque processus et il recherche le chemin du fichier du fichier verrouillé:
$lockedFile="C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}}
Vous pouvez trouver une solution en utilisant Sysinternal 's Poignée utilitaire.
I eu pour modifier le code (légèrement) pour travailler avec PowerShell 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>.*)"
# (?m) for multiline matching.
# It must be . (not \.) for user group.
[regex]$matchPattern = "(?m)^(?<Name>\w+\.\w+)\s+pid:\s+(?<PID>\d+)\s+type:\s+(?<Type>\w+)\s+(?<User>.+)\s+\w+:\s+(?<Path>.*)$"
# skip processing banner
$data = &$handle -u $path -nobanner
# join output for multi-line matching
$data = $data -join "`n"
$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
Exemple:
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>
Je l'ai vu une bonne solution à Locked détection de fichiers qui utilise uniquement des classes cadres PowerShell et .NET:
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
}
J'aime ce que l'invite de commande (CMD) a, et il peut être utilisé dans PowerShell ainsi:
tasklist /m <dllName>
Notez juste que vous ne pouvez pas entrer le chemin complet du fichier DLL. Juste le nom est assez bon.
Si vous modifiez la fonction ci-dessus un peu comme ci-dessous, il retournera Vrai ou faux (Vous devrez exécuter avec des droits d'administrateur complets) par exemple. Utilisation:
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
}