jonnyblue
Goto Top

Filesystemgruppen Manager herausfinden

Hallo zusammen,

wir nutzen bei uns im Unternehmen einen klassischen Fileserver mit Universal Gruppen im Active Directory mit den üblichen 3 Gruppen zum durchklicken, Lesen und Schreiben.
Das funktioniert auch mittlerweile recht gut - das ganze lebt und ja, es gibt auch Probleme, aber in summe kapieren sogar die Anwender das System mit den Gruppenrechten.

Seit knapp 2 Jahren nutzen wir den GroupManager von cjwdev.com unternehmensweit und sind mit dem Preis - Leistungsverhältnis mehr als zufrieden. Mit dem GroupManager können die "Manager" einer Gruppe ohne weitere Tools einfach die Mitglieder einer Gruppe anpassen, d.h. entfernen und hinzufügen. Das Tool ist simpel und läuft auch ohne installation direkt vom Fileshare. Der Entwickler hat sogar eine neue Funktion eingebaut mit der der Manager einer Gruppe angezeigt werden kann.

Nun gibt es allerdings das Problem, dass die Anwender zwar mit dem GroupManager umgehen können und diesen auch schätzen, immerhin können Sie sich dadurch den Call bei der IT sparen und können direkt die Zugriffsrechte verteilen. Leider wissen aber viele nicht wer der Manager für die Gruppe eines bestimmten Ordners ist und machen dann doch einen Call bei der IT auf. Durch die Funktion den Manager einer Gruppe anzeigen zu lassen wird das schon viel besser, aber einfach noch nicht massentauglich. Ich stelle mir entweder ein Tool vor, bei dem ich den Pfad angeben kann und der mir automatisch die möglichen Gruppen und per Doppelklick den Manager anzeigt - oder einfach eine Liste (in Excel?) die zentral täglich aus dem AD extrahiert wird und die die Manager mit samt Gruppenname und Filesystempfad auflistet.

Hat jemand sowas schon gemacht oder eine andere sexy Idee wie die Anwender die Berechtigungen selber verwalten können ohne damit immer wieder in die IT kommen zu müssen?

Danke für jegliche Ideen im Voraus!

Content-Key: 328007

Url: https://administrator.de/contentid/328007

Printed on: April 26, 2024 at 09:04 o'clock

Member: SlainteMhath
Solution SlainteMhath Jan 31, 2017 at 12:10:49 (UTC)
Goto Top
Moin,

eine Liste (in Excel?) die zentral täglich aus dem AD extrahiert wird
Das geht mit Powreshell. In etwa:
Get-ADGroup -filter * -properties managedby | select name,managedby | Export-Csv -Path c:\...

Filter und/oder Pfad must du noch anpassen.

lg,
Slainte
Mitglied: 132272
Solution 132272 Jan 31, 2017 updated at 12:16:11 (UTC)
Goto Top
Zitat von @SlainteMhath:
Das geht mit Powreshell. In etwa:
> Get-ADGroup -filter * -properties managedby | select name,managedby | Export-Csv -Path c:\...
> 
Und so auch von jeder Workstation ohne installiertes RSAT und Co. für die Abfrage einer bestimmten Gruppe
(new-object adsisearcher("LDAP://$(([adsi]'LDAP://rootDSE').defaultNamingContext)","(&(objectCategory=group)(SamAccountName=MeineGruppe))","managedBy",[System.DirectoryServices.SearchScope]::Subtree)).FindOne()| %{$_.Properties['managedBy']}  
Gruppenname anpassen.

Gruß
Member: Jonnyblue
Jonnyblue Jan 31, 2017 at 21:14:24 (UTC)
Goto Top
Schon mal gute Ansätze. Leider wird dann ja bei beiden Scripts der Pfad nicht mit angezeigt. Der gruppenname entspricht zwar einer gewissen Logik, aber ich befürchte, dass die User nicht in der Lage sind den zu verstehen, es fehlt also noch die Möglichkeit aus einem Pfad die möglichen Sicherheitsgruppen anzuzeigen und von denen den/die Manager anzuzeigen.
Mitglied: 132272
132272 Jan 31, 2017 updated at 21:30:21 (UTC)
Goto Top
Das ist kein Problem die ACLs kann man sich ja mit Get-ACL c:\Pfad holen.
Member: colinardo
Solution colinardo Feb 01, 2017 updated at 13:55:23 (UTC)
Goto Top
Servus JonnyBlue,
sowas lässt sich leicht zusammenscripten face-wink.

Hier mal schnell einen grafischen Dialog in Powershell:
(Kann man sich natürlich auch eine EXE von bauen, wie man es halt braucht)
$showWindowAsync = Add-Type –memberDefinition @"   
[DllImport("user32.dll")]   
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); 
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions –passThru  

function Hide-PowerShell() { 
    [void]$showWindowAsync::ShowWindowAsync((Get-Process –id $pid).MainWindowHandle, 0)
}

function GenerateForm {

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null  
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null  
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$dgv = New-Object System.Windows.Forms.DataGridView
$btnChooseFolder = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
$dt = new-object System.Data.DataTable
$dt.Columns.AddRange(@("Group","Manager"))  
#endregion Generated Form Objects

function Get-GroupManager([string]$groupsid){
    try{
        $result = (new-object adsisearcher("LDAP://$(([adsi]'LDAP://rootDSE').defaultNamingContext)","(&(objectCategory=group)(objectSid=$groupsid))","managedBy",[System.DirectoryServices.SearchScope]::Subtree)).FindOne()  
        if($result -and $result.Properties.Contains('managedBy')){  
            return [regex]::Match($result.Properties['managedBy'],'(?i)^CN=(.+?)(?=,(OU|CN|DC)=)').Groups[1].Value  
        }else{
            return $false
        }
    }catch{
        return $false
    }
}

$handler_btnChooseFolder_Click= 
{
    $dt.Rows.Clear()
    $dlg = New-Object System.Windows.Forms.FolderBrowserDialog
    if($dlg.ShowDialog() -eq 'OK'){  
        (Get-ACL $dlg.SelectedPath).Access | %{
            $result = Get-GroupManager -groupsid $_.IdentityReference.translate([System.Security.Principal.SecurityIdentifier]).Value
            if($result){
                $dt.Rows.Add(@($_.IdentityReference.toString(),$result))
            }
        }
        if ($dt.Rows.Count -eq 0){
            [System.Windows.Forms.MessageBox]::Show("Ordner enthält keine Gruppe mit Managern!","Keine Gruppen mit Managern",0,48)  
        }
    }
}

$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
	$form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 207
$System_Drawing_Size.Width = 313
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 235
$System_Drawing_Size.Width = 321
$form1.MinimumSize = $System_Drawing_Size
$form1.Name = "form1"  
$form1.Text = "List Group Managers"  

$dgv.Anchor = 15
$dgv.AutoSizeColumnsMode = 16
$dgv.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 45
$dgv.Location = $System_Drawing_Point
$dgv.Name = "dgv"  
$dgv.RowHeadersVisible = $False
$dgv.RowHeadersWidth = 20
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 150
$System_Drawing_Size.Width = 289
$dgv.Size = $System_Drawing_Size
$dgv.TabIndex = 1
$dgv.DataSource = $dt

$form1.Controls.Add($dgv)

$btnChooseFolder.Anchor = 13

$btnChooseFolder.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$btnChooseFolder.Location = $System_Drawing_Point
$btnChooseFolder.Name = "btnChooseFolder"  
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 289
$btnChooseFolder.Size = $System_Drawing_Size
$btnChooseFolder.TabIndex = 0
$btnChooseFolder.Text = "Choose folder"  
$btnChooseFolder.UseVisualStyleBackColor = $True
$btnChooseFolder.add_Click($handler_btnChooseFolder_Click)

$form1.Controls.Add($btnChooseFolder)


#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

} #End Function
Hide-PowerShell
GenerateForm

screenshot

Grüße Uwe
Member: Jonnyblue
Jonnyblue Feb 01, 2017 at 15:27:23 (UTC)
Goto Top
DAS ist exakt was ich gebraucht habe. Und wird genau so in Anwendung kommen. Vielen herzlichen Dank!
2 Verbesserungennoch, dann wär's perfekt:

1) Den Pfad anstatt per "Ordner suchen" per copy and paste einfügen
2) Wenn ein Manager für eine Gruppe wieder eine Gruppe ist wäre gut wenn man diese per Doppelklick öffnen zu kann oder wenn direkt wieder der Manager dieser Gruppe angezeigt wird
Member: colinardo
Solution colinardo Feb 01, 2017 updated at 16:05:18 (UTC)
Goto Top
Zitat von @Jonnyblue:
2 Verbesserungennoch, dann wär's perfekt:

1) Den Pfad anstatt per "Ordner suchen" per copy and paste einfügen
2) .... oder wenn direkt wieder der Manager dieser Gruppe angezeigt wird

Beides im Code unten eingebaut. Der Button nutzt hier den Pfad in der Zwischenablage, und die Manager werden rekursiv ermittelt.

Falls der Beitrag gefällt, seid so nett und unterstützt mich durch eine kleine Spende / If you like my contribution please support me and donate

Grüße Uwe
$showWindowAsync = Add-Type –memberDefinition @"   
[DllImport("user32.dll")]   
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); 
"@ -name "Win32ShowWindowAsync" -namespace Win32Functions –passThru  

function Hide-PowerShell() { 
    [void]$showWindowAsync::ShowWindowAsync((Get-Process –id $pid).MainWindowHandle, 0)
}

function GenerateForm {

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null  
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null  
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$dgv = New-Object System.Windows.Forms.DataGridView
$btnChooseFolder = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
$dt = new-object System.Data.DataTable
$dt.Columns.AddRange(@("Group","Manager"))  
#endregion Generated Form Objects


function Get-GroupManager([string]$groupsid){
    try{
        $manager = ""  
        $result = (new-object adsisearcher("LDAP://$(([adsi]'LDAP://rootDSE').defaultNamingContext)","(&(objectCategory=group)(objectSid=$groupsid))","managedBy",[System.DirectoryServices.SearchScope]::Subtree)).FindOne()  
        if($result -and $result.Properties.Contains('managedBy')){  
            $cn = $result.Properties['managedBy']   
            while($manager -eq ""){  
                $sub = (new-object adsisearcher("LDAP://$(([adsi]'LDAP://rootDSE').defaultNamingContext)","(&(objectCategory=group)(distinguishedName=$cn))","managedBy",[System.DirectoryServices.SearchScope]::Subtree)).FindOne()  
                if($sub){
                    $cn = $sub.Properties['managedBy']  
                }else{
                    $manager = $cn
                }
            }
            return [regex]::Match($manager,'(?i)^CN=(.+?)(?=,(OU|CN|DC)=)').Groups[1].Value  
        }else{
            return $false
        }
    }catch{
        return $false
    }
}

$handler_btnChooseFolder_Click= 
{
    $dt.Rows.Clear()
    $path = [System.Windows.Forms.Clipboard]::GetText()

    if($path -ne "" -and (Test-Path $path)){  
        (Get-ACL $path).Access | %{
            $result = Get-GroupManager -groupsid $_.IdentityReference.translate([System.Security.Principal.SecurityIdentifier]).Value
            if($result){
                $dt.Rows.Add(@($_.IdentityReference.toString(),$result))
            }
        }
        if ($dt.Rows.Count -eq 0){
            [System.Windows.Forms.MessageBox]::Show("Ordner enthält keine Gruppe mit Managern!","Keine Gruppen mit Managern",0,48)  
        }
    }else{
        [System.Windows.Forms.MessageBox]::Show("Es wurde kein gültiger Pfad übergeben","Kein gültiger Pfad",0,48)  
    }
}

$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
	$form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 207
$System_Drawing_Size.Width = 313
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 235
$System_Drawing_Size.Width = 321
$form1.MinimumSize = $System_Drawing_Size
$form1.Name = "form1"  
$form1.Text = "List Group Managers"  

$dgv.Anchor = 15
$dgv.AutoSizeColumnsMode = 16
$dgv.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 45
$dgv.Location = $System_Drawing_Point
$dgv.Name = "dgv"  
$dgv.RowHeadersVisible = $False
$dgv.RowHeadersWidth = 20
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 150
$System_Drawing_Size.Width = 289
$dgv.Size = $System_Drawing_Size
$dgv.TabIndex = 1
$dgv.DataSource = $dt

$form1.Controls.Add($dgv)

$btnChooseFolder.Anchor = 13

$btnChooseFolder.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 12
$btnChooseFolder.Location = $System_Drawing_Point
$btnChooseFolder.Name = "btnPasteFromClipboard"  
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 289
$btnChooseFolder.Size = $System_Drawing_Size
$btnChooseFolder.TabIndex = 0
$btnChooseFolder.Text = "Paste path from clipboard"  
$btnChooseFolder.UseVisualStyleBackColor = $True
$btnChooseFolder.add_Click($handler_btnChooseFolder_Click)

$form1.Controls.Add($btnChooseFolder)

#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

} #End Function
Hide-PowerShell
GenerateForm
Member: Jonnyblue
Jonnyblue Feb 02, 2017 at 09:41:42 (UTC)
Goto Top
Also, das Script funktioniert super. Leider hatte ich einen kleinen Denkfehler drin. Die Anwender haben ja meist gar keine Rechte um die Rechte eines Pfades auszulesen. Das führt dazu, dass zwar die Admins das Tool nutzen können aber nicht die Anwender und das ist zwar immerhin aber war nicht das Ziel...

Ich werde wohl jetzt einfach ein Export der Gruppen erstellen und als Excel bereitstellen - allen "Rechtelesen" auf den ganzen Filer zu geben ist mir Sicherheitstechnisch zu kritisch.

@uwe trotzdem vielen dank und viel Spaß mit der kleinen Spende...
Member: colinardo
colinardo Feb 02, 2017 updated at 09:56:03 (UTC)
Goto Top
Zitat von @Jonnyblue:
Also, das Script funktioniert super. Leider hatte ich einen kleinen Denkfehler drin. Die Anwender haben ja meist gar keine Rechte um die Rechte eines Pfades auszulesen. Das führt dazu, dass zwar die Admins das Tool nutzen können aber nicht die Anwender und das ist zwar immerhin aber war nicht das Ziel...
Oder man gibt einem speziellen User welcher das Script intern startet nur das erweiterte Recht zum Lesen der ACLs
Ich werde wohl jetzt einfach ein Export der Gruppen erstellen und als Excel bereitstellen - allen "Rechtelesen" auf den ganzen Filer zu geben ist mir Sicherheitstechnisch zu kritisch.
Denke auch das hier "Organisation" die beste Lösung ist. Jeder User erhält seinen Ansprechpartner in Sachen Rechte.
Nach AGDLP-Prinzip sollte das aber eigentlich schon fast obsolet sein.
@uwe trotzdem vielen dank und viel Spaß mit der kleinen Spende...
Keine Ursache und Danke face-smile!
Member: Jonnyblue
Jonnyblue Feb 02, 2017 at 14:25:20 (UTC)
Goto Top
Falls jemand mal ein solches Problem hat - hier der Codeblock den ich jetzt nutze - funktioniert 1a

import-module activedirectory
Get-ADGroup -filter {(Name -like "G") -and (Name -notlike "*-S") } -Properties managedBy,description | Sort-Object Name |   
ForEach-Object { `
$managedBy = $_.managedBy;

if ($managedBy -like $null)
{
    $managerName = 'N/A';  
    $managerEmail = 'N/A';  
    $managerPhone = 'N/A';  
}
else
{
    if ($managedby -like "CN=Group*")  
    {
        
        $group = (get-adgroup -Identity $managedBy -Properties managedBy)
        $manager = (get-aduser -Identity $group.ManagedBy -Properties emailAddress,telephoneNumber)
        $managerName = $manager.Name;
        $managerEmail = $manager.emailAddress;
        $managerPhone = $manager.telephoneNumber;
    }
    else
    {
        $manager = (get-aduser -Identity $managedBy -Properties emailAddress,telephoneNumber);
        $managerName = $manager.Name;
        $managerEmail = $manager.emailAddress;
        $managerPhone = $manager.telephoneNumber;
    }
}

Write-Output $_; } | 
Select-Object @{n='Group Name';e={$_.Name}}, @{n='Path';e={$_.Description}}, @{n='Managed By';e={$managerName}}, @{n='Email';e={$managerEmail}}, @{n='Phone';e={$managerPhone}} | ConvertTo-HTML | Out-File ManagedBy-Liste.html