de script PowerShell pour vérifier une application qui est un fichier de verrouillage?

StackOverflow https://stackoverflow.com/questions/958123

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

Était-ce utile?

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
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top