Загрузка данных
# ============================================================
# Скрипт для поиска файлов на серверах, участвующих в DFS
# ============================================================
$DFSroot = "\\mydep.corporate.ru\"
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.DirectoryServices
# ---------- Получение серверов DFS через Active Directory ----------
function Get-DFSServersFromAD {
param([string]$RootPath)
try {
# Разбираем корень DFS: \\mydep.corporate.ru\
$rootTrim = $RootPath.TrimEnd('\')
if ($rootTrim.StartsWith('\\')) { $rootTrim = $rootTrim.Substring(2) }
$parts = $rootTrim.Split('\')
$nsFull = $parts[0] # mydep.corporate.ru
if ($nsFull -match '^([^.]+)\.(.+)$') {
$nsName = $Matches[1] # mydep
$domain = $Matches[2] # corporate.ru
} else {
$nsName = $nsFull
$domain = $env:USERDNSDOMAIN
}
$domainDN = ($domain.Split('.') | ForEach-Object { "DC=$_" }) -join ','
$searchBase = "CN=Dfs-Configuration,CN=System,$domainDN"
# 1. Находим объект пространства имён (msDFS-Namespacev2) по cn
$nsSearcher = New-Object System.DirectoryServices.DirectorySearcher
$nsSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$searchBase")
$nsSearcher.Filter = "(cn=$nsName)"
$nsSearcher.PropertiesToLoad.Add("objectGUID") | Out-Null
$nsResult = $nsSearcher.FindOne()
if (-not $nsResult) { return @() }
$nsGuid = $nsResult.Properties["objectguid"][0]
# 2. Ищем все ссылки (msDFS-Linkv2) и фильтруем по GUID пространства имён
$linkSearcher = New-Object System.DirectoryServices.DirectorySearcher
$linkSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$searchBase")
$linkSearcher.Filter = "(objectClass=msDFS-Linkv2)"
$linkSearcher.PropertiesToLoad.Add("msDFS-TargetListv2") | Out-Null
$linkSearcher.PropertiesToLoad.Add("msDFS-NamespaceIdentityGUIDv2") | Out-Null
$servers = @{}
foreach ($link in $linkSearcher.FindAll()) {
$linkGuid = $link.Properties["msdfs-namespaceidentityguidv2"][0]
if ($linkGuid -ne $nsGuid) { continue }
$targets = $link.Properties["msdfs-targetlistv2"]
foreach ($target in $targets) {
if ($target -match '^\\\\?([^\\]+)') {
$servers[$Matches[1]] = $true
}
}
}
return $servers.Keys
}
catch {
[System.Windows.Forms.MessageBox]::Show("Ошибка при чтении DFS из AD:`n$($_.Exception.Message)", "Ошибка", 'OK', 'Error')
return @()
}
}
# ---------- Получение списка общих ресурсов на сервере ----------
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 '\$$' } |
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-DFSServersFromAD -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()