function Get-OpenFilesOnServers {
<#
.SYNOPSIS
Получает информацию об открытых файлах на SMB-шарах указанных серверов,
включая количество блокировок (Locks) и режим открытия (Open Mode).
.DESCRIPTION
Для каждого сервера из списка $Servers функция выполняет openfiles.exe
с ключами /query /fo CSV /v, преобразует вывод в объекты PowerShell
и возвращает сводную таблицу.
.PARAMETER Servers
Массив имён или IP-адресов серверов.
.EXAMPLE
Get-OpenFilesOnServers -Servers $Servers
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string[]]$Servers
)
$allOpenFiles = @()
foreach ($server in $Servers) {
Write-Verbose "Опрос сервера: $server"
try {
$result = Invoke-Command -ComputerName $server -ScriptBlock {
# openfiles.exe выводит CSV с заголовками на языке системы.
# Чтобы получить предсказуемые имена колонок, используем /nh
# (no header) и задаём заголовки самостоятельно.
$raw = openfiles /query /fo CSV /v /nh 2>$null
if (-not $raw) { return }
# Первая строка openfiles /nh содержит пустую строку или мусор,
# отфильтровываем её.
$dataLines = $raw | Where-Object { $_ -match '","' }
# Имена колонок в том порядке, в котором их выводит openfiles /v.
# Порядок соответствует: ID, Accessed By, Type, Open File, Locks, Open Mode
$headers = 'ID','AccessedBy','Type','OpenFile','Locks','OpenMode'
$dataLines |
ConvertFrom-Csv -Header $headers |
Select-Object @{Name='Server';Expression={$env:COMPUTERNAME}},
ID,
AccessedBy,
Type,
OpenFile,
Locks,
OpenMode
} -ErrorAction Stop
$allOpenFiles += $result
}
catch {
Write-Warning "Не удалось получить данные с сервера $server : $_"
}
}
if ($allOpenFiles.Count -gt 0) {
$allOpenFiles | Format-Table -AutoSize
}
else {
Write-Host "На указанных серверах открытых файлов не обнаружено."
}
}