WIP
This commit is contained in:
122
Find-FileHandles.ps1
Normal file
122
Find-FileHandles.ps1
Normal file
@@ -0,0 +1,122 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Specifies a directory and lists all processes that have open file handles within that directory and its
|
||||
subdirectories.
|
||||
|
||||
.DESCRIPTION
|
||||
This script utilizes the handle.exe tool from Microsoft's Sysinternals suite to find open file handles.
|
||||
It filters the results to show only file handles within the specified target directory path.
|
||||
The script requires handle.exe to be downloaded and its path correctly configured in the $handleExePath
|
||||
variable.
|
||||
For best results, run this script with Administrator privileges.
|
||||
|
||||
.PARAMETER TargetDirectory
|
||||
The path to the directory to scan for open file handles. Defaults to the Windows directory (C:\Windows).
|
||||
|
||||
.EXAMPLE
|
||||
.\Find-FileHandles.ps1
|
||||
(Scans the default C:\Windows directory)
|
||||
|
||||
.EXAMPLE
|
||||
.\Find-FileHandles.ps1 -TargetDirectory "D:\Project\video-av1"
|
||||
(Scans the D:\Project\video-av1 directory)
|
||||
#>
|
||||
param (
|
||||
[string]$TargetDirectory = $env:SystemRoot # Defaults to C:\Windows
|
||||
)
|
||||
|
||||
# 콘솔 인코딩 설정 (한글 깨짐 방지)
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
|
||||
# --- CONFIGURATION ---
|
||||
# handle.exe 경로 자동 탐지
|
||||
$possiblePaths = @(
|
||||
"C:\Sysinternals\handle.exe",
|
||||
"$env:ProgramFiles\Sysinternals\handle.exe",
|
||||
"$env:USERPROFILE\Downloads\handle.exe",
|
||||
"$env:TEMP\handle.exe",
|
||||
"handle.exe" # PATH에 있는 경우
|
||||
)
|
||||
|
||||
$handleExePath = $null
|
||||
foreach ($path in $possiblePaths) {
|
||||
if (Test-Path $path) {
|
||||
$handleExePath = $path
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# PATH에서 handle.exe 찾기
|
||||
if (-not $handleExePath) {
|
||||
try {
|
||||
$handleExePath = (Get-Command "handle.exe" -ErrorAction Stop).Source
|
||||
} catch {
|
||||
$handleExePath = $null
|
||||
}
|
||||
}
|
||||
# ---------------------
|
||||
|
||||
# handle.exe 파일 존재 여부 확인
|
||||
if (-not $handleExePath -or -not (Test-Path $handleExePath)) {
|
||||
Write-Host "[ERROR] handle.exe not found in any of the following locations:" -ForegroundColor Red
|
||||
$possiblePaths | ForEach-Object { Write-Host " - $_" -ForegroundColor Yellow }
|
||||
Write-Host ""
|
||||
Write-Host "Please download handle.exe from:" -ForegroundColor Cyan
|
||||
Write-Host "https://learn.microsoft.com/en-us/sysinternals/downloads/handle" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "And place it in one of the above locations, or add it to your PATH." -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Scanning for open file handles in '$TargetDirectory'..."
|
||||
Write-Host "This may take a moment..."
|
||||
|
||||
# Execute handle.exe to get all open file handle information
|
||||
try {
|
||||
Write-Host "Executing handle.exe..." -ForegroundColor Gray
|
||||
$handleOutput = & $handleExePath -nobanner -a -u "$TargetDirectory" 2>$null | Out-String
|
||||
}
|
||||
catch {
|
||||
Write-Host "[ERROR] Failed to execute handle.exe: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return
|
||||
}
|
||||
|
||||
# 결과를 저장할 배열 초기화
|
||||
$foundProcesses = @()
|
||||
|
||||
# Analyze handle.exe output line by line
|
||||
if ($handleOutput) {
|
||||
# Use regex to extract process name, PID, and file path
|
||||
# handle.exe output format variations:
|
||||
# "ProcessName.exe pid: 1234 type: File C:\path\to\file"
|
||||
# "ProcessName.exe pid: 1234 user: DOMAIN\User type: File C:\path\to\file"
|
||||
$regex = "^(.+?)\s+pid:\s*(\d+)\s+.*?\s+type:\s+File\s+(.+?)\s*$"
|
||||
|
||||
$handleOutput.Split([Environment]::NewLine) | ForEach-Object {
|
||||
if ($_ -match $regex) {
|
||||
$processName = $matches[1].Trim()
|
||||
$processId = [int]$matches[2]
|
||||
$filePath = $matches[3].Trim()
|
||||
|
||||
# 지정된 디렉토리 경로에 포함되는 결과만 필터링
|
||||
if ($filePath.StartsWith($TargetDirectory, [System.StringComparison]::OrdinalIgnoreCase)) {
|
||||
# PSCustomObject를 생성
|
||||
$customObject = [PSCustomObject]@{
|
||||
ProcessName = $processName
|
||||
PID = $processId
|
||||
FilePath = $filePath
|
||||
}
|
||||
$foundProcesses += $customObject
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 결과 출력
|
||||
if ($foundProcesses.Count -gt 0) {
|
||||
Write-Host "`n[+] Found $($foundProcesses.Count) open file handles in '$TargetDirectory':"
|
||||
$foundProcesses | Sort-Object -Property ProcessName, FilePath | Format-Table -AutoSize
|
||||
} else {
|
||||
Write-Host "`n[-] No open file handles were found for the specified directory."
|
||||
}
|
||||
Reference in New Issue
Block a user