Загрузка данных


# ============================================================
# Скрипт для поиска файлов на серверах, участвующих в DFS
# ============================================================
# Задайте корневой путь DFS в начале скрипта
$DFSroot = "\\mydep.corporate.ru\"

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# ---------- Функция получения списка серверов из DFS через WMI ----------
function Get-DFSServers {
    param([string]$RootPath)
    try {
        # Убираем завершающий слэш для сравнения
        $root = $RootPath.TrimEnd('\')
        # WMI-класс Win32_DFSTarget содержит информацию о целях DFS
        $targets = Get-WmiObject -Namespace "root\MicrosoftDFS" -Class Win32_DFSTarget -ErrorAction Stop
        # Фильтруем цели, относящиеся к нашему корню DFS
        $servers = $targets | Where-Object {
            $_.LinkName -like "$root*" -or $_.LinkName -like "$root\*"
        } | Select-Object -ExpandProperty ServerName -Unique
        return $servers
    }
    catch {
        [System.Windows.Forms.MessageBox]::Show("Ошибка при получении списка серверов DFS:`n$($_.Exception.Message)", "Ошибка", 'OK', 'Error')
        return @()
    }
}

# ---------- Функция получения списка общих ресурсов на сервере через CIM ----------
function Get-ServerShares {
    param([string]$ServerName)
    $shares = @()
    try {
        $cim = New-CimSession -ComputerName $ServerName -ErrorAction Stop
        $shares = Get-SmbShare -CimSession $cim -ErrorAction Stop |
                  Where-Object { $_.Name -notmatch '\$$' } |  # исключаем административные шары (C$, ADMIN$ и т.п.)
                  Select-Object -ExpandProperty Name
        Remove-CimSession -CimSession $cim -ErrorAction SilentlyContinue
    }
    catch {
        # Если не удалось подключиться, возвращаем пустой массив
    }
    return $shares
}

# ---------- Функция поиска файлов на всех серверах и шарах ----------
function Search-Files {
    param(
        [string[]]$Servers,
        [string]$Query,
        [System.Windows.Forms.ListView]$ListView
    )
    $ListView.Items.Clear()
    foreach ($server in $Servers) {
        $shares = Get-ServerShares -ServerName $server
        if (-not $shares) { continue }
        foreach ($share in $shares) {
            $unc = "\\$server\$share"
            try {
                # Поиск по маске (часть имени или пути)
                Get-ChildItem -Path $unc -Recurse -Force -ErrorAction SilentlyContinue |
                Where-Object { -not $_.PSIsContainer -and $_.FullName -like "*$Query*" } |
                ForEach-Object {
                    $item = New-Object System.Windows.Forms.ListViewItem($server)
                    $item.SubItems.Add($share) | Out-Null
                    $item.SubItems.Add($_.FullName) | Out-Null
                    $item.SubItems.Add($_.Name) | Out-Null
                    $ListView.Items.Add($item) | Out-Null
                    $ListView.Refresh()
                }
            }
            catch { }
        }
    }
}

# ---------- Создание графического интерфейса ----------
$form = New-Object System.Windows.Forms.Form
$form.Text = "Поиск файлов в DFS"
$form.Size = New-Object System.Drawing.Size(900, 600)
$form.StartPosition = "CenterScreen"

# Поле ввода поискового запроса
$label = New-Object System.Windows.Forms.Label
$label.Text = "Введите имя файла, часть пути или маску:"
$label.Location = New-Object System.Drawing.Point(10, 15)
$label.Size = New-Object System.Drawing.Size(300, 20)
$form.Controls.Add($label)

$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10, 40)
$textBox.Size = New-Object System.Drawing.Size(500, 25)
$form.Controls.Add($textBox)

# Кнопка поиска
$button = New-Object System.Windows.Forms.Button
$button.Text = "Найти"
$button.Location = New-Object System.Drawing.Point(520, 38)
$button.Size = New-Object System.Drawing.Size(100, 28)
$form.Controls.Add($button)

# Таблица результатов
$listView = New-Object System.Windows.Forms.ListView
$listView.Location = New-Object System.Drawing.Point(10, 80)
$listView.Size = New-Object System.Drawing.Size(860, 470)
$listView.View = "Details"
$listView.FullRowSelect = $true
$listView.GridLines = $true
$listView.Columns.Add("Сервер", 150) | Out-Null
$listView.Columns.Add("Шара", 150) | Out-Null
$listView.Columns.Add("Полный путь", 400) | Out-Null
$listView.Columns.Add("Имя файла", 150) | Out-Null
$form.Controls.Add($listView)

# Обработчик нажатия кнопки
$button.Add_Click({
    $query = $textBox.Text.Trim()
    if ([string]::IsNullOrEmpty($query)) {
        [System.Windows.Forms.MessageBox]::Show("Введите строку для поиска.", "Предупреждение", 'OK', 'Warning')
        return
    }
    $button.Enabled = $false
    $form.Cursor = [System.Windows.Forms.Cursors]::WaitCursor
    try {
        $servers = Get-DFSServers -RootPath $DFSroot
        if ($servers.Count -eq 0) {
            [System.Windows.Forms.MessageBox]::Show("Не найдено ни одного сервера в указанном DFS-корне.", "Информация", 'OK', 'Information')
            return
        }
        Search-Files -Servers $servers -Query $query -ListView $listView
    }
    finally {
        $button.Enabled = $true
        $form.Cursor = [System.Windows.Forms.Cursors]::Default
    }
})

# Запуск формы
[void]$form.ShowDialog()