From 760e875e480b4e108cf2ff4253afb64624054001 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 17 Dec 2025 08:41:50 +0100 Subject: [PATCH] first version --- Freigabe-Entfernen.ps1 | 277 +++++++++++++++++++++++++ Freigabe-Hinzufuegen.ps1 | 336 +++++++++++++++++++++++++++++++ Install-FreigabeKontextmenue.ps1 | 294 +++++++++++++++++++++++++++ README.md | 2 +- 4 files changed, 908 insertions(+), 1 deletion(-) create mode 100644 Freigabe-Entfernen.ps1 create mode 100644 Freigabe-Hinzufuegen.ps1 create mode 100644 Install-FreigabeKontextmenue.ps1 diff --git a/Freigabe-Entfernen.ps1 b/Freigabe-Entfernen.ps1 new file mode 100644 index 0000000..5098530 --- /dev/null +++ b/Freigabe-Entfernen.ps1 @@ -0,0 +1,277 @@ +#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-FreigabeInfo { + param([string]$TargetPath) + + $metaDirs = @( + "$env:ProgramData\FreigabeKontextmenue\meta", + "$env:APPDATA\FreigabeKontextmenue\meta" + ) + + $pathHash = [System.BitConverter]::ToString([System.Security.Cryptography.MD5]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TargetPath))).Replace("-","") + + foreach ($metaDir in $metaDirs) { + $metaFile = Join-Path $metaDir "$pathHash.json" + if (Test-Path $metaFile) { + return Get-Content $metaFile -Raw | ConvertFrom-Json + } + } + + return $null +} + +function Save-FreigabeInfo { + param( + [string]$TargetPath, + [array]$Users + ) + + $metaDir = if (Test-Path "$env:ProgramData\FreigabeKontextmenue") { + "$env:ProgramData\FreigabeKontextmenue\meta" + } else { + "$env:APPDATA\FreigabeKontextmenue\meta" + } + + $pathHash = [System.BitConverter]::ToString([System.Security.Cryptography.MD5]::Create().ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TargetPath))).Replace("-","") + $metaFile = Join-Path $metaDir "$pathHash.json" + + if ($Users.Count -eq 0) { + if (Test-Path $metaFile) { + Remove-Item $metaFile -Force + } + } else { + $meta = @{ + TargetPath = $TargetPath + Users = $Users + } + $meta | ConvertTo-Json | Set-Content -Path $metaFile -Encoding UTF8 + } +} + +function Show-UserRemoveDialog { + param([array]$Users) + + $form = New-Object System.Windows.Forms.Form + $form.Text = "Freigabe entfernen - Benutzer auswählen" + $form.Size = New-Object System.Drawing.Size(400, 400) + $form.StartPosition = "CenterScreen" + $form.FormBorderStyle = "FixedDialog" + $form.MaximizeBox = $false + + $label = New-Object System.Windows.Forms.Label + $label.Text = "Freigabe entfernen für folgende Benutzer:" + $label.Location = New-Object System.Drawing.Point(10, 15) + $label.Size = New-Object System.Drawing.Size(360, 20) + $form.Controls.Add($label) + + $checkedListBox = New-Object System.Windows.Forms.CheckedListBox + $checkedListBox.Location = New-Object System.Drawing.Point(10, 40) + $checkedListBox.Size = New-Object System.Drawing.Size(360, 260) + $checkedListBox.Font = New-Object System.Drawing.Font("Segoe UI", 10) + $checkedListBox.CheckOnClick = $true + $form.Controls.Add($checkedListBox) + + foreach ($user in $Users) { + $checkedListBox.Items.Add($user) | Out-Null + } + + $selectAllBtn = New-Object System.Windows.Forms.Button + $selectAllBtn.Text = "Alle auswählen" + $selectAllBtn.Location = New-Object System.Drawing.Point(10, 310) + $selectAllBtn.Size = New-Object System.Drawing.Size(100, 25) + $selectAllBtn.Add_Click({ + for ($i = 0; $i -lt $checkedListBox.Items.Count; $i++) { + $checkedListBox.SetItemChecked($i, $true) + } + }) + $form.Controls.Add($selectAllBtn) + + $okBtn = New-Object System.Windows.Forms.Button + $okBtn.Text = "Entfernen" + $okBtn.Location = New-Object System.Drawing.Point(190, 310) + $okBtn.Size = New-Object System.Drawing.Size(85, 30) + $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(285, 310) + $cancelBtn.Size = New-Object System.Drawing.Size(85, 30) + $cancelBtn.DialogResult = [System.Windows.Forms.DialogResult]::Cancel + $form.CancelButton = $cancelBtn + $form.Controls.Add($cancelBtn) + + $script:selectedUsers = @() + + if ($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { + $script:selectedUsers = @($checkedListBox.CheckedItems) + } + + return $script:selectedUsers +} + +function Remove-FreigabePermission { + param( + [string]$TargetPath, + [string]$QualifiedUserName + ) + + try { + $acl = Get-Acl -Path $TargetPath + + $rulesToRemove = $acl.Access | Where-Object { + $_.IdentityReference.Value -eq $QualifiedUserName + } + + foreach ($rule in $rulesToRemove) { + $acl.RemoveAccessRule($rule) | Out-Null + } + + Set-Acl -Path $TargetPath -AclObject $acl + return $true + } catch { + Write-Warning "Fehler beim Entfernen der Berechtigung für $QualifiedUserName : $_" + return $false + } +} + +function Remove-UserShortcut { + param( + [string]$TargetPath, + [string]$QualifiedUserName, + [string]$BasePath + ) + + # SamAccountName aus QualifiedName extrahieren (für Ordnerpfad) + $samAccountName = if ($QualifiedUserName -match '\\') { + $QualifiedUserName.Split('\')[1] + } else { + $QualifiedUserName + } + + $userFolder = Join-Path $BasePath $samAccountName + + if (-not (Test-Path $userFolder)) { + return + } + + $shortcuts = Get-ChildItem -Path $userFolder -Filter "*.lnk" -ErrorAction SilentlyContinue + $shell = New-Object -ComObject WScript.Shell + + foreach ($shortcut in $shortcuts) { + try { + $lnk = $shell.CreateShortcut($shortcut.FullName) + $shortcutTarget = $lnk.TargetPath + + $targetNormalized = $TargetPath.TrimEnd('\').ToLower() + $shortcutTargetNormalized = $shortcutTarget.TrimEnd('\').ToLower() + + $targetName = Split-Path $TargetPath -Leaf + $shortcutTargetName = Split-Path $shortcutTarget -Leaf + + if ($shortcutTargetNormalized -eq $targetNormalized -or + ($targetName.ToLower() -eq $shortcutTargetName.ToLower() -and + $shortcutTarget -match [regex]::Escape($targetName))) { + Remove-Item -Path $shortcut.FullName -Force + } + } catch { + Write-Warning "Fehler beim Prüfen der Verknüpfung: $($shortcut.Name)" + } + } + + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null + + $remainingItems = Get-ChildItem -Path $userFolder -ErrorAction SilentlyContinue + if ($remainingItems.Count -eq 0) { + Remove-Item -Path $userFolder -Force -ErrorAction SilentlyContinue + } +} + +try { + $config = Get-Config + $basePath = $config.LinkBasePath + + if (-not (Test-Path $Path)) { + throw "Der Pfad existiert nicht: $Path" + } + + $freigabeInfo = Get-FreigabeInfo -TargetPath $Path + + if (-not $freigabeInfo -or $freigabeInfo.Users.Count -eq 0) { + [System.Windows.Forms.MessageBox]::Show( + "Für dieses Element wurden keine Freigaben über das Kontextmenü erstellt.", + "Keine Freigaben", + [System.Windows.Forms.MessageBoxButtons]::OK, + [System.Windows.Forms.MessageBoxIcon]::Information + ) + exit 0 + } + + $usersToRemove = Show-UserRemoveDialog -Users $freigabeInfo.Users + + if ($usersToRemove.Count -eq 0) { + exit 0 + } + + $removedUsers = @() + $errors = @() + + foreach ($qualifiedUserName in $usersToRemove) { + try { + Remove-FreigabePermission -TargetPath $Path -QualifiedUserName $qualifiedUserName + Remove-UserShortcut -TargetPath $Path -QualifiedUserName $qualifiedUserName -BasePath $basePath + $removedUsers += $qualifiedUserName + } catch { + $errors += "Fehler bei $qualifiedUserName : $_" + } + } + + $remainingUsers = @($freigabeInfo.Users | Where-Object { $_ -notin $removedUsers }) + Save-FreigabeInfo -TargetPath $Path -Users $remainingUsers + + $message = "Freigaben entfernt für:`n" + ($removedUsers -join "`n") + + if ($errors.Count -gt 0) { + $message += "`n`nFehler:`n" + ($errors -join "`n") + } + + [System.Windows.Forms.MessageBox]::Show( + $message, + "Freigaben entfernt", + [System.Windows.Forms.MessageBoxButtons]::OK, + $(if ($errors.Count -gt 0) { [System.Windows.Forms.MessageBoxIcon]::Warning } else { [System.Windows.Forms.MessageBoxIcon]::Information }) + ) + +} catch { + [System.Windows.Forms.MessageBox]::Show( + "Fehler: $($_.Exception.Message)", + "Fehler", + [System.Windows.Forms.MessageBoxButtons]::OK, + [System.Windows.Forms.MessageBoxIcon]::Error + ) + exit 1 +} diff --git a/Freigabe-Hinzufuegen.ps1 b/Freigabe-Hinzufuegen.ps1 new file mode 100644 index 0000000..4528567 --- /dev/null +++ b/Freigabe-Hinzufuegen.ps1 @@ -0,0 +1,336 @@ +#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 $qualifiedName + Save-FreigabeInfo -TargetPath $Path -UserName $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 +} \ No newline at end of file diff --git a/Install-FreigabeKontextmenue.ps1 b/Install-FreigabeKontextmenue.ps1 new file mode 100644 index 0000000..a49baed --- /dev/null +++ b/Install-FreigabeKontextmenue.ps1 @@ -0,0 +1,294 @@ +#Requires -Version 5.1 +<# +.SYNOPSIS + Installiert/Deinstalliert Kontextmenü-Einträge für Datei-/Ordnerfreigaben +.DESCRIPTION + Erstellt Kontextmenü-Einträge "Freigeben für Mitarbeiter" und "Freigabe entfernen" +.PARAMETER Install + Installiert die Kontextmenü-Einträge +.PARAMETER Uninstall + Entfernt die Kontextmenü-Einträge (Freigaben bleiben erhalten) +.PARAMETER AllUsers + Installation für alle Benutzer (erfordert Admin-Rechte) +.PARAMETER CurrentUser + Installation nur für aktuellen Benutzer +.PARAMETER LinkBasePath + Stammverzeichnis für Benutzer-Verknüpfungsordner +#> + +param( + [switch]$Install, + [switch]$Uninstall, + [switch]$AllUsers, + [switch]$CurrentUser, + [string]$LinkBasePath +) + +$ErrorActionPreference = "Stop" + +function Test-Administrator { + $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() + $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) + return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +} + +function Get-ScriptDirectory { + return $PSScriptRoot +} + +function Show-Menu { + Clear-Host + Write-Host "========================================" -ForegroundColor Cyan + Write-Host " Freigabe-Kontextmenü Installation" -ForegroundColor Cyan + Write-Host "========================================" -ForegroundColor Cyan + Write-Host "" + Write-Host "[1] Installieren für aktuellen Benutzer" + Write-Host "[2] Installieren für alle Benutzer (Admin erforderlich)" + Write-Host "[3] Deinstallieren für aktuellen Benutzer" + Write-Host "[4] Deinstallieren für alle Benutzer (Admin erforderlich)" + Write-Host "[Q] Beenden" + Write-Host "" +} + +function Get-LinkBasePath { + Add-Type -AssemblyName System.Windows.Forms + + $form = New-Object System.Windows.Forms.Form + $form.Text = "Stammverzeichnis für Verknüpfungen" + $form.Size = New-Object System.Drawing.Size(500, 180) + $form.StartPosition = "CenterScreen" + $form.FormBorderStyle = "FixedDialog" + $form.MaximizeBox = $false + + $label = New-Object System.Windows.Forms.Label + $label.Text = "Stammverzeichnis für Benutzer-Verknüpfungsordner:" + $label.Location = New-Object System.Drawing.Point(10, 20) + $label.Size = New-Object System.Drawing.Size(460, 20) + $form.Controls.Add($label) + + $textBox = New-Object System.Windows.Forms.TextBox + $textBox.Location = New-Object System.Drawing.Point(10, 45) + $textBox.Size = New-Object System.Drawing.Size(380, 20) + $textBox.Text = "C:\Freigaben\Benutzer" + $form.Controls.Add($textBox) + + $browseBtn = New-Object System.Windows.Forms.Button + $browseBtn.Text = "..." + $browseBtn.Location = New-Object System.Drawing.Point(395, 43) + $browseBtn.Size = New-Object System.Drawing.Size(75, 25) + $browseBtn.Add_Click({ + $folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog + $folderBrowser.Description = "Stammverzeichnis auswählen" + if ($folderBrowser.ShowDialog() -eq "OK") { + $textBox.Text = $folderBrowser.SelectedPath + } + }) + $form.Controls.Add($browseBtn) + + $okBtn = New-Object System.Windows.Forms.Button + $okBtn.Text = "OK" + $okBtn.Location = New-Object System.Drawing.Point(310, 100) + $okBtn.Size = New-Object System.Drawing.Size(75, 25) + $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(395, 100) + $cancelBtn.Size = New-Object System.Drawing.Size(75, 25) + $cancelBtn.DialogResult = [System.Windows.Forms.DialogResult]::Cancel + $form.CancelButton = $cancelBtn + $form.Controls.Add($cancelBtn) + + $result = $form.ShowDialog() + + if ($result -eq [System.Windows.Forms.DialogResult]::OK) { + return $textBox.Text + } + return $null +} + +function Install-ContextMenu { + param( + [bool]$ForAllUsers, + [string]$BasePath + ) + + $scriptDir = Get-ScriptDirectory + $freigabeScript = Join-Path $scriptDir "Freigabe-Hinzufuegen.ps1" + $entfernenScript = Join-Path $scriptDir "Freigabe-Entfernen.ps1" + + if ($ForAllUsers) { + if (-not (Test-Administrator)) { + throw "Admin-Rechte erforderlich für Installation für alle Benutzer!" + } + $regBase = "HKLM:\SOFTWARE\Classes" + $configPath = "$env:ProgramData\FreigabeKontextmenue" + } else { + $regBase = "HKCU:\SOFTWARE\Classes" + $configPath = "$env:APPDATA\FreigabeKontextmenue" + } + + if (-not (Test-Path $configPath)) { + New-Item -Path $configPath -ItemType Directory -Force | Out-Null + } + + $config = @{ + LinkBasePath = $BasePath + InstalledFor = if ($ForAllUsers) { "AllUsers" } else { "CurrentUser" } + InstallDate = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") + ScriptDirectory = $scriptDir + } + $config | ConvertTo-Json | Set-Content -Path (Join-Path $configPath "config.json") -Encoding UTF8 + + $shellExTypes = @( + "*\shell", + "Directory\shell", + "Directory\Background\shell" + ) + + foreach ($shellType in $shellExTypes) { + $freigabeKey = "$regBase\$shellType\FreigabeFuerMitarbeiter" + $entfernenKey = "$regBase\$shellType\FreigabeEntfernen" + + if (-not (Test-Path $freigabeKey)) { + New-Item -Path $freigabeKey -Force | Out-Null + } + Set-ItemProperty -Path $freigabeKey -Name "(Default)" -Value "Freigeben für Mitarbeiter" + Set-ItemProperty -Path $freigabeKey -Name "Icon" -Value "imageres.dll,232" + + $freigabeCmd = "$freigabeKey\command" + if (-not (Test-Path $freigabeCmd)) { + New-Item -Path $freigabeCmd -Force | Out-Null + } + + if ($shellType -eq "Directory\Background\shell") { + Set-ItemProperty -Path $freigabeCmd -Name "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$freigabeScript`" -Path `"%V`"" + } else { + Set-ItemProperty -Path $freigabeCmd -Name "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$freigabeScript`" -Path `"%1`"" + } + + if (-not (Test-Path $entfernenKey)) { + New-Item -Path $entfernenKey -Force | Out-Null + } + Set-ItemProperty -Path $entfernenKey -Name "(Default)" -Value "Freigabe für Mitarbeiter entfernen" + Set-ItemProperty -Path $entfernenKey -Name "Icon" -Value "imageres.dll,229" + + $entfernenCmd = "$entfernenKey\command" + if (-not (Test-Path $entfernenCmd)) { + New-Item -Path $entfernenCmd -Force | Out-Null + } + + if ($shellType -eq "Directory\Background\shell") { + Set-ItemProperty -Path $entfernenCmd -Name "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$entfernenScript`" -Path `"%V`"" + } else { + Set-ItemProperty -Path $entfernenCmd -Name "(Default)" -Value "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$entfernenScript`" -Path `"%1`"" + } + } + + if (-not (Test-Path $BasePath)) { + New-Item -Path $BasePath -ItemType Directory -Force | Out-Null + Write-Host "Stammverzeichnis erstellt: $BasePath" -ForegroundColor Green + } + + Write-Host "Installation erfolgreich abgeschlossen!" -ForegroundColor Green +} + +function Uninstall-ContextMenu { + param( + [bool]$ForAllUsers + ) + + if ($ForAllUsers) { + if (-not (Test-Administrator)) { + throw "Admin-Rechte erforderlich für Deinstallation für alle Benutzer!" + } + $regBase = "HKLM:\SOFTWARE\Classes" + $configPath = "$env:ProgramData\FreigabeKontextmenue" + } else { + $regBase = "HKCU:\SOFTWARE\Classes" + $configPath = "$env:APPDATA\FreigabeKontextmenue" + } + + $shellExTypes = @( + "*\shell", + "Directory\shell", + "Directory\Background\shell" + ) + + foreach ($shellType in $shellExTypes) { + $freigabeKey = "$regBase\$shellType\FreigabeFuerMitarbeiter" + $entfernenKey = "$regBase\$shellType\FreigabeEntfernen" + + if (Test-Path $freigabeKey) { + Remove-Item -Path $freigabeKey -Recurse -Force + } + if (Test-Path $entfernenKey) { + Remove-Item -Path $entfernenKey -Recurse -Force + } + } + + if (Test-Path $configPath) { + Remove-Item -Path $configPath -Recurse -Force + } + + Write-Host "Deinstallation erfolgreich!" -ForegroundColor Green + Write-Host "Hinweis: Bestehende Freigaben und Verknüpfungen wurden NICHT entfernt." -ForegroundColor Yellow +} + +if ($Install -or $Uninstall) { + if ($Install) { + $forAll = $AllUsers -and -not $CurrentUser + if (-not $LinkBasePath) { + $LinkBasePath = Get-LinkBasePath + if (-not $LinkBasePath) { + Write-Host "Installation abgebrochen." -ForegroundColor Yellow + exit 1 + } + } + Install-ContextMenu -ForAllUsers $forAll -BasePath $LinkBasePath + } + if ($Uninstall) { + $forAll = $AllUsers -and -not $CurrentUser + Uninstall-ContextMenu -ForAllUsers $forAll + } +} else { + do { + Show-Menu + $choice = Read-Host "Auswahl" + + switch ($choice.ToUpper()) { + "1" { + $basePath = Get-LinkBasePath + if ($basePath) { + Install-ContextMenu -ForAllUsers $false -BasePath $basePath + } + pause + } + "2" { + if (-not (Test-Administrator)) { + Write-Host "Bitte als Administrator ausführen!" -ForegroundColor Red + } else { + $basePath = Get-LinkBasePath + if ($basePath) { + Install-ContextMenu -ForAllUsers $true -BasePath $basePath + } + } + pause + } + "3" { + Uninstall-ContextMenu -ForAllUsers $false + pause + } + "4" { + if (-not (Test-Administrator)) { + Write-Host "Bitte als Administrator ausführen!" -ForegroundColor Red + } else { + Uninstall-ContextMenu -ForAllUsers $true + } + pause + } + } + } while ($choice.ToUpper() -ne "Q") +} diff --git a/README.md b/README.md index ed2362c..20ca460 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,4 @@ ## Hinweise - Netzlaufwerke werden automatisch als UNC-Pfade aufgelöst - Pro Benutzer wird ein Unterordner im Stammverzeichnis erstellt -- Nur über dieses Tool erstellte Freigaben werden beim Entfernen angezeigt \ No newline at end of file +- Nur über dieses Tool erstellte Freigaben werden beim Entfernen angezeigt