michi.wtr
Goto Top

Benutzer AD-Gruppen filtern Batch

Hey zusammen,

für ein kleines Projekt muss ich zum Entwickeln einer Applikation die Gruppenmitgliedschaften im AD eines Benutzers abfragen. Wenn der Benutzer Mitglied von bestimmten Gruppen ist, bekommt er je nach Gruppe bestimmte Möglichkeiten in der Applikation zum bearbeiten von Dokumenten.

Die App programmiere ich in C# / WPF. Gibt es eine Möglichkeit, dort zu Beginn des Programms eine Abfrage zu starten, zu welchen Gruppen der ausführende Benutzer im AD gehört?
Bestimmt gibt es dafür eine einfache Möglichkeit mit irgendwelchen .NET Eigenschaften, die ich leider nur nicht kenne... face-smile

Ich habe aber herausgefunden, dass man in einem C# Programm auch die Möglichkeit hat, CMD Befehle auszuführen und deren Ergebnis in einem String zu erhalten.

FOR /f "tokens=2 delims=\" %a IN ('whoami') DO SET user=%a  
Dieser Befehl speichert mir den Benutzernamen in der Variable user ab.
Wie genau das funktioniert habe ich noch nicht ganz verstanden mit den Tokens, aber es ist wohl so, dass ich die 1. Zahl, die ich im Token angebe (hier 2) der Teil ist, welcher in der Definierten Variable (hier %a) gespeichert wird. Alle weiteren würden wohl in fortlaufenden Tokens gespeichert werden? (also %b, %c, %d etc., sollte ich tokens=2,3,4-8,9* angeben)

Lange Rede kurzer Sinn, ich erhalte durch whoami das Ergebnis: DOMAIN\username, welches ich an "\" splitte und nur den 2. Teil in "user" speichere.


NET USER /domain "%user%"  
Der Befehl gibt mir nun einen Haufen von Informationen zu dem AD-User (ich schätze einfach mal AD Informationen) zurück. Darunter auch "Globale Gruppenmitgliedschaften", die Gruppen, in welcher der AD-Benutzer Mitglied ist.

Diese möchte ich nun auf bestimmte Gruppen prüfen. Das Ergebnis kann entweder "null" sein, da der Benutzer kein Mitglied einer der benötigten Gruppen ist, eine der Gruppen oder auch mehrere Gruppen...

Wie genau kann ich diese Gruppen filtern, um beispielsweise nur die Gruppen zu erhalten, welche mit "E-" beginnen, also E mit Bindestrich?

Wenn das möglich ist, dann würde ich gerne diese Gruppennamen in einer Variable speichern.
Die Gruppen sind immer in einer Zeile mit mehreren Leerzeichen, dann einem * gefolgt von den Gruppennamen. Ich gehe davon aus, dass sich das mit eben derselben Vorgehensweise lösen lässt:
SET temp=
FOR /f "tokens=?? delims=??" %a IN ('NET USER /domain "%user%"') DO SET temp=%temp% , %a%b%c  

Der net user befehl gibt einige für mich uninteressanten Zeilen zurück gefolgt von:

Globale Gruppenmitliedschaften ::::::::::: *Gruppenname1
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *Gruppenname2
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *Gruppenname3
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *Gruppenname4
(Die ::::: wegdenken, habe ich eingefügt da die Leerzeichen hier einfach getrimmt werden :\ also ::::: eigentlich = whitespace face-smile

Diese möchte ich in temp speichern, falls der Gruppenname mit "E-" beginnt.


Vielen lieben Dank schonmal im Voraus,
Micha

Content-Key: 6710125018

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

Printed on: April 28, 2024 at 12:04 o'clock

Member: michi.wtr
michi.wtr Apr 09, 2023 updated at 21:39:09 (UTC)
Goto Top
Okay, eventuell geht das wohl auch viel einfacher, kenne leider noch kaum CMD-Befehle, aber whoami /groups liefert auch schon ein Ergebnis mit den Gruppen, diese müsste ich nun nur auch dementsprechend noch filtern.....

Oder ich nutze die leichter zu filternde Darstellung von net user, verzichte aber auf whoami da es eine Variable USERNAME gibt.... die ich gerade auch noch entdeckt habe.

Primär geht es mir ja aber um die Möglichkeit die Zeilen ausfiltern zu können face-smile
Bzw. ob es auch eine viel einfachere Möglichkeit gibt das ganze ohne CMD Kommandos zu lösen innerhalb von C#
Member: mayho33
Solution mayho33 Apr 09, 2023 at 21:37:53 (UTC)
Goto Top
Member: michi.wtr
michi.wtr Apr 09, 2023 at 21:41:12 (UTC)
Goto Top
nvm, sorry für die Dummheit xD
Member: mayho33
mayho33 Apr 09, 2023 at 22:01:56 (UTC)
Goto Top
Zitat von @michi.wtr:

nvm, sorry für die Dummheit xD

🤷‍♂️🤣 Fragen kostet ja nichts.
Member: Crusher79
Crusher79 Apr 09, 2023 at 22:02:06 (UTC)
Goto Top
Zitat von @michi.wtr:

nvm, sorry für die Dummheit xD

Alles gut. Google ist ja auch immer so eine Sache. Du bist aber in ein anderes Fettnäpfchen getreten: Batch. Manche machen da schon zu, da man vieles mit PowerShell erledigt. Geht soweit, dass PS Execute in Batch verschachtelt wird, um die Leute dahin zu bringen. face-big-smile

Nativ mit C# ist natürlich bei MS das Mittel der Wahl.

Wenn du aber eh schon in C# unterwegs bist wirst du auch mit PS zurecht kommen und damit Lücken schließen können, die in C# zu einer gewissen Zeit vlt. zuviel Aufwand machen. face-wink
Member: mayho33
mayho33 Apr 09, 2023 at 22:04:41 (UTC)
Goto Top
Zitat von @Crusher79:

Zitat von @michi.wtr:

nvm, sorry für die Dummheit xD

Alles gut. Google ist ja auch immer so eine Sache. Du bist aber in ein anderes Fettnäpfchen getreten: Batch. Manche machen da schon zu, da man vieles mit PowerShell erledigt.

Igittigitt... Wenn ich Batch schon höre.. 🤣🤣

Na! Ganz nutzlos ist es ja nicht.
Member: Crusher79
Crusher79 Apr 09, 2023 at 22:11:19 (UTC)
Goto Top
Ja stimmt. Arbeite auch mit allen. Nur du weisst selber das wir hier zig Anfragen bezüglich Auslesen oder Manipulation von System Eigenschaften haben. Das ist mit Bacht halt nich so elegant, als wie wenn ich gleich Objekte zurück bekomme und übergeben kann face-wink
Member: mayho33
mayho33 Apr 09, 2023 at 22:22:46 (UTC)
Goto Top
Zitat von @Crusher79:

Ja stimmt. Arbeite auch mit allen. Nur du weisst selber das wir hier zig Anfragen bezüglich Auslesen oder Manipulation von System Eigenschaften haben. Das ist mit Bacht halt nich so elegant, als wie wenn ich gleich Objekte zurück bekomme und übergeben kann face-wink

Ja richtig! Wenn die die Daten weiterverarbeiten werden sollen ist Batch genau das verkehrte, da die einfach als Text daherkommen.

PS in C# finde ich allerdings nicht so smooth, C# in PS ist aber ganz geil. Ausgenommen C# CmdLets ...manchmal 🤷‍♂️😅
Member: Crusher79
Crusher79 Apr 09, 2023 at 22:32:35 (UTC)
Goto Top
Ja stimmt. Die Grenzen verwischen sich. Interessant ist vor allem das man DLLs in PowerShell einbinden kann.

Hab mit < 10 Zeilen Barcode Scanner in Script aufgenommen. Einschl. slice des Bildes und Übergabe des Ausschnitts an die DLL.

Manche rümpfen jetzt starkt die Nase: hab auch Bock mal wieder was mit Magic XPA zu machen. 4 GL. Zumindest in puncto Geschwindigkeit beim proggen unschlagbar. Auch wenn etwas umständlich. Und auch C# Snippets kann man direkt eingeben und damit arbeiten.

Irgendwie schweifen wir ab face-big-smile
Member: mayho33
mayho33 Apr 09, 2023 at 22:43:36 (UTC)
Goto Top
Ich sags mal so:

Mir ist wichtig, dass der Code lesbar und nicht Spaghetti ist.

Alles was flutscht und halbwegs performant ist, ist erlaubt.
Member: michi.wtr
michi.wtr Apr 11, 2023 at 05:55:55 (UTC)
Goto Top
Also ich wollte gerade mal ausprobieren, das Ganze mit System.DirectoryServices anzuschauen, leider aber habe ich diesen namespace wohl nicht. Muss man dafür etwas herunterladen oder importieren zuerst? Nicht dass man hierfür die Windows Capability für AD aktiviert haben muss....


Zitat von @Crusher79:

Wenn du aber eh schon in C# unterwegs bist wirst du auch mit PS zurecht kommen und damit Lücken schließen können, die in C# zu einer gewissen Zeit vlt. zuviel Aufwand machen. face-wink

Ja mit PowerShell wäre es mir sowieso am liebsten, aber da ich auch dort glaube ich erst das Modul für AD bräuchte. Irgendwie kann man das glaube ich auch ohne Modul mit Klassen, CimClassen oder so machen, jedoch kenne ich mich da noch gar nicht aus. Aber dachte wenn es so einfach mit net user geht dann tu ich mir lieber das an, da der Befehl auch zu 100% auf allen Clients später auch funktioniert.

Zitat von @mayho33:

Ja richtig! Wenn die die Daten weiterverarbeiten werden sollen ist Batch genau das verkehrte, da die einfach als Text daherkommen.

Natürlich ist es dann auch sinnvoller die Ausgabe von net user als String mit C# zu verarbeiten, hat mich nur interessiert wie es denn mit Batch funktionieren würde. face-smile
Mitglied: 6247018886
Solution 6247018886 Apr 11, 2023 updated at 06:11:12 (UTC)
Goto Top
Easy ...
dsquery user -samid %username% | dsget user -memberof
Oder PowerShell ohne Abhängigkeiten
[adsisearcher]::new("(SamAccountName=$env:Username)","memberOf").FindOne() | %{$_.Properties['memberof']}  
in ne Batch eingebaut
@echo off
PowerShell -EP Bypass -C "[adsisearcher]::new(\"(SamAccountName=$env:Username)\",'memberOf').FindOne() | foreach{$_.Properties['memberof']}"  
usw.
1001 possibilities ...

Cheers briggs
Member: mayho33
Solution mayho33 Apr 11, 2023 at 06:23:57 (UTC)
Goto Top
Zitat von @michi.wtr:

Also ich wollte gerade mal ausprobieren, das Ganze mit System.DirectoryServices anzuschauen, leider aber habe ich diesen namespace wohl nicht. Muss man dafür etwas herunterladen oder importieren zuerst? Nicht dass man hierfür die Windows Capability für AD aktiviert haben muss....
Was meinst du aktuell? Das Thema an sich? Das Beispiel das ich dir gepostet habe? Ich habe mir das jetzt nicht groß angesehen, aber du hast bestimmt bemerkt, dass du ein paar Assemblies einbinden musst:
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;

Ja mit PowerShell wäre es mir sowieso am liebsten, aber da ich auch dort glaube ich erst das Modul für AD bräuchte.
Das ist richtig, aber es lässt sich ja zur Laufzeit problemlos nachladen. Siehe dazu (unteres Drittel):
https://www.imanami.com/get-aduser-not-recognized/#:~:text=Error%3A%20Ge ....

Irgendwie kann man das glaube ich auch ohne Modul mit Klassen, CimClassen oder so machen, jedoch kenne ich mich da noch gar nicht aus.
Da wäre eventuell dieser Artikel hilfreich:
https://devblogs.microsoft.com/powershell-community/how-do-i-discover-ch ...

Aber dachte wenn es so einfach mit net user geht dann tu ich mir lieber das an, da der Befehl auch zu 100% auf allen Clients später auch funktioniert.
Wie gesagt! Da bekommst du halt einen String zurück mit ganz viel Schrott drinnen. Den erst mal programmatikalisch aufzudröseln und die wichtigen Infos zu filtern ist buggy und aufwändig.

Zitat von @mayho33:

Ja richtig! Wenn die die Daten weiterverarbeiten werden sollen ist Batch genau das verkehrte, da die einfach als Text daherkommen.

Natürlich ist es dann auch sinnvoller die Ausgabe von net user als String mit C# zu verarbeiten...
Na, eigentlich ist es sinnvoller das Return einer Abfrage als Object mit seinem Eigenschaften zu verarbeiten.

hat mich nur interessiert wie es denn mit Batch funktionieren würde. face-smile
Dazu kann ich nur folgendes sagen: Es funktioniert beschissen 😂😂🤦‍♂️
Member: mayho33
mayho33 Apr 11, 2023 at 06:33:46 (UTC)
Goto Top
Zitat von @6247018886:
dsquery user -samid %username% | dsget user -memberof
Oder PowerShell ohne Abhängigkeiten
[adsisearcher]::new("(SamAccountName=$env:Username)","memberOf").FindOne() | %{$_.Properties['memberof']}  
in ne Batch eingebaut
@echo off
PowerShell -EP Bypass -C "[adsisearcher]::new(\"(SamAccountName=$env:Username)\",'memberOf').FindOne() | foreach{$_.Properties['memberof']}"  

Smoooooth ! 👍👍
Mitglied: 3063370895
Solution 3063370895 Apr 11, 2023 updated at 07:32:51 (UTC)
Goto Top
Zitat von @michi.wtr:

Also ich wollte gerade mal ausprobieren, das Ganze mit System.DirectoryServices anzuschauen, leider aber habe ich diesen namespace wohl nicht. Muss man dafür etwas herunterladen oder importieren zuerst? Nicht dass man hierfür die Windows Capability für AD aktiviert haben muss....

Ich habe etwas Erfahrung hiermit, da ich für unsere IT eine eigene AD-Benutzerverwaltung programmiert habe (inkl. an unser System angepasstes Erstellen neuer Benutzer etc).

Du musst deinem Projekt einen Verweis zu System.DirectoryServices.AccountManagement hinzufügen.
Dazu im Menü auf Projekt -> Verweis hinzufügen und dann unter Assemblys System.DirectoryServices.AccountManagement anhaken und OK drücken.

Hier eine Funktion zum abrufen der Gruppen eines Users:

public List<GroupPrincipal> GetGroups(string userName)
        {
            List<GroupPrincipal> result = new List<GroupPrincipal>();
            PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
            UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
            if (user != null)
            {
                PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
                foreach (Principal p in groups)
                {
                    if (null != p.DistinguishedName )
                    {
                        result.Add((GroupPrincipal)p);
                    }
                }
            }

            return result;
        }
    }
Member: Crusher79
Solution Crusher79 Apr 11, 2023 at 06:38:53 (UTC)
Goto Top
NuGet Console:

NuGet\Install-Package System.DirectoryServices -Version 4.0.0

Fertig.
Member: michi.wtr
michi.wtr Apr 11, 2023 at 06:40:57 (UTC)
Goto Top
Zitat von @6247018886:

Easy ...
dsquery user -samid %username% | dsget user -memberof
Oder PowerShell ohne Abhängigkeiten
[adsisearcher]::new("(SamAccountName=$env:Username)","memberOf").FindOne() | %{$_.Properties['memberof']}  
in ne Batch eingebaut
@echo off
PowerShell -EP Bypass -C "[adsisearcher]::new(\"(SamAccountName=$env:Username)\",'memberOf').FindOne() | foreach{$_.Properties['memberof']}"  

Ja so funktioniert es, lass das ganze über einen CMD Prozess die Gruppen auslesen.


Wollte es aber noch mit C# Methoden versuchen:


Zitat von @mayho33:

Was meinst du aktuell? Das Thema an sich? Das Beispiel das ich dir gepostet habe? Ich habe mir das jetzt nicht groß angesehen, aber du hast bestimmt bemerkt, dass du ein paar Assemblies einbinden musst:
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;

Ich meine, dass es kein System.DirectoryServices gibt das ich einbinden könnte :\
Auf meiner Maschine, auf der ich programmiere, habe ich aber kein Windows Feature für RSAT-ActiveDirectory. Wusste nicht ob ich das benötige, um im C# Projekt diesen Namespace System.DirectoryServices (wenn das ein Namespace ist, aber denke namespace = package von Java) in das Projekt einzubinden. Denke nicht, dass das das Problem ist, aber System.DirectoryServices finde ich leider nicht.
Member: michi.wtr
michi.wtr Apr 11, 2023 at 06:42:52 (UTC)
Goto Top
Zitat von @Crusher79:

NuGet Console:

NuGet\Install-Package System.DirectoryServices -Version 4.0.0

Fertig.

Ah okay, denke das wird es sein face-smile
Member: michi.wtr
michi.wtr Apr 11, 2023 at 06:45:09 (UTC)
Goto Top
Zitat von @3063370895:

Zitat von @michi.wtr:

Also ich wollte gerade mal ausprobieren, das Ganze mit System.DirectoryServices anzuschauen, leider aber habe ich diesen namespace wohl nicht. Muss man dafür etwas herunterladen oder importieren zuerst? Nicht dass man hierfür die Windows Capability für AD aktiviert haben muss....

Ich habe etwas Erfahrung hiermit, da ich für unsere IT eine eigene AD-Benutzerverwaltung programmiert habe (inkl. an unser System angepasstes Erstellen neuer Benutzer etc).

Du musst deinem Projekt einen Verweis zu System.DirectoryServices.AccountManagement hinzufügen.
Dazu im Menü auf Projekt -> Verweis hinzufügen und dann unter Assemblys System.DirectoryServices.AccountManagement anhaken und OK drücken.

Hier eine Funktion zum abrufen der Gruppen eines Users:

 public List<GroupPrincipal> GetGroups(string userName)
        {
            List<GroupPrincipal> result = new List<GroupPrincipal>();
            PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
            UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
            if (user != null)
            {
                PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
                foreach (Principal p in groups)
                {
                    if (p is GroupPrincipal)
                    {
                        result.Add((GroupPrincipal)p);
                    }
                }
            }

            return result;
        }

Das hört sich auch vielversprechend an, werde ich auf jeden Fall mal probieren :D

Ich denke da waren jetzt einige gute Lösungen dabei, die ich verwenden kann.
Vielen lieben Dank euch allen <3
Member: Crusher79
Crusher79 Apr 11, 2023 at 06:47:54 (UTC)
Goto Top
Zitat von @michi.wtr:

Zitat von @Crusher79:

NuGet Console:

NuGet\Install-Package System.DirectoryServices -Version 4.0.0

Fertig.

Ah okay, denke das wird es sein face-smile

Jup.

Bei den Snippets muss man immer aufpassen. Oft fehlt da was. Google hilft meist.

using System.DirectoryServices missing

missing, not found - liefert da meist schnell Hilfe face-wink
Member: michi.wtr
michi.wtr Apr 11, 2023 at 06:49:47 (UTC)
Goto Top
Zitat von @6247018886:

Easy ...
dsquery user -samid %username% | dsget user -memberof
Oder PowerShell ohne Abhängigkeiten
[adsisearcher]::new("(SamAccountName=$env:Username)","memberOf").FindOne() | %{$_.Properties['memberof']}  
in ne Batch eingebaut
@echo off
PowerShell -EP Bypass -C "[adsisearcher]::new(\"(SamAccountName=$env:Username)\",'memberOf').FindOne() | foreach{$_.Properties['memberof']}"  
usw.
1001 possibilities ...

Cheers briggs

Oh den Beitrag hatte ich vorhin noch gar nicht gesehen, das sieht auch sehr vielversprechend aus. Was aber ist dsquery? Weder cmd noch PS kennt bei mir diesen Befehl, muss ich dafür auch erst noch etwas herunterladen?
Mitglied: 3063370895
3063370895 Apr 11, 2023 at 06:50:34 (UTC)
Goto Top
dsquery ist teil des AD RSAT-Pakets
Member: michi.wtr
michi.wtr Apr 11, 2023 at 06:53:06 (UTC)
Goto Top
Zitat von @3063370895:

dsquery ist teil des AD RSAT-Pakets

Ah okay, dann nutze ich aber die PS variante ohne Abhängigkeiten, möchte das AD RSAT-Paket nicht bei jedem User des Programms herunterladen ;)
Aber mit dem PowerShell Befehl, den ich über CMD ausführen kann sollte es wunderbar funktionieren.
Member: Crusher79
Crusher79 Apr 11, 2023 updated at 07:09:13 (UTC)
Goto Top
Naja auch bei Forms müssen die Dateien ja erst eröffnet werden. Also mal Button Event belegen.

GetGroupsOfMember("NAME");

Darf nicht leer sein! Name ist der Benutzername.

Mit dem Result mache ich hier natürlichnichts! Wenn du Breakpoint auf

return groups;

setzt siehst du aber das Ergebnis!


using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace AD_Test_Forms
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

        /// <summary>
        ///     Ermittelt alle Gruppen die ein bestimmter User gehört.
        /// </summary>
        /// <param name="username"> 
        ///     Windows-NT-Anmeldename des Benutzers für welchen die Gruppenzugehörigkeit ermittelt werden soll
        /// </param>
        /// <returns>
        ///     eine Liste mit den Gruppennamen
        /// </returns>
        private List<String> GetGroupsOfMember(string username)
        {
            List<string> groups = new List<string>();
            // Objekt für AD-Abfrage erzeugen
            using (DirectorySearcher searcher = new DirectorySearcher(new DirectoryEntry(string.Empty)))
            {
                // nach Kriterium filtern - hier nach Gruppe mit einem best. Namen (Inhalt von 'username') 
                searcher.Filter = string.Concat(string.Format(@"(&(ObjectClass=user)(sAMAccountName={0}))", username));  

                // Anfrage mit gesetzteen Filter ausführen und Ergebnisse durch iterieren
                foreach (SearchResult result in searcher.FindAll())
                {
                    // Eigenschaft 'MemberOf' des AD-Knotenpunktes 'result' durch iterieren 
                    foreach (var group in result.Properties["MemberOf"])  
                    {
                        // cast von 'group' zum Datentyp 'string' sollte nicht möglich sein, wird 'groupResult' 'null' 
                        string groupResult = group as string;

                        if (groupResult != null)
                        {
                            // CN aus dem Pfad extrahieren und zur Liste hinzufügen
                            groups.Add(groupResult.Substring(3, groupResult.IndexOf(',') - 3));  
                        }
                    }
                }
            }

            // sollte nichts ermittelt worden sein, "- kein Eintrag gefunden -" in Liste einfügen 
            if (groups.Count < 1)
                groups.Add("- kein Eintrag gefunden -");  


            return groups;
        }

        private void button1_Click(object sender, EventArgs e)
		{
            GetGroupsOfMember("NAME");  
		}
	}
}
Mitglied: 3063370895
3063370895 Apr 11, 2023 updated at 07:32:35 (UTC)
Goto Top
Zitat von @Crusher79:
...

Da gefällt mir meine Funktion besser face-smile

public List<GroupPrincipal> GetGroups(string userName)
        {
            List<GroupPrincipal> result = new List<GroupPrincipal>();
            PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
            UserPrincipal user = UserPrincipal.FindByIdentity(yourDomain, userName);
            if (user != null)
            {
                PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
                foreach (Principal p in groups)
                {
                    if (null != p.DistinguishedName )
                    {
                        result.Add((GroupPrincipal)p);
                    }
                }
            }

            return result;
        }
    }
Member: Crusher79
Crusher79 Apr 11, 2023 at 07:12:14 (UTC)
Goto Top
Zitat von @3063370895:

Zitat von @Crusher79:
...

Da gefällt mir meine Funktion besser face-smile

Naja hab nur mal das Snippet von oben aufgenommen face-wink

Aber du weisst ja auch, es kommt auf die Umgebung an. Konsolen-Anwendung oder GUI. private ... kann man ja nicht irgendwo hin pflanzen.

War noch mal als kurz Hinweise gedacht, was z.B. nach Button-Event ausgelöst werden kann.

Klar gibt es schönere.

ad_groups
Mitglied: 3063370895
3063370895 Apr 11, 2023 at 07:35:35 (UTC)
Goto Top
Zitat von @3063370895:
Da gefällt mir meine Funktion besser face-smile

Wichtig zu wissen: hier werden auch nested groups mit aufgelistet.