first version
This commit is contained in:
parent
737f4b98b8
commit
760e875e48
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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")
|
||||
}
|
||||
Loading…
Reference in New Issue