Zugriffsrechte von Ordnern mit VB-Script auslesen
Script für VB oder CMD zum auslesen von Rechten
Hallo Gemeinde,
Der Beitrag Besitzer von Ordnern mit VB-Script auslesen&thread=false hat mir schon weitergeholfen. Allerdings möchte der User dort nur die Besitzer von Ordnern angezeigt bekommen.
Mein Problem ist, das ich einer von mehreren Ablageverwalter bin und für einen Teilbereich einer sehr großen Ablage Verantwortung trage. Jeder Verwalter hat seinen eigenen Bereich wo er User entsprechende Rechte auf die Ordner vergeben kann.
Ich möchte nun eine Dokumentation mit Excel2007(oder Access2007) und einem VBA Script oder einer Batchdatei(cmd) erstellen, mit der ich regelmäßig alle Ordner abfrage und mir dann in einer Liste die User mit ihren entsprechenden Rechten dargestellt werden.
Bisher mach ich das immer händisch, aber wenn ich mal ausfallen sollte, muss ja dokumentiert sein, wer was darf.
Ich benötige eine Übersicht in der Art:
Pfad Dateiname Erstellt User Rechte
Kann mir jemand da weiterhelfen? Denn ich habe jetzt mehrere dutzende Excel-, VB-, Script-Seiten durchsucht, aber nirgends etwas zufriedenstellendes gefunden.
Gruß
DieDrohne
Hallo Gemeinde,
Der Beitrag Besitzer von Ordnern mit VB-Script auslesen&thread=false hat mir schon weitergeholfen. Allerdings möchte der User dort nur die Besitzer von Ordnern angezeigt bekommen.
Mein Problem ist, das ich einer von mehreren Ablageverwalter bin und für einen Teilbereich einer sehr großen Ablage Verantwortung trage. Jeder Verwalter hat seinen eigenen Bereich wo er User entsprechende Rechte auf die Ordner vergeben kann.
Ich möchte nun eine Dokumentation mit Excel2007(oder Access2007) und einem VBA Script oder einer Batchdatei(cmd) erstellen, mit der ich regelmäßig alle Ordner abfrage und mir dann in einer Liste die User mit ihren entsprechenden Rechten dargestellt werden.
Bisher mach ich das immer händisch, aber wenn ich mal ausfallen sollte, muss ja dokumentiert sein, wer was darf.
Ich benötige eine Übersicht in der Art:
Pfad Dateiname Erstellt User Rechte
Kann mir jemand da weiterhelfen? Denn ich habe jetzt mehrere dutzende Excel-, VB-, Script-Seiten durchsucht, aber nirgends etwas zufriedenstellendes gefunden.
Gruß
DieDrohne
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 151233
Url: https://administrator.de/contentid/151233
Ausgedruckt am: 19.11.2024 um 15:11 Uhr
27 Kommentare
Neuester Kommentar
HI.
Ein kleiner Ansatz:
Bei Fragen, einfach stellen bzw nachlesen
Gruss Mono
Ein kleiner Ansatz:
Option Explicit
Dim fso, csvFilePath,csvFile,fname
fname = "D:\Temp" 'Der Pfad zum Ordner wo die Rechte ausgelesen werden sollen
csvFilePath = Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"\")) & "myCsvlist.csv" 'csvFile wird In
'selben Ordner wie das Script gelegt bzw erzeugt
Set fso = CreateObject("Scripting.FileSystemObject")
Set csvFile = fso.OpenTextFile(csvFilePath,8,True)
csvFile.WriteLine(VbCrLf & "Ausgelesene Daten vom " & Now & VbCrLf)
Call main
MsgBox "fertig"
Sub main()
Dim folder
Set folder = fso.GetFolder(fname)
recFolder(folder)
csvFile.Close
End Sub
Sub recFolder(fname)
Dim subfolder
csvFile.Write(readacl(fname))
For Each subfolder In fname.SubFolders
recFolder(subfolder)
Next
End Sub
Function readacl(Folder)
readacl = True
Dim wmi
Dim Result
Dim AFlags, FormatType,fss,sts,dce,sd
Result = Folder & ";"
Set wmi = GetObject("winmgmts:{impersonationLevel=Impersonate,(TakeOwnership)}!\\.\root\cimv2")
Set fss = wmi.Get("Win32_LogicalFileSecuritySetting='" & fname & "'")
sts = fss.GetSecurityDescriptor(sd)
For Each dce In sd.dacl
Result = Result & dce.Trustee.Name & ";"
Result = Result & dce.Trustee.SIDString & ";"
Select Case hex(dce.AccessMask)
'Eine Dokumentation über die AccessMask findest du bei MSDN, ich habe die 3 geläufigsten aufgelistet:
Case "1F01FF"
FormatType= "Full"
Case "1301BF"
FormatType = "Write"
Case "1200A9"
FormatType = "Read"
Case Else
FormatType = "Unspecified"
End Select
Result = Result & FormatType & ";"
'Eine Dokumentation über die AceFlags findest du bei MSDN, ich habe dir ein paar Bsp gelistet:
Select Case Hex(dce.AceFlags)
Case "0"
AFlags = "NUR DIESER ORDNER ---- nicht geerbt"
Case "3"
AFlags = "diesen Ordner, Unterordner und Dateien ---- nicht geerbt"
Case "13"
AFlags = "NUR DIESER ORDNER ---- geerbt"
Case "1B"
AFlags = "Nur Unterordner und Dateien --- geerbt"
End Select
Result = Result & AFlags & ";" & VbCrLf & ";"
Next
Result = Left(Result,Len(Result)-1)
readacl = Result
End Function
Bei Fragen, einfach stellen bzw nachlesen
Gruss Mono
HI,
das ist ein VB Script.
Dazu muss du den Inhalt in eine Textdatei einfügen, diese mit der Endung .vbs abspeichern und danach ausführen.
Die PFade musst du natürlich anpassen. Am besten baust du dir ein paar Testordner mit verschiedenen Berechtigungen, legst im Script den Pfad auf die Testordner und startest es.
Danach erhältst du eine .csv Datei mit den entsprechenden Ausgaben.
Alternativ kannst du das auch in Excel direkt ausführen. Dazu musst es dir nur nach VBA anpassen und entsprechend aufrufen.
das ist ein VB Script.
Dazu muss du den Inhalt in eine Textdatei einfügen, diese mit der Endung .vbs abspeichern und danach ausführen.
Die PFade musst du natürlich anpassen. Am besten baust du dir ein paar Testordner mit verschiedenen Berechtigungen, legst im Script den Pfad auf die Testordner und startest es.
Danach erhältst du eine .csv Datei mit den entsprechenden Ausgaben.
Alternativ kannst du das auch in Excel direkt ausführen. Dazu musst es dir nur nach VBA anpassen und entsprechend aufrufen.
Hallo DieDrohne!
Dann versuch mal, ob Du hiermit weiterkommst
Der nachfolgende VBA-Code gestattet eine flexible Erstellung einer Csv-Datei mit den entsprechenden Folder-Zugriffsrechten.
Die ersten Zeilen mit ihren Konstanten sollten selbsterklärend sein.
Erklärung zu den Definitionen der Zugriffs-Konstanten:
Die Konstanten-Namen:
AF steht für AccessFlags, AT für Access-Type und AM für AccessMask und die Nummer dahinter ist die dazugehörige Bit-Nummer.
Die Konstanten mit einem x und einer Nummer z.B. AMx1 (Hex 1F01FF) definieren Bit-Masken und können beliebig definiert werden, wobei die Bezeichnungen nach den ersten beiden Buchstaben frei wählbar sind.
An dieser Stelle sei schonmal zu erwähnen, dass in der Definition nach dem "="-Zeichen im ersten Token z.B. "AM?;" eine Besonderheit zu beachten ist, die im Code eine wichtige Rolle spielt. Und zwar wird anhand des 3. Zeichens im Code unterschieden, ob ein Bit-Test (& alias And) oder ein Vergleich (= alias Compare) durchgeführt wird. Sprich ein Bit-Wert mit And und eine Bit-Maske oder der Wert 0 mit Compare testen. Hierbei ist ebenfalls zu beachten, dass der Vergleich (Compare) Vorang vor einem Bit-Test (And) hat, was bedeutet, wenn eine Bit-Maske True ist, dann wird kein Bit-Test durchgeführt.
Die Konstanten nach Wunsch registrieren:
Die Konstanten AFxx, ATxx, AMxx werden nun zwecks Flexibilität im Code in dem Array CsvListe eingetragen, in der sie ausgegeben werden sollen. D.h. das nur die Konstanten, die in der CsvListe eingetragen sind und in der Reihenfolge wie sie eingetragen sind, in die Csv-Datei geschrieben werden, wobei allerdings die ersten 4 Spalten schon mit "Pfad;Erstellt;Benutzer;SID-String" vordefiniert sind.
Anhand der CsvListe werden die Werte, die sich hinter dem "="-Zeichen befinden in einem Dictionary-Object registriert. D.h. es wird ein Schlüssel (Key/ID) mit einem dazugehörigen Wert (Item) erzeugt.
Der Eintrag für z.B. AM02 = "AM&;&H00000004;TitelText" würde dann so aussehen: Key = "AM&00000004 + Item = "00000004" und der wahlfreie TitelText wird in das Überschrift-Array Csv-Titel übernommen und als Überschriftzeile in die Csv-Datei geschrieben.
Hoffe das es bis hierher einigermaßen verständlich war, ansonsten nachfragen
Quellcode in ein Modul einfügen und einfach mal starten und die Csv-Datei anschauen und danach entsprechende Anpassungen vornehmen.
Gruß Dieter
[edit] geändert [/edit]
Dann versuch mal, ob Du hiermit weiterkommst
Der nachfolgende VBA-Code gestattet eine flexible Erstellung einer Csv-Datei mit den entsprechenden Folder-Zugriffsrechten.
Die ersten Zeilen mit ihren Konstanten sollten selbsterklärend sein.
Erklärung zu den Definitionen der Zugriffs-Konstanten:
Die Konstanten-Namen:
AF steht für AccessFlags, AT für Access-Type und AM für AccessMask und die Nummer dahinter ist die dazugehörige Bit-Nummer.
Die Konstanten mit einem x und einer Nummer z.B. AMx1 (Hex 1F01FF) definieren Bit-Masken und können beliebig definiert werden, wobei die Bezeichnungen nach den ersten beiden Buchstaben frei wählbar sind.
An dieser Stelle sei schonmal zu erwähnen, dass in der Definition nach dem "="-Zeichen im ersten Token z.B. "AM?;" eine Besonderheit zu beachten ist, die im Code eine wichtige Rolle spielt. Und zwar wird anhand des 3. Zeichens im Code unterschieden, ob ein Bit-Test (& alias And) oder ein Vergleich (= alias Compare) durchgeführt wird. Sprich ein Bit-Wert mit And und eine Bit-Maske oder der Wert 0 mit Compare testen. Hierbei ist ebenfalls zu beachten, dass der Vergleich (Compare) Vorang vor einem Bit-Test (And) hat, was bedeutet, wenn eine Bit-Maske True ist, dann wird kein Bit-Test durchgeführt.
Die Konstanten nach Wunsch registrieren:
Die Konstanten AFxx, ATxx, AMxx werden nun zwecks Flexibilität im Code in dem Array CsvListe eingetragen, in der sie ausgegeben werden sollen. D.h. das nur die Konstanten, die in der CsvListe eingetragen sind und in der Reihenfolge wie sie eingetragen sind, in die Csv-Datei geschrieben werden, wobei allerdings die ersten 4 Spalten schon mit "Pfad;Erstellt;Benutzer;SID-String" vordefiniert sind.
Anhand der CsvListe werden die Werte, die sich hinter dem "="-Zeichen befinden in einem Dictionary-Object registriert. D.h. es wird ein Schlüssel (Key/ID) mit einem dazugehörigen Wert (Item) erzeugt.
Der Eintrag für z.B. AM02 = "AM&;&H00000004;TitelText" würde dann so aussehen: Key = "AM&00000004 + Item = "00000004" und der wahlfreie TitelText wird in das Überschrift-Array Csv-Titel übernommen und als Überschriftzeile in die Csv-Datei geschrieben.
Hoffe das es bis hierher einigermaßen verständlich war, ansonsten nachfragen
Quellcode in ein Modul einfügen und einfach mal starten und die Csv-Datei anschauen und danach entsprechende Anpassungen vornehmen.
Option Explicit
Option Compare Text
Const FoldersPath = "D:\Temp" 'Start-Ordner
Const CsvFileName = "FolderUserRights.csv" 'Wird im Workbook-Pfad gespeichert
Const CsvDelim = ";" 'Beliebiges Trennzeichen festlegen
'______________________________________________________________________________________
'Spalte 1-4 = Path, Erstellungsdatum, Gruppe/Benutzername, G/B-Name-SID
Const CsvTextReserved = 4
'Control-Flag Infos verfügbar
Const SE_DACL_PRESENT = &H4
'Zugriffs-Flags, TitelText nach belieben festlegen
Const AF00 = "AF&;&H01;TitelText" 'OBJECT_INHERIT_ACE
Const AF01 = "AF&;&H02;TitelText" 'CONTAINER_INHERIT_ACE
Const AF02 = "AF&;&H04;TitelText" 'NO_PROPOGATE_INHERIT_ACE
Const AF03 = "AF&;&H08;TitelText" 'INHERIT_ONLY_ACE
Const AF04 = "AF&;&H10;TitelText" 'INHERIT_ACE"
'Zugriffs-Type
Const ATx0 = "AT=;&H00;TitelText" 'ACCESS_ALLOWED_ACE_TYPE
Const AT00 = "AT&;&H01;TitelText" 'ACCESS_DENIED_ACE_TYPE
Const AT01 = "AT&;&H02;TitelText" 'AUDIT
'Zugriffsrechte: Objektspezifisch
Const AM00 = "AM&;&H00000001;TitelText" 'DIR_LIST_DIRECTORY/FILE_READ_DATA
Const AM01 = "AM&;&H00000002;TitelText" 'DIR_ADD_FILE/FILE_WRITE_DATA
Const AM02 = "AM&;&H00000004;TitelText" 'DIR_ADD_SUBDIRECTORY/FILE_APPEND_DATA
Const AM03 = "AM&;&H00000008;TitelText" 'READ_NAMED_ATTRIBUTS
Const AM04 = "AM&;&H00000010;TitelText" 'WRITE_NAMED_ATTRIBUTS
Const AM05 = "AM&;&H00000020;TitelText" 'EXECUTE
Const AM06 = "AM&;&H00000040;TitelText" 'DELETE_CHILD
Const AM07 = "AM&;&H00000080;TitelText" 'READ_ATTRIBUTES
Const AM08 = "AM&;&H00000100;TitelText" 'WRITE_ATTRIBUTES
Const AMx1 = "AM=;&H001F01FF;TitelText" 'FILE_ALL_ACCESS"
'Zugriffsrechte: Standard --> Zugriffsrechte auf Objektspezifisch
Const AM16 = "AM&;&H00010000;TitelText" 'DELETE
Const AM17 = "AM&;&H00020000;TitelText" 'READ_ACL
Const AM18 = "AM&;&H00040000;TitelText" 'WRITE_ACL
Const AM19 = "AM&;&H00080000;TitelText" 'WRITE_OWNER
Const AM20 = "AM&;&H00100000;TitelText" 'SYNCHRONIZE
'Zugriffsrechte: Security-Descriptor SACL (System Access Control List)
Const AM24 = "AM&;&H01000000;TitelText" 'ACCESS_SYSTEM_SECURITY
'Zugriffsrechte Erweitert --> Zugriffsrechte auf Standard/Objektspezifisch
Const AM28 = "AM&;&H10000000;TitelText" 'GENERIC_ALL
Const AM29 = "AM&;&H20000000;TitelText" 'GENERIC_EXECUTE
Const AM30 = "AM&;&H40000000;TitelText" 'GENERIC_WRITE
Const AM31 = "AM&;&H80000000;TitelText" 'GENERIC_READ
'______________________________________________________________________________________
Const Msg0 = "Der Vorgang kann je nach Anzahl der Ordner einige Minuten dauern!"
Const Msg1 = "Der Csv-Export ist abgeschlossen."
Dim Fso As Object, ACL As Object, objWMIService As Object, CsvFile As Object
Dim CsvText As Variant, CsvSize As Integer
Sub GetFoldersAccessRights()
Dim CsvListe As Variant, CsvTitel As Variant, Token As Variant, i As Integer
If MsgBox(Msg0, vbOKCancel Or vbInformation, "Zugriffsrechte...") = vbCancel Then Exit Sub
CsvListe = Array(AF00, AF01, AF02, AF03, AF04, ATx0, AT00, AT01, AM00, AM01, AM02, AM03, AM04, AM05, AM06, AM07, AM08, AM16, AM17, AM18, AM19, AM20, AMx1)
CsvSize = UBound(CsvListe) + CsvTextReserved
ReDim CsvText(CsvSize): ReDim CsvTitel(CsvSize)
Set ACL = CreateObject("Scripting.Dictionary")
CsvTitel(0) = "Pfad"
CsvTitel(1) = "Erstellt"
CsvTitel(2) = "Benutzer"
CsvTitel(3) = "SID"
For i = 0 To UBound(CsvListe)
Token = Split(CsvListe(i), ";")
ACL.Add Token(0) & Hex(Token(1)), i + CsvTextReserved & ";" & Token(1)
CsvTitel(i + CsvTextReserved) = Token(2)
Next
Set Fso = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=Impersonate,(TakeOwnership)}!\\.\root\cimv2")
Set CsvFile = Fso.CreateTextFile(ThisWorkbook.Path & "\" & CsvFileName)
CsvFile.WriteLine Join(CsvTitel, ";")
Call GetFolder(Fso.GetFolder(FoldersPath)): CsvFile.Close
MsgBox Msg1, vbInformation, "Csv-Export..."
End Sub
Private Sub GetFolder(ByRef Folder)
Dim Subfolder As Object, i As Integer
CsvText(0) = Folder.Path
If Folder.Name = "" Then
CsvText(1) = ""
Else
CsvText(1) = FormatDateTime(Folder.DateCreated, vbShortDate)
End If
Call GetSecuritySettings(Folder)
On Error Resume Next
For Each Subfolder In Folder.SubFolders
If Err.Number = 0 Then
Call GetFolder(Subfolder)
Else
Err.Clear
Call WriteCsvFile("Zugriff verweigert")
End If
Next
End Sub
Private Sub GetSecuritySettings(ByRef Folder)
Dim objFSS As Object, objSD As Object, objACL As Variant
Dim LastName As String, DoWrite As Boolean, i As Integer
On Error Resume Next
Set objFSS = objWMIService.Get("Win32_LogicalFileSecuritySetting='" & Folder & "'")
If Err.Number <> 0 Then
Call WriteCsvFile("Nicht verfügbar"): Exit Sub
End If
On Error GoTo 0
If objFSS.GetSecurityDescriptor(objSD) = 0 Then
If (objSD.ControlFlags And SE_DACL_PRESENT) <> 0 Then
For Each objACL In objSD.DACL
With objACL
CsvText(2) = .Trustee.Name
CsvText(3) = .Trustee.SIDString
For i = 4 To CsvSize: CsvText(i) = "": Next
Call SetSecuritySettings("AM", .AccessMask)
Call SetSecuritySettings("AF", .AceFlags)
Call SetSecuritySettings("AT", .AceType)
CsvFile.WriteLine Join(CsvText, CsvDelim)
End With
Next
Else
Call WriteCsvFile("Nicht verfügbar")
End If
Else
Call WriteCsvFile("Nicht verfügbar")
End If
End Sub
Private Sub SetSecuritySettings(ByRef Target, ByVal Value)
Dim Key As Variant, Token As Variant
If ACL.Exists(Target & "=" & Hex(Value)) Then
Token = Split(ACL.Item(Target & "=" & Hex(Value)), ";")
CsvText(Token(0)) = "x"
Else
For Each Key In ACL.Keys
If Left(Key, 3) = Target & "&" Then
Token = Split(ACL.Item(Key), ";")
If (Value And CLng(Token(1))) Then CsvText(Token(0)) = "x"
End If
Next
End If
End Sub
Private Sub WriteCsvFile(ByRef Text)
Dim i As Integer
CsvText(2) = Text
For i = 3 To CsvSize: CsvText(i) = "": Next
CsvFile.WriteLine Join(CsvText, CsvDelim)
End Sub
Gruß Dieter
[edit] geändert [/edit]
Hallo DieDrohne!
Setze mal in der Codezeile 115 und Codezeile 135 ein Kommentarzeichen (Hochkomma) davor.
Gruß Dieter
Setze mal in der Codezeile 115 und Codezeile 135 ein Kommentarzeichen (Hochkomma) davor.
Zitat von @DieDrohne:
P.S.: Was mir grad noch aufgefallen ist. Egal welchen Startordner ich nehme, es steht in den Zeilen 2-4 genau dasselbe drin. Also
er wiederholt die Zeile 2 noch 2 mal und dann geht er erst weiter.
Das kann ich für den Moment leider nicht nachvollziehenP.S.: Was mir grad noch aufgefallen ist. Egal welchen Startordner ich nehme, es steht in den Zeilen 2-4 genau dasselbe drin. Also
er wiederholt die Zeile 2 noch 2 mal und dann geht er erst weiter.
Gruß Dieter
Hallo DieDrohne!
Ersetze die Codezeile 107 mal durch diese Codezeilen, die beim Auftreten des Fehlers den betreffenden Ordner-Pfad in einer MsgBox anzeigt:
Gruß Dieter
PS. Den Teil Mit Csv-Ausgabe (Benutzer...) habe ich im Code (oben) entfernt
Zitat von @DieDrohne:
So habe jetzt wieder die Fehlermeldung:
Ungültiger Objektpfad. Tritt nach ca. 10 Minuten durchlaufen erst auf.
Nach dem ich auf Debuggen gegangen bin, führte er mich zur Zeile:
So habe jetzt wieder die Fehlermeldung:
Ungültiger Objektpfad. Tritt nach ca. 10 Minuten durchlaufen erst auf.
Nach dem ich auf Debuggen gegangen bin, führte er mich zur Zeile:
Set objFSS = objWMIService.Get("Win32_LogicalFileSecuritySetting='" & Folder & "'") |
Ersetze die Codezeile 107 mal durch diese Codezeilen, die beim Auftreten des Fehlers den betreffenden Ordner-Pfad in einer MsgBox anzeigt:
On Error Resume Next
Set objFSS = objWMIService.Get("Win32_LogicalFileSecuritySetting='" & Folder & "'")
If Err.Number <> 0 Then MsgBox Folder
On Error GoTo 0
Gruß Dieter
PS. Den Teil Mit Csv-Ausgabe (Benutzer...) habe ich im Code (oben) entfernt
Hallo DieDrohne!
Und noch ne Frage, ich habe sehr viele Ordner, kann es zu einem Überlauf kommen wo er dann abschaltet und mir eine Meldung
ausgibt "Vorgang abgebrochen"?
Das sollte meines Wissens nicht passieren?
Gruß Dieter
Zitat von @DieDrohne:
Ich habs rausgenommen und jetzt listet er mir alle auf, ok er versuchts. Keine Ahnung warum, aber er bricht bei
übergeordneten Ordnern bei 1-2 Einträgen ab und untergeordnete bei 2 Einträgen und geht dann schon zum
nächsten Ordner.
Kommt da irgendeine Meldung "Zugriff verweigert" sowas in der Art?Ich habs rausgenommen und jetzt listet er mir alle auf, ok er versuchts. Keine Ahnung warum, aber er bricht bei
übergeordneten Ordnern bei 1-2 Einträgen ab und untergeordnete bei 2 Einträgen und geht dann schon zum
nächsten Ordner.
Kann ich irgendwo einstellen, wie oft er durchläuft oder macht er das von sich aus.
Verstehe ich jetzt irgendwie nicht so ganz?Und noch ne Frage, ich habe sehr viele Ordner, kann es zu einem Überlauf kommen wo er dann abschaltet und mir eine Meldung
ausgibt "Vorgang abgebrochen"?
Gruß Dieter
Hallo DieDrohne!
Ok, werde ich morgen eine entsprechende Fehlerbehandlung mit einbauen, wobei diese Ordner dann übersprungen werden.
Gruß Dieter
Ok, werde ich morgen eine entsprechende Fehlerbehandlung mit einbauen, wobei diese Ordner dann übersprungen werden.
Gruß Dieter
Hallo André!
Den Code habe ich nochmal ab Codezeile 60 komplett geändert.
Dabei wird in der Spalte Benutzer dann bei Zugriffsverweigerung "Zugriff verweigert" eingetragen. In anderen Fällen wird "Nicht verfügbar" eingetragen
Zu Beginn kommt jetzt noch eine MsgBox, die darauf hinweist, dass der Vorgange je nach Ordner-Anzahl einige Minuten dauern kann.
Gruß Dieter
Den Code habe ich nochmal ab Codezeile 60 komplett geändert.
Dabei wird in der Spalte Benutzer dann bei Zugriffsverweigerung "Zugriff verweigert" eingetragen. In anderen Fällen wird "Nicht verfügbar" eingetragen
Zu Beginn kommt jetzt noch eine MsgBox, die darauf hinweist, dass der Vorgange je nach Ordner-Anzahl einige Minuten dauern kann.
Da ist aber immer noch eine Sache die ich nicht verstehe. Er listet mir zu 99% die Ordner auf und gibt 2 eingetragene Benutzer aus. Es sind aber mindestens bei
jedem Ordner 7 Sicherheitsgruppen mit unterschiedlichen Rechten eingetragen. Auf manche Ordner müssen noch mehr Kollegen darauf zugreifen, dann werden es
auch mal schnell 10-15 noch zusätzlich eingetragene Personen.
Dazu habe ich leider keine Ideejedem Ordner 7 Sicherheitsgruppen mit unterschiedlichen Rechten eingetragen. Auf manche Ordner müssen noch mehr Kollegen darauf zugreifen, dann werden es
auch mal schnell 10-15 noch zusätzlich eingetragene Personen.
Gruß Dieter
Hallo André!
Aja, danke für den Hinweis Muss ich mir heute Abend oder morgen nochmal ansehen.
Gruß Dieter
Aja, danke für den Hinweis Muss ich mir heute Abend oder morgen nochmal ansehen.
Gruß Dieter
Hallo André!
Also, ich hatte tatsächlich einen Denkfehler
Allerdings stimmt Deine Code-Änderung auch nicht Da fehlen ebenfalls wieder Einträge.
Ich hatte leider nur auf meiner Daten-Partition getestet und da ist es so, dass für System, Admin, Benutzer.. immer 2 Datensätze zurückgegeben werden. Von daher dachte ich, dass dies generell so wäre, was aber leider ein Irtum war. Deswegen hatte ich den Code so geschrieben, das erst mit dem 2. Datensatz eine Zeile in die Csv-Datei geschrieben wird, was in diesem Fall auch funktioniert hat.
Bei einem weiteren Test auf meiner W7-Partition ist mir das leider jetzt erst aufgefallen
Den Code oben habe ich jetzt nochmal so geändert, dass jeder Datensatz in die Csv-Datei geschrieben wird, wobei allerdings für System, Admin... dann teilweise wieder 2 Datensätze (sprich 2 Zeilen) ausgegeben werden.
Gut das ich den Code mal auf meiner W7-Partition hab laufen lassen. Dabei ist mir nämlich erst aufgefallen, dass mein Win7 2 Endlos-Ordnerstrukturen enthält z.B.
Bei 260 MB mit fast 1 Million Zeilen habe ich dann mal abgebrochen
Nach Behebung des Problems hat das Auslesen meiner Win7-Partition mit ca 26.000 Ordnern ca 15 Minuten gedauert, wobei die Csv-Datei eine Größe von rund 20 MB erreichte (ca 118.000 Zeilen).
Gruß Dieter
[edit] Kommentar aktualisiert [/edit]
Also, ich hatte tatsächlich einen Denkfehler
Allerdings stimmt Deine Code-Änderung auch nicht Da fehlen ebenfalls wieder Einträge.
Ich hatte leider nur auf meiner Daten-Partition getestet und da ist es so, dass für System, Admin, Benutzer.. immer 2 Datensätze zurückgegeben werden. Von daher dachte ich, dass dies generell so wäre, was aber leider ein Irtum war. Deswegen hatte ich den Code so geschrieben, das erst mit dem 2. Datensatz eine Zeile in die Csv-Datei geschrieben wird, was in diesem Fall auch funktioniert hat.
Bei einem weiteren Test auf meiner W7-Partition ist mir das leider jetzt erst aufgefallen
Den Code oben habe ich jetzt nochmal so geändert, dass jeder Datensatz in die Csv-Datei geschrieben wird, wobei allerdings für System, Admin... dann teilweise wieder 2 Datensätze (sprich 2 Zeilen) ausgegeben werden.
Gut das ich den Code mal auf meiner W7-Partition hab laufen lassen. Dabei ist mir nämlich erst aufgefallen, dass mein Win7 2 Endlos-Ordnerstrukturen enthält z.B.
C:\Users\Default User\Lokale Einstellungen\Anwendungsdaten\Anwendungsdaten\Anwendungsdaten\Endlos..... |
Nach Behebung des Problems hat das Auslesen meiner Win7-Partition mit ca 26.000 Ordnern ca 15 Minuten gedauert, wobei die Csv-Datei eine Größe von rund 20 MB erreichte (ca 118.000 Zeilen).
Gruß Dieter
[edit] Kommentar aktualisiert [/edit]
Hallo André!
Gruß Dieter
Zitat von @DieDrohne:
Aber da ist immer noch eine Sache, Kann man den umschreiben das er ein 2. Tabellenblatt in der aktuellen Exceldatei automatisch
befüllt, ohne den Umweg über eine csv Datei zu machen?
Ja, dass wäre im Prinzip keine große Sache. Hierbei besteht allerdings, je nach Anzahl der Ordner, die Gefahr eines Überlaufs (Max-Zeilen).Aber da ist immer noch eine Sache, Kann man den umschreiben das er ein 2. Tabellenblatt in der aktuellen Exceldatei automatisch
befüllt, ohne den Umweg über eine csv Datei zu machen?
Gruß Dieter
Hallo André!
Hier der neue Code, der die Daten in die Arbeitsmappe schreibt.
Schritt 1:
Jenachdem, ob die Arbeitsmappe bereits Tabellen beinhaltet oder nicht, muss eine Tabelle mit dem Namen angelegt werden, der der Konstanten SheetName entspricht und am Ende muss die Ziffer 1 stehen z.B Tabelle1, Liste1...
Schritt 2:
Die Konstante StartLine besagt, dass die Rechte ab dieser Zeile eingetragen werden. Die Überschrift wird jedoch in die Zeile 1 eingetragen.
Sofern eine Tabelle mit dem Namen (SheetName) existiert, wobei ich jetzt als Beispiel den Namen Rechte1 verwende, dann ist der weitere Ablauf in etwa so:
Beim Start des Makro, wird eine CleanUp-Funktion durchgeführt, in der alle Sheets, die dem Namen Rechte entsprechen - mit Ausnahme von Rechte1 - gelöscht werden.
Im weiteren Verlauf werden je nach Bedarf, automatisch weitere Sheets in fortlaufender Reihenfolge und hintereinander angelegt z.B. Rechte1, Rechte2 usw.
In der Schluss-Meldung wird noch zusätzlich die Gesamtzahl der eingelesenen Ordner mit ausgegeben.
Neuer Code:
Gruß Dieter
Hier der neue Code, der die Daten in die Arbeitsmappe schreibt.
Schritt 1:
Jenachdem, ob die Arbeitsmappe bereits Tabellen beinhaltet oder nicht, muss eine Tabelle mit dem Namen angelegt werden, der der Konstanten SheetName entspricht und am Ende muss die Ziffer 1 stehen z.B Tabelle1, Liste1...
Schritt 2:
Die Konstante StartLine besagt, dass die Rechte ab dieser Zeile eingetragen werden. Die Überschrift wird jedoch in die Zeile 1 eingetragen.
Sofern eine Tabelle mit dem Namen (SheetName) existiert, wobei ich jetzt als Beispiel den Namen Rechte1 verwende, dann ist der weitere Ablauf in etwa so:
Beim Start des Makro, wird eine CleanUp-Funktion durchgeführt, in der alle Sheets, die dem Namen Rechte entsprechen - mit Ausnahme von Rechte1 - gelöscht werden.
Im weiteren Verlauf werden je nach Bedarf, automatisch weitere Sheets in fortlaufender Reihenfolge und hintereinander angelegt z.B. Rechte1, Rechte2 usw.
In der Schluss-Meldung wird noch zusätzlich die Gesamtzahl der eingelesenen Ordner mit ausgegeben.
Neuer Code:
Option Explicit
Option Compare Text
Const FoldersPath = "C:\" 'Start-Ordner
Const SheetName = "Rechte1" 'Tabellenname wahlweise, am Ende muss die Ziffer 1 stehen
Const StartLine = 2 'Ab Zeile
'______________________________________________________________________________________
'Spalte 1-4 = Path, Erstellungsdatum, Gruppe/Benutzername, G/B-Name-SID
Const TextReserved = 4
'Control-Flag Infos verfügbar
Const SE_DACL_PRESENT = &H4
'Zugriffs-Flags, TitelText nach belieben festlegen
Const AF00 = "AF&;&H01;TitelText" 'OBJECT_INHERIT_ACE
Const AF01 = "AF&;&H02;TitelText" 'CONTAINER_INHERIT_ACE
Const AF02 = "AF&;&H04;TitelText" 'NO_PROPOGATE_INHERIT_ACE
Const AF03 = "AF&;&H08;TitelText" 'INHERIT_ONLY_ACE
Const AF04 = "AF&;&H10;TitelText" 'INHERIT_ACE"
'Zugriffs-Type
Const ATx0 = "AT=;&H00;TitelText" 'ACCESS_ALLOWED_ACE_TYPE
Const AT00 = "AT&;&H01;TitelText" 'ACCESS_DENIED_ACE_TYPE
Const AT01 = "AT&;&H02;TitelText" 'AUDIT
'Zugriffsrechte: Objektspezifisch
Const AM00 = "AM&;&H00000001;TitelText" 'DIR_LIST_DIRECTORY/FILE_READ_DATA
Const AM01 = "AM&;&H00000002;TitelText" 'DIR_ADD_FILE/FILE_WRITE_DATA
Const AM02 = "AM&;&H00000004;TitelText" 'DIR_ADD_SUBDIRECTORY/FILE_APPEND_DATA
Const AM03 = "AM&;&H00000008;TitelText" 'READ_NAMED_ATTRIBUTS
Const AM04 = "AM&;&H00000010;TitelText" 'WRITE_NAMED_ATTRIBUTS
Const AM05 = "AM&;&H00000020;TitelText" 'EXECUTE
Const AM06 = "AM&;&H00000040;TitelText" 'DELETE_CHILD
Const AM07 = "AM&;&H00000080;TitelText" 'READ_ATTRIBUTES
Const AM08 = "AM&;&H00000100;TitelText" 'WRITE_ATTRIBUTES
Const AMx1 = "AM=;&H001F01FF;TitelText" 'FILE_ALL_ACCESS"
'Zugriffsrechte: Standard --> Zugriffsrechte auf Objektspezifisch
Const AM16 = "AM&;&H00010000;TitelText" 'DELETE
Const AM17 = "AM&;&H00020000;TitelText" 'READ_ACL
Const AM18 = "AM&;&H00040000;TitelText" 'WRITE_ACL
Const AM19 = "AM&;&H00080000;TitelText" 'WRITE_OWNER
Const AM20 = "AM&;&H00100000;TitelText" 'SYNCHRONIZE
'Zugriffsrechte: Security-Descriptor SACL (System Access Control List)
Const AM24 = "AM&;&H01000000;TitelText" 'ACCESS_SYSTEM_SECURITY
'Zugriffsrechte Erweitert --> Zugriffsrechte auf Standard/Objektspezifisch
Const AM28 = "AM&;&H10000000;TitelText" 'GENERIC_ALL
Const AM29 = "AM&;&H20000000;TitelText" 'GENERIC_EXECUTE
Const AM30 = "AM&;&H40000000;TitelText" 'GENERIC_WRITE
Const AM31 = "AM&;&H80000000;TitelText" 'GENERIC_READ
'______________________________________________________________________________________
Const Msg0 = "Der Vorgang kann je nach Anzahl der Ordner einige Minuten dauern!"
Const Msg1 = "Das Einlesen der Rechte aus %1 Ordnern ist abgeschlossen."
Dim Fso As Object, ACL As Object, objWMIService As Object, TextLine As Variant, TitelLine As Variant
Dim TextSize As Long, CellSize As Long, FoldersCount As Long, NewLine As Long, EndLine As Long
Sub GetFoldersAccessRights()
Dim TextList As Variant, Token As Variant, i As Integer
If MsgBox(Msg0, vbOKCancel Or vbInformation, "Zugriffsrechte...") = vbCancel Then Exit Sub
TextList = Array(AF00, AF01, AF02, AF03, AF04, ATx0, AT00, AT01, AM00, AM01, AM02, AM03, AM04, AM05, AM06, AM07, AM08, AM16, AM17, AM18, AM19, AM20, AMx1)
TextSize = UBound(TextList) + TextReserved: CellSize = TextSize + 1
ReDim TextLine(TextSize): ReDim TitelLine(TextSize)
Set ACL = CreateObject("Scripting.Dictionary")
TitelLine(0) = "Pfad"
TitelLine(1) = "Erstellt"
TitelLine(2) = "Benutzer"
TitelLine(3) = "SID"
For i = 0 To UBound(TextList)
Token = Split(TextList(i), ";")
ACL.Add Token(0) & Hex(Token(1)), i + TextReserved & ";" & Token(1)
TitelLine(i + TextReserved) = Token(2)
Next
Set Fso = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=Impersonate,(TakeOwnership)}!\\.\root\cimv2")
FoldersCount = 0
Call CleanUpSheets
Range(Range("A1"), Cells(1, CellSize)) = TitelLine
Call GetFolder(Fso.GetFolder(FoldersPath))
MsgBox Replace(Msg1, "%1", FoldersCount), vbInformation, "Rechte einlesen..."
End Sub
Private Sub GetFolder(ByRef Folder)
Dim Subfolder As Object, i As Integer
TextLine(0) = Folder.Path
If Folder.Name = "" Then
TextLine(1) = ""
Else
TextLine(1) = FormatDateTime(Folder.DateCreated, vbShortDate)
End If
Call GetSecuritySettings(Folder)
On Error Resume Next
For Each Subfolder In Folder.SubFolders
If Err.Number = 0 Then
Call GetFolder(Subfolder)
Else
Err.Clear
Call WriteText("Zugriff verweigert")
End If
Next
End Sub
Private Sub GetSecuritySettings(ByRef Folder)
Dim objFSS As Object, objSD As Object, objACL As Variant
Dim LastName As String, DoWrite As Boolean, i As Integer
FoldersCount = FoldersCount + 1
On Error Resume Next
Set objFSS = objWMIService.Get("Win32_LogicalFileSecuritySetting='" & Folder & "'")
If Err.Number <> 0 Then
Call WriteText("Nicht verfügbar"): Exit Sub
End If
On Error GoTo 0
If objFSS.GetSecurityDescriptor(objSD) = 0 Then
If (objSD.ControlFlags And SE_DACL_PRESENT) <> 0 Then
For Each objACL In objSD.DACL
With objACL
TextLine(2) = .Trustee.Name
TextLine(3) = .Trustee.SIDString
For i = 4 To TextSize: TextLine(i) = "": Next
Call SetSecuritySettings("AM", .AccessMask)
Call SetSecuritySettings("AF", .AceFlags)
Call SetSecuritySettings("AT", .AceType)
If NewLine > EndLine Then Call CreateNewSheet
Range(Cells(NewLine, 1), Cells(NewLine, CellSize)) = TextLine: NewLine = NewLine + 1
End With
Next
Else
Call WriteText("Nicht verfügbar")
End If
Else
Call WriteText("Nicht verfügbar")
End If
End Sub
Private Sub SetSecuritySettings(ByRef Target, ByVal Value)
Dim Key As Variant, Token As Variant
If ACL.Exists(Target & "=" & Hex(Value)) Then
Token = Split(ACL.Item(Target & "=" & Hex(Value)), ";")
TextLine(Token(0)) = "x"
Else
For Each Key In ACL.Keys
If Left(Key, 3) = Target & "&" Then
Token = Split(ACL.Item(Key), ";")
If (Value And CLng(Token(1))) Then TextLine(Token(0)) = "x"
End If
Next
End If
End Sub
Private Sub WriteText(ByRef Text)
Dim i As Integer
TextLine(2) = Text
For i = 3 To TextSize: TextLine(i) = "": Next
If NewLine > EndLine Then Call CreateNewSheet
Range(Cells(NewLine, 1), Cells(NewLine, CellSize)) = TextLine: NewLine = NewLine + 1
End Sub
Private Sub CleanUpSheets()
Dim Wks As Worksheet
ThisWorkbook.Activate
Sheets(SheetName).Cells.Clear
For Each Wks In Sheets
If Wks.Name Like Left(SheetName, Len(SheetName) - 1) & "[!1]" Then
Application.DisplayAlerts = False
Wks.Delete
Application.DisplayAlerts = True
End If
Next
Sheets(SheetName).Activate: Range("A1").Select
NewLine = StartLine: EndLine = Rows.Count
End Sub
Private Sub CreateNewSheet()
Dim LastNumber As Integer, LastName As String
LastName = ActiveSheet.Name
LastNumber = Right(LastName, 1)
Sheets.Add After:=ActiveSheet
ActiveSheet.Name = Replace(LastName, LastNumber, LastNumber + 1)
Range(Range("A1"), Cells(1, CellSize)) = TitelLine
NewLine = StartLine
End Sub
Gruß Dieter
Hallo André!
Freut mich zu hören
Dann fehlt ja nur noch das grüne Gelöst-Häkchen
Gruß Dieter
Freut mich zu hören
Danke Danke Danke!
Yepp, gern geschehenDann fehlt ja nur noch das grüne Gelöst-Häkchen
Gruß Dieter
Hallo zusammen
Da hier schon seit mehr als zwei Jahren Funkstille herrscht, bin ich mir nicht sicher, ob ich eine Antwort bekomme. Ich versuchs mal und bin dankbar, wenn mir jemand, der mehr von der Sache verstehet, weiterhilft.
Das Script hier würde genau das machen, das ich benötige. Lokal funktioniert das auch 1A. Sobald ich es aber auf Netzlaufwerke anwende, bekommen ich beim Benutzer nur ein "Nicht verfügbar". Dabei spielt es keine Rolle, ob ich es von meinem Rechner aus mache, oder ob es auf einem Server ausgeführt wird. Was mach ich falsch.
Beste Dank im Voraus
ZurigoX
Da hier schon seit mehr als zwei Jahren Funkstille herrscht, bin ich mir nicht sicher, ob ich eine Antwort bekomme. Ich versuchs mal und bin dankbar, wenn mir jemand, der mehr von der Sache verstehet, weiterhilft.
Das Script hier würde genau das machen, das ich benötige. Lokal funktioniert das auch 1A. Sobald ich es aber auf Netzlaufwerke anwende, bekommen ich beim Benutzer nur ein "Nicht verfügbar". Dabei spielt es keine Rolle, ob ich es von meinem Rechner aus mache, oder ob es auf einem Server ausgeführt wird. Was mach ich falsch.
Beste Dank im Voraus
ZurigoX