PowerShell-Tools/NTFS-ACL-Finder-ng.ps1
2025-05-14 11:56:59 +02:00

209 lines
7.2 KiB
PowerShell

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = "Haruna's NTFS-ACL Finder"
$form.Size = New-Object System.Drawing.Size(700, 600)
$form.StartPosition = "CenterScreen"
$global:CancelSearch = $false
$global:Results = @()
$labelUser = New-Object System.Windows.Forms.Label
$labelUser.Text = "Gruppe aus AD auswählen (OU=ZFD):"
$labelUser.Location = New-Object System.Drawing.Point(10, 20)
$labelUser.Size = New-Object System.Drawing.Size(680, 20)
$form.Controls.Add($labelUser)
$comboBoxGroups = New-Object System.Windows.Forms.ComboBox
$comboBoxGroups.Location = New-Object System.Drawing.Point(10, 45)
$comboBoxGroups.Size = New-Object System.Drawing.Size(660, 20)
$comboBoxGroups.AutoCompleteMode = 'SuggestAppend'
$comboBoxGroups.AutoCompleteSource = 'ListItems'
$comboBoxGroups.Sorted = $true
$comboBoxGroups.DropDownStyle = 'DropDownList'
$form.Controls.Add($comboBoxGroups)
function Load-ADGroups {
try {
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectClass=group)(distinguishedName=*))"
$searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://OU=ZFD,DC=zfd,DC=forumzfd,DC=de")
$searcher.PageSize = 1000
$searcher.PropertiesToLoad.Add("cn") | Out-Null
$results = $searcher.FindAll()
$groupNames = @()
foreach ($result in $results) {
$groupNames += $result.Properties["cn"][0]
}
$groupNames = $groupNames | Sort-Object
foreach ($name in $groupNames) {
$comboBoxGroups.Items.Add($name) | Out-Null
}
} catch {
[System.Windows.Forms.MessageBox]::Show("Fehler beim Laden der Gruppen: $_", "Fehler")
}
}
Load-ADGroups
$buttonBrowse = New-Object System.Windows.Forms.Button
$buttonBrowse.Text = "Pfad wählen"
$buttonBrowse.Location = New-Object System.Drawing.Point(10, 75)
$form.Controls.Add($buttonBrowse)
$labelPath = New-Object System.Windows.Forms.Label
$labelPath.Text = "Kein Pfad ausgewählt"
$labelPath.Location = New-Object System.Drawing.Point(110, 80)
$labelPath.Size = New-Object System.Drawing.Size(560, 20)
$form.Controls.Add($labelPath)
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$buttonBrowse.Add_Click({
if ($folderBrowser.ShowDialog() -eq "OK") {
$labelPath.Text = $folderBrowser.SelectedPath
}
})
$labelDepth = New-Object System.Windows.Forms.Label
$labelDepth.Text = "Maximale Suchtiefe (0 = unbegrenzt):"
$labelDepth.Location = New-Object System.Drawing.Point(10, 110)
$labelDepth.Size = New-Object System.Drawing.Size(250, 20)
$form.Controls.Add($labelDepth)
$textBoxDepth = New-Object System.Windows.Forms.TextBox
$textBoxDepth.Text = "0"
$textBoxDepth.Location = New-Object System.Drawing.Point(270, 110)
$textBoxDepth.Size = New-Object System.Drawing.Size(50, 20)
$form.Controls.Add($textBoxDepth)
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Text = "Bereit."
$statusLabel.Location = New-Object System.Drawing.Point(10, 140)
$statusLabel.Size = New-Object System.Drawing.Size(680, 20)
$form.Controls.Add($statusLabel)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10, 170)
$listBox.Size = New-Object System.Drawing.Size(660, 300)
$listBox.HorizontalScrollbar = $true
$form.Controls.Add($listBox)
$buttonStart = New-Object System.Windows.Forms.Button
$buttonStart.Text = "Suche starten"
$buttonStart.Location = New-Object System.Drawing.Point(10, 490)
$form.Controls.Add($buttonStart)
$buttonCancel = New-Object System.Windows.Forms.Button
$buttonCancel.Text = "Abbrechen"
$buttonCancel.Location = New-Object System.Drawing.Point(130, 490)
$buttonCancel.Enabled = $false
$form.Controls.Add($buttonCancel)
$buttonExport = New-Object System.Windows.Forms.Button
$buttonExport.Text = "Exportieren als CSV"
$buttonExport.Location = New-Object System.Drawing.Point(250, 490)
$form.Controls.Add($buttonExport)
function Search-Folder {
param (
[string]$path,
[string]$searchTerm,
[int]$depth,
[int]$maxDepth
)
if ($global:CancelSearch) { return }
if ($maxDepth -gt 0 -and $depth -ge $maxDepth) { return }
$statusLabel.Text = "Verarbeite: $path"
[System.Windows.Forms.Application]::DoEvents()
try {
$items = Get-ChildItem -LiteralPath $path -Force -ErrorAction SilentlyContinue
foreach ($item in $items) {
if ($global:CancelSearch) { return }
$statusLabel.Text = "Verarbeite: $($item.FullName)"
[System.Windows.Forms.Application]::DoEvents()
try {
$acl = Get-Acl $item.FullName
foreach ($entry in $acl.Access) {
if ($entry.IdentityReference -match $searchTerm) {
$result = [PSCustomObject]@{
Pfad = $item.FullName
BenutzerOderGruppe = $entry.IdentityReference.ToString()
}
$global:Results += $result
$listBox.Items.Add("$($result.Pfad)$($result.BenutzerOderGruppe)")
}
}
} catch {}
if ($item.PSIsContainer) {
Search-Folder -path $item.FullName -searchTerm $searchTerm -depth ($depth + 1) -maxDepth $maxDepth
}
}
} catch {}
}
$buttonStart.Add_Click({
$listBox.Items.Clear()
$global:Results = @()
$global:CancelSearch = $false
$statusLabel.Text = "Suche gestartet..."
$buttonCancel.Enabled = $true
$searchTerm = $comboBoxGroups.SelectedItem
$startPath = $labelPath.Text
$maxDepth = 0
if (-not [int]::TryParse($textBoxDepth.Text.Trim(), [ref]$maxDepth)) {
$maxDepth = 0
}
if (-not (Test-Path $startPath)) {
[System.Windows.Forms.MessageBox]::Show("Ungültiger Pfad!", "Fehler")
return
}
if ([string]::IsNullOrWhiteSpace($searchTerm)) {
[System.Windows.Forms.MessageBox]::Show("Bitte eine Gruppe auswählen.", "Hinweis")
return
}
Search-Folder -path $startPath -searchTerm $searchTerm -depth 0 -maxDepth $maxDepth
if ($global:CancelSearch) {
$statusLabel.Text = "Suche abgebrochen."
} else {
$statusLabel.Text = "Suche abgeschlossen."
}
$buttonCancel.Enabled = $false
})
$buttonCancel.Add_Click({
$global:CancelSearch = $true
$statusLabel.Text = "Abbruch angefordert..."
$buttonCancel.Enabled = $false
})
$buttonExport.Add_Click({
if ($global:Results.Count -eq 0) {
[System.Windows.Forms.MessageBox]::Show("Keine Ergebnisse zum Exportieren.", "Hinweis")
return
}
$saveDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveDialog.Filter = "CSV-Dateien (*.csv)|*.csv"
$saveDialog.Title = "Speichern unter..."
$saveDialog.FileName = "ACL-Ergebnisse.csv"
if ($saveDialog.ShowDialog() -eq "OK") {
$global:Results | Export-Csv -Path $saveDialog.FileName -NoTypeInformation -Encoding UTF8
[System.Windows.Forms.MessageBox]::Show("Ergebnisse wurden gespeichert.", "Export erfolgreich")
}
})
$form.Topmost = $true
[void]$form.ShowDialog()