336 lines
11 KiB
PowerShell
336 lines
11 KiB
PowerShell
#Requires -Version 5.1
|
|
param(
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$Path
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
function Get-Config {
|
|
$configPaths = @(
|
|
"$env:APPDATA\FreigabeKontextmenue\config.json",
|
|
"$env:ProgramData\FreigabeKontextmenue\config.json"
|
|
)
|
|
|
|
foreach ($configPath in $configPaths) {
|
|
if (Test-Path $configPath) {
|
|
return Get-Content $configPath -Raw | ConvertFrom-Json
|
|
}
|
|
}
|
|
|
|
throw "Konfiguration nicht gefunden. Bitte zuerst installieren!"
|
|
}
|
|
|
|
function Get-UNCPath {
|
|
param([string]$LocalPath)
|
|
|
|
$drive = Split-Path -Path $LocalPath -Qualifier
|
|
$driveLetter = $drive.TrimEnd(':')
|
|
|
|
$netUse = net use 2>$null | Where-Object { $_ -match "^\s*\w*\s+$driveLetter`:" }
|
|
|
|
if ($netUse) {
|
|
$parts = $netUse -split '\s+'
|
|
foreach ($part in $parts) {
|
|
if ($part -match '^\\\\') {
|
|
$uncRoot = $part
|
|
$relativePath = $LocalPath.Substring($drive.Length)
|
|
return Join-Path $uncRoot $relativePath
|
|
}
|
|
}
|
|
}
|
|
|
|
$psDrive = Get-PSDrive -Name $driveLetter -ErrorAction SilentlyContinue
|
|
if ($psDrive -and $psDrive.DisplayRoot) {
|
|
$relativePath = $LocalPath.Substring($drive.Length)
|
|
return Join-Path $psDrive.DisplayRoot $relativePath
|
|
}
|
|
|
|
$wmiDrive = Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='$drive'" -ErrorAction SilentlyContinue
|
|
if ($wmiDrive -and $wmiDrive.ProviderName) {
|
|
$relativePath = $LocalPath.Substring($drive.Length)
|
|
return Join-Path $wmiDrive.ProviderName $relativePath
|
|
}
|
|
|
|
$computerName = $env:COMPUTERNAME
|
|
$adminShare = "\\$computerName\$driveLetter`$"
|
|
$relativePath = $LocalPath.Substring($drive.Length)
|
|
return Join-Path $adminShare $relativePath
|
|
}
|
|
|
|
function Get-DomainUsers {
|
|
$users = @()
|
|
|
|
try {
|
|
$searcher = [adsisearcher]"(&(objectCategory=person)(objectClass=user))"
|
|
$searcher.PageSize = 1000
|
|
$searcher.PropertiesToLoad.AddRange(@("samaccountname", "displayname", "mail"))
|
|
|
|
# NetBIOS-Domänennamen ermitteln
|
|
$rootDSE = [ADSI]"LDAP://RootDSE"
|
|
$domainDN = $rootDSE.defaultNamingContext
|
|
$domainSearcher = [adsisearcher]"(&(objectClass=domain))"
|
|
$domainSearcher.SearchRoot = [ADSI]"LDAP://$domainDN"
|
|
$domainResult = $domainSearcher.FindOne()
|
|
$netbiosDomain = $null
|
|
|
|
# NetBIOS-Name aus Partitions holen
|
|
$configDN = $rootDSE.configurationNamingContext
|
|
$partSearcher = [adsisearcher]"(&(objectClass=crossRef)(nCName=$domainDN))"
|
|
$partSearcher.SearchRoot = [ADSI]"LDAP://CN=Partitions,$configDN"
|
|
$partResult = $partSearcher.FindOne()
|
|
if ($partResult -and $partResult.Properties["netbiosname"]) {
|
|
$netbiosDomain = $partResult.Properties["netbiosname"][0]
|
|
}
|
|
|
|
# Fallback: Aus USERDOMAIN
|
|
if (-not $netbiosDomain) {
|
|
$netbiosDomain = $env:USERDOMAIN
|
|
}
|
|
|
|
$results = $searcher.FindAll()
|
|
foreach ($result in $results) {
|
|
$samAccount = $result.Properties["samaccountname"][0]
|
|
$displayName = if ($result.Properties["displayname"]) { $result.Properties["displayname"][0] } else { $samAccount }
|
|
$qualifiedName = "$netbiosDomain\$samAccount"
|
|
|
|
$users += [PSCustomObject]@{
|
|
SamAccountName = $samAccount
|
|
DisplayName = $displayName
|
|
FullName = "$displayName ($samAccount)"
|
|
QualifiedName = $qualifiedName
|
|
Domain = $netbiosDomain
|
|
IsLocal = $false
|
|
}
|
|
}
|
|
} catch {
|
|
# Fallback auf lokale Benutzer (kein AD verfügbar)
|
|
$localUsers = Get-LocalUser -ErrorAction SilentlyContinue | Where-Object { $_.Enabled }
|
|
foreach ($user in $localUsers) {
|
|
$users += [PSCustomObject]@{
|
|
SamAccountName = $user.Name
|
|
DisplayName = if ($user.FullName) { $user.FullName } else { $user.Name }
|
|
FullName = if ($user.FullName) { "$($user.FullName) ($($user.Name))" } else { $user.Name }
|
|
QualifiedName = "$env:COMPUTERNAME\$($user.Name)"
|
|
Domain = $env:COMPUTERNAME
|
|
IsLocal = $true
|
|
}
|
|
}
|
|
}
|
|
|
|
return $users | Sort-Object DisplayName
|
|
}
|
|
|
|
function Show-UserSelectionDialog {
|
|
param([array]$Users)
|
|
|
|
$form = New-Object System.Windows.Forms.Form
|
|
$form.Text = "Benutzer auswählen - Freigabe"
|
|
$form.Size = New-Object System.Drawing.Size(450, 500)
|
|
$form.StartPosition = "CenterScreen"
|
|
$form.FormBorderStyle = "FixedDialog"
|
|
$form.MaximizeBox = $false
|
|
|
|
$lblSearch = New-Object System.Windows.Forms.Label
|
|
$lblSearch.Text = "Suchen:"
|
|
$lblSearch.Location = New-Object System.Drawing.Point(10, 15)
|
|
$lblSearch.Size = New-Object System.Drawing.Size(50, 20)
|
|
$form.Controls.Add($lblSearch)
|
|
|
|
$txtSearch = New-Object System.Windows.Forms.TextBox
|
|
$txtSearch.Location = New-Object System.Drawing.Point(65, 12)
|
|
$txtSearch.Size = New-Object System.Drawing.Size(355, 20)
|
|
$form.Controls.Add($txtSearch)
|
|
|
|
$listBox = New-Object System.Windows.Forms.ListBox
|
|
$listBox.Location = New-Object System.Drawing.Point(10, 45)
|
|
$listBox.Size = New-Object System.Drawing.Size(410, 360)
|
|
$listBox.Font = New-Object System.Drawing.Font("Segoe UI", 10)
|
|
$form.Controls.Add($listBox)
|
|
|
|
$script:allUsers = $Users
|
|
foreach ($user in $Users) {
|
|
$listBox.Items.Add($user.FullName) | Out-Null
|
|
}
|
|
|
|
$txtSearch.Add_TextChanged({
|
|
$searchText = $txtSearch.Text.ToLower()
|
|
$listBox.Items.Clear()
|
|
foreach ($user in $script:allUsers) {
|
|
if ($user.FullName.ToLower().Contains($searchText) -or
|
|
$user.SamAccountName.ToLower().Contains($searchText)) {
|
|
$listBox.Items.Add($user.FullName) | Out-Null
|
|
}
|
|
}
|
|
})
|
|
|
|
$okBtn = New-Object System.Windows.Forms.Button
|
|
$okBtn.Text = "Freigeben"
|
|
$okBtn.Location = New-Object System.Drawing.Point(240, 420)
|
|
$okBtn.Size = New-Object System.Drawing.Size(85, 30)
|
|
$okBtn.Enabled = $false
|
|
$okBtn.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
|
$form.AcceptButton = $okBtn
|
|
$form.Controls.Add($okBtn)
|
|
|
|
$cancelBtn = New-Object System.Windows.Forms.Button
|
|
$cancelBtn.Text = "Abbrechen"
|
|
$cancelBtn.Location = New-Object System.Drawing.Point(335, 420)
|
|
$cancelBtn.Size = New-Object System.Drawing.Size(85, 30)
|
|
$cancelBtn.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
|
|
$form.CancelButton = $cancelBtn
|
|
$form.Controls.Add($cancelBtn)
|
|
|
|
$listBox.Add_SelectedIndexChanged({
|
|
$okBtn.Enabled = $listBox.SelectedIndex -ge 0
|
|
})
|
|
|
|
$listBox.Add_DoubleClick({
|
|
if ($listBox.SelectedIndex -ge 0) {
|
|
$form.DialogResult = [System.Windows.Forms.DialogResult]::OK
|
|
$form.Close()
|
|
}
|
|
})
|
|
|
|
$script:selectedUser = $null
|
|
|
|
if ($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK -and $listBox.SelectedIndex -ge 0) {
|
|
$selectedText = $listBox.SelectedItem
|
|
$script:selectedUser = $script:allUsers | Where-Object { $_.FullName -eq $selectedText } | Select-Object -First 1
|
|
}
|
|
|
|
return $script:selectedUser
|
|
}
|
|
|
|
function Add-FreigabePermission {
|
|
param(
|
|
[string]$TargetPath,
|
|
[string]$QualifiedUserName
|
|
)
|
|
|
|
try {
|
|
$acl = Get-Acl -Path $TargetPath
|
|
|
|
$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
|
|
$inheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
|
|
$propagation = [System.Security.AccessControl.PropagationFlags]::None
|
|
$type = [System.Security.AccessControl.AccessControlType]::Allow
|
|
|
|
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($QualifiedUserName, $rights, $inheritance, $propagation, $type)
|
|
$acl.AddAccessRule($rule)
|
|
Set-Acl -Path $TargetPath -AclObject $acl
|
|
|
|
return $true
|
|
} catch {
|
|
throw "Fehler beim Setzen der Berechtigungen: $_"
|
|
}
|
|
}
|
|
|
|
function Create-Shortcut {
|
|
param(
|
|
[string]$TargetPath,
|
|
[string]$ShortcutPath
|
|
)
|
|
|
|
$shell = New-Object -ComObject WScript.Shell
|
|
$shortcut = $shell.CreateShortcut($ShortcutPath)
|
|
$shortcut.TargetPath = $TargetPath
|
|
$shortcut.Save()
|
|
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
|
|
}
|
|
|
|
function Save-FreigabeInfo {
|
|
param(
|
|
[string]$TargetPath,
|
|
[string]$UserName
|
|
)
|
|
|
|
$metaDir = if (Test-Path "$env:ProgramData\FreigabeKontextmenue") {
|
|
"$env:ProgramData\FreigabeKontextmenue\meta"
|
|
} else {
|
|
"$env:APPDATA\FreigabeKontextmenue\meta"
|
|
}
|
|
|
|
if (-not (Test-Path $metaDir)) {
|
|
New-Item -Path $metaDir -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
$pathHash = [System.BitConverter]::ToString([System.Security.Cryptography.MD5]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TargetPath))).Replace("-","")
|
|
$metaFile = Join-Path $metaDir "$pathHash.json"
|
|
|
|
$meta = @{
|
|
TargetPath = $TargetPath
|
|
Users = @()
|
|
}
|
|
|
|
if (Test-Path $metaFile) {
|
|
$existing = Get-Content $metaFile -Raw | ConvertFrom-Json
|
|
$meta.Users = @($existing.Users)
|
|
}
|
|
|
|
if ($UserName -notin $meta.Users) {
|
|
$meta.Users += $UserName
|
|
}
|
|
|
|
$meta | ConvertTo-Json | Set-Content -Path $metaFile -Encoding UTF8
|
|
}
|
|
|
|
try {
|
|
$config = Get-Config
|
|
$basePath = $config.LinkBasePath
|
|
|
|
if (-not (Test-Path $Path)) {
|
|
throw "Der Pfad existiert nicht: $Path"
|
|
}
|
|
|
|
$users = Get-DomainUsers
|
|
if ($users.Count -eq 0) {
|
|
throw "Keine Benutzer gefunden!"
|
|
}
|
|
|
|
$selectedUser = Show-UserSelectionDialog -Users $users
|
|
if (-not $selectedUser) {
|
|
exit 0
|
|
}
|
|
|
|
$userName = $selectedUser.SamAccountName
|
|
$userFolder = Join-Path $basePath $userName
|
|
|
|
if (-not (Test-Path $userFolder)) {
|
|
New-Item -Path $userFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
$uncPath = Get-UNCPath -LocalPath $Path
|
|
$itemName = Split-Path -Path $Path -Leaf
|
|
$shortcutPath = Join-Path $userFolder "$itemName.lnk"
|
|
|
|
$counter = 1
|
|
while (Test-Path $shortcutPath) {
|
|
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($itemName)
|
|
$extension = [System.IO.Path]::GetExtension($itemName)
|
|
$shortcutPath = Join-Path $userFolder "$baseName ($counter)$extension.lnk"
|
|
$counter++
|
|
}
|
|
|
|
Create-Shortcut -TargetPath $uncPath -ShortcutPath $shortcutPath
|
|
Add-FreigabePermission -TargetPath $Path -QualifiedUserName $selectedUser.QualifiedName
|
|
Save-FreigabeInfo -TargetPath $Path -UserName $selectedUser.QualifiedName
|
|
|
|
[System.Windows.Forms.MessageBox]::Show(
|
|
"Freigabe erfolgreich erstellt!`n`nBenutzer: $($selectedUser.DisplayName)`nVerknüpfung: $shortcutPath`nUNC-Pfad: $uncPath",
|
|
"Freigabe erfolgreich",
|
|
[System.Windows.Forms.MessageBoxButtons]::OK,
|
|
[System.Windows.Forms.MessageBoxIcon]::Information
|
|
)
|
|
|
|
} catch {
|
|
[System.Windows.Forms.MessageBox]::Show(
|
|
"Fehler: $($_.Exception.Message)",
|
|
"Fehler bei Freigabe",
|
|
[System.Windows.Forms.MessageBoxButtons]::OK,
|
|
[System.Windows.Forms.MessageBoxIcon]::Error
|
|
)
|
|
exit 1
|
|
} |