파일을 잠그는 응용 프로그램을 확인하는 PowerShell 스크립트?
PowerShell에서 응용 프로그램이 파일을 잠그고 있는지 확인하려면 어떻게 해야 합니까?
파일을 닫을 수 있도록 어떤 프로세스/어플리케이션이 사용되고 있는지 확인하고 싶습니다.
이 작업은 SysInternals tool handle.exe를 사용하여 수행할 수 있습니다.다음과 같은 것을 시도해 보십시오.
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
...
이를 통해 다음과 같은 이점을 얻을 수 있습니다.PowerShell을 사용하여 파일을 잠그는 프로세스를 찾습니다.시스템을 파싱합니다.진단.각 프로세스의 ProcessModule Collection Modules 속성과 잠금 파일의 파일 경로를 찾습니다.
$lockedFile="C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq $lockedFile){$processVar.Name + " PID:" + $processVar.id}}}
일반 명령줄 또는 PowerShell에서 openfiles 명령을 사용할 수 있어야 합니다.
열린 파일 내장 도구는 파일 공유 또는 로컬 파일에 사용할 수 있습니다.로컬 파일의 경우 도구를 켜고 기계를 다시 시작해야 합니다(처음 사용하는 경우에만 해당).이 기능을 켜는 명령은 다음과 같습니다.
openfiles /local on
예를 들어(Windows Vista x64에서 작동):
openfiles /query | find "chrome.exe"
Chrome과 관련된 파일 핸들을 성공적으로 반환합니다.파일 이름을 전달하여 해당 파일에 현재 액세스 중인 프로세스를 확인할 수도 있습니다.
Sysinternal의 Handle 유틸리티를 사용하면 해결책을 찾을 수 있습니다.
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
예:
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>
저도 해결책을 찾고 있었는데 딸꾹질을 좀 했어요.
- 외부 앱을 사용하고 싶지 않음
- Open Files(열린 파일)에는 로컬 ON 특성이 필요한데, 이는 실행 전에 시스템이 이 특성을 사용하도록 구성해야 함을 의미합니다.
광범위한 탐색 끝에 발견했습니다.
폴 디마지오 덕분에
이것은 순수한 파워셸과 .net / C#인 것 같습니다.
handle.exe에서 경로를 찾을 수 있습니다.
PowerShell을 사용해 보았지만 다른 명령줄 도구를 사용할 수 있습니다.
관리 권한이 있는 경우:
handle.exe -a | Select-String "<INSERT_PATH_PART>" -context 0,100
행을 따라 "Thread:..."를 검색하면 경로를 사용하는 프로세스의 이름이 표시됩니다.
PsGallery에 PowerShell 모듈을 게시하여 파일 또는 폴더에 대한 핸들이 열려 있는 프로세스를 검색 및 삭제했습니다.1) 잠금 프로세스를 찾고 2) 잠금 프로세스를 종료하는 기능을 제공합니다.모듈이 핸들을 자동으로 다운로드합니다.초용을 집행하다
찾기-잠금 프로세스()
지정된 경로에 대해 파일 핸들이 열려 있는 프로세스 정보를 검색합니다.
: 프로세스 - 기-스-로 $Env:로컬 앱 데이터
예: 프로세스 - 기-스-로 $Env:TA | Get-Process
정지-잠금 프로세스()
지정된 경로에 대해 파일 핸들이 열려 있는 모든 프로세스를 죽입니다.
:Stop-Locking Process -Path $Home\문서 .
PsGallery Link: https://www.powershellgallery.com/packages/LockingProcessKiller 설치하려면 다음을 실행합니다.
설치-모듈 - 이름 잠금 프로세스 킬러
저는 SysInternals에 의존하고 싶지 않았기 때문에 이 문제에 부딪혀 완전히 자기 자신을 포함한 스크립트를 작성했습니다.스크립트는 전체 재귀 복사본을 만들기 전에 파일을 잠그는 프로세스를 식별하고 삭제합니다.
https://github.com/Tikinsin/ForceCopy.ps1/blob/main/ForceCopy.ps1
이는 Zachery Fischer와 Paul DiMagio의 Github 솔루션의 답변을 활용합니다.
명령 프롬프트(CMD)가 있는 것이 마음에 들고 파워셸에서도 사용할 수 있습니다.
tasklist /m <dllName>
DLL 파일의 전체 경로를 입력할 수는 없습니다.이름만으로도 충분합니다.
PowerShell 과만 사용하는 Locked file detection에서 멋진 솔루션을 본 적이 있습니다.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
}
아래와 같이 위 기능을 약간 수정하면 True 또는 False가 반환됩니다(전체 관리 권한으로 실행해야 함). 예:
PS> 파일잠금 테스트 "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
}
언급URL : https://stackoverflow.com/questions/958123/powershell-script-to-check-an-application-thats-locking-a-file
'programing' 카테고리의 다른 글
MariaDB Galera 클러스터가 동기화되고 있지 않습니다. (0) | 2023.10.26 |
---|---|
매개 변수가 포함된 Swift GET 요청 (0) | 2023.10.26 |
드롭 테이블도 제약 조건을 드롭합니까? (0) | 2023.10.26 |
중복된 기본 키에서 Pandas to_sql이 실패함 (0) | 2023.10.26 |
파워셸의 목록에서 마지막 항목 선택 (0) | 2023.10.26 |