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-ID: 328007

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

Ausgedruckt am: 22.11.2024 um 05:11 Uhr

SlainteMhath
Lösung SlainteMhath 31.01.2017 um 13:10:49 Uhr
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
132272
Lösung 132272 31.01.2017 aktualisiert um 13:16:11 Uhr
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ß
Jonnyblue
Jonnyblue 31.01.2017 um 22:14:24 Uhr
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.
132272
132272 31.01.2017 aktualisiert um 22:30:21 Uhr
Goto Top
Das ist kein Problem die ACLs kann man sich ja mit Get-ACL c:\Pfad holen.
colinardo
Lösung colinardo 01.02.2017 aktualisiert um 14:55:23 Uhr
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
Jonnyblue
Jonnyblue 01.02.2017 um 16:27:23 Uhr
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
colinardo
Lösung colinardo 01.02.2017 aktualisiert um 17:05:18 Uhr
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
Jonnyblue
Jonnyblue 02.02.2017 um 10:41:42 Uhr
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...
colinardo
colinardo 02.02.2017 aktualisiert um 10:56:03 Uhr
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!
Jonnyblue
Jonnyblue 02.02.2017 um 15:25:20 Uhr
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