none
Abfangen von Fehlern bei get-acl und dafür Fehlertext in einer pipe übergeben. RRS feed

  • Frage

  • Mittels Powershell versuche ich die ACL von Server Shares auszulesen. In etwa so:

    get-childitem \\SERVER\SHARE | get-acl $_.pspath

    Das funktioniert ja auch ganz gut. Jedoch sollte ich auf einem Pfad keine Rechte haben so stoppt alles. Daher habe ich diese Änderung vorgenommen:

    get-childitem \\SERVER\SHARE | %{ echo "ERROR"  ; continue } ; get-acl $_.pspath } | ...

     

    Bei einem Fehler stoppt nun nur noch der einzelne get-acl und ich erhalte durch das trap Statement den Text "ERROR". Problem ist nun, dass dieser Text nur auf der console landet. Wenn ich das ganze aber später z. B. mit export-csv in eine Tabelle schreiben will fehlen die fehlerhaften Zeilen komplett. Ich hätte aber lieber z.B. den Pfad und Dateinamen wie für alle anderen 'guten' Einträge auch und Daten, die ich nicht erhalten habe mit dem Wort "<ERROR>" gekennzeichnet.

     

    Hier ein Beispiel CSV output wie ich gerne hätte:

     

    Path IdentityReference AccessControlType FileSystemRights
    \\server\users\user1 domain\user1 Allow FullControl
    \\server\users\user2 <ERROR> <ERROR> <ERROR>

    Die Daten wie sie für user1 angezeigt werden bekomme ich wunderbar mit meinen Script. Für User2 hätte ich z.B. nicht die Berechtigung die Filerechte auszulesen. Hier hätte ich gerne das Wort "<ERROR>" innerhalb der Pipe in das Object ein geflickt. Wie geht das?

    Montag, 6. Februar 2012 16:05

Antworten

  • Get-ACL hat eine bekannte macke, selbst mit ErrorAction SilentlyContinue wirst du die Fehler nicht weg bekommen.
    Ein gutes Tool um dies auch hinzubekommen ist AccessChk von Windows Sysinternals
    http://technet.microsoft.com/de-de/sysinternals/bb664922

    sieh dort auch: AccessEnum und ShareEnum

    Für eine bessere ACL verarbeitung mit PowerShell empfehle ich dir die Tools von Reimund Andree (ist deutscher).
    http://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85

    $ACLInfos = @()
    get-childitem c:\windows | foreach {
        # für jede Datei die ACL holen
    	$ACL = get-acl $_.pspath
            # abfragen ob Get-ACL erfolgreich war
    		If (!$?) {
    			# Get-Acl war nicht erfolgreich (Access denied)
    			# neues ACL info Object mit ERROR erstellen und dem Array hinzufügen
                $ACLInfos += new-object -typename PSobject -Property @{Path = $_.FullName ; IdentityReference = "Error" ; AccessControlType = "Error" ; FileSystemRights = "Error"}
            } else {
    			# Get-Acl war erfolgreich
                $Path = $_.FullName
    			# für jede Access Rule ein eigenes Object erstellen und dem Array hinzufügen 
                $ACL.access | % { $ACLInfos += new-object -typename PSobject -Property @{
                        	Path = $Path ;
                        	IdentityReference = $_.IdentityReference ;
                       		AccessControlType = $_.AccessControlType ;
                        	FileSystemRights = $_.FileSystemRights
                    		}
    					}
            }
        }
    # Access Rules ausgeben (müsste auch mit Out-File funktionieren)
    $ACLInfos | Export-Csv -path "C:\temp\ServerName.csv"  -NoTypeInformation -Delimiter ";"


    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info

    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace" "




    • Bearbeitet Peter Kriegel Dienstag, 7. Februar 2012 10:10
    • Als Antwort markiert qwerty3654 Dienstag, 7. Februar 2012 12:53
    Dienstag, 7. Februar 2012 08:36
  • In einem Object die Propertys zu sortieren macht keinen Sinn!

    einfach die ausgabezeile so ändern:

    # Access Rules ausgeben (müsste auch mit Out-File funktionieren)
    $ACLInfos | select Path,IdentityReference,FileSystemRights,AccessControlType |  Export-Csv -path "C:\temp\ServerName.csv"  -NoTypeInformation -Delimiter ";"


    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info

    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace" "

    Dienstag, 7. Februar 2012 12:19

Alle Antworten

  • Get-ACL hat eine bekannte macke, selbst mit ErrorAction SilentlyContinue wirst du die Fehler nicht weg bekommen.
    Ein gutes Tool um dies auch hinzubekommen ist AccessChk von Windows Sysinternals
    http://technet.microsoft.com/de-de/sysinternals/bb664922

    sieh dort auch: AccessEnum und ShareEnum

    Für eine bessere ACL verarbeitung mit PowerShell empfehle ich dir die Tools von Reimund Andree (ist deutscher).
    http://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85

    $ACLInfos = @()
    get-childitem c:\windows | foreach {
        # für jede Datei die ACL holen
    	$ACL = get-acl $_.pspath
            # abfragen ob Get-ACL erfolgreich war
    		If (!$?) {
    			# Get-Acl war nicht erfolgreich (Access denied)
    			# neues ACL info Object mit ERROR erstellen und dem Array hinzufügen
                $ACLInfos += new-object -typename PSobject -Property @{Path = $_.FullName ; IdentityReference = "Error" ; AccessControlType = "Error" ; FileSystemRights = "Error"}
            } else {
    			# Get-Acl war erfolgreich
                $Path = $_.FullName
    			# für jede Access Rule ein eigenes Object erstellen und dem Array hinzufügen 
                $ACL.access | % { $ACLInfos += new-object -typename PSobject -Property @{
                        	Path = $Path ;
                        	IdentityReference = $_.IdentityReference ;
                       		AccessControlType = $_.AccessControlType ;
                        	FileSystemRights = $_.FileSystemRights
                    		}
    					}
            }
        }
    # Access Rules ausgeben (müsste auch mit Out-File funktionieren)
    $ACLInfos | Export-Csv -path "C:\temp\ServerName.csv"  -NoTypeInformation -Delimiter ";"


    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info

    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace" "




    • Bearbeitet Peter Kriegel Dienstag, 7. Februar 2012 10:10
    • Als Antwort markiert qwerty3654 Dienstag, 7. Februar 2012 12:53
    Dienstag, 7. Februar 2012 08:36
  • Ok, das hat dann schon mal ein gutes Stück weitergeholfen. Ich hatte zunächst versucht anhand des obigen Beispiels über den originalen typename von get-acl meine Fehlermeldung in den selben stream zu schreiben. Aber anscheinend get das mit dem typename "System.Security.AccessControl.DirectorySecurity" nicht: 

    PS C:\Users\User1> new-object -typename System.Security.AccessControl.DirectorySecurity -property @{Path="<ERROR>"}

    New-Object : The value supplied is not valid, or the property is read-only. Change the value, and then try again.
    At line:1 char:11
    + new-object <<<<  -typename System.Security.AccessControl.DirectorySecurity -property @{Path="<ERROR>"}
        + CategoryInfo          : InvalidData: (:) [New-Object], Exception
        + FullyQualifiedErrorId : InvalidValue,Microsoft.PowerShell.Commands.NewObjectCommand

    Könnte man dirkt den typename "System.Security.AccessControl.DirectorySecurity" nehmen würde das ein paar Zeilen code und Ausführungszeit sparen. Aber egal, habe dann mein script ziemlich genau so gemacht wie das Beispiel und es funktioniert so auch gut. Vielen Dank an dieser Stelle.

    Ein Problem hätte ich aber noch. Ich habe das custom object so definiert:

    $ACL_LIST += new-object -typename PSobject -Property @{
       Path = convert-path $_.PATH ;
       IdentityReference = $_.IdentityReference ;
       AccessControlType = $_.AccessControlType ;
       FileSystemRights = $_.FileSystemRights
    }

    Also die Reihenfolge beim definieren ist:

        Path, IdentityReference, AccessControlType, FileSystemRights.

    Wenn ich dieses Objekt dann nach html oder csv exportiere ist die Reihenfolge in der Tabelle aber (siehe auch Beispiel weiter unten):

        FileSystemRights, Path, AccessControlType, IdentityReference.

    Gibt es eine Möglichkeit direkt beim definieren des Hash Array die Reihenfolge der Spalten festzulegen?

    PS C:\Users\User1> new-object -typename PSobject -Property @{Path = "test1" ; IdentityReference = "test2" ; AccessControlType = "test3" ; FileSystemRights = "test4" }

    FileSystemRights              Path                          AccessControlType             IdentityReference
    ----------------              ----                          -----------------             -----------------
    test4                         test1                         test3                         test2



    Dienstag, 7. Februar 2012 11:49
  • In einem Object die Propertys zu sortieren macht keinen Sinn!

    einfach die ausgabezeile so ändern:

    # Access Rules ausgeben (müsste auch mit Out-File funktionieren)
    $ACLInfos | select Path,IdentityReference,FileSystemRights,AccessControlType |  Export-Csv -path "C:\temp\ServerName.csv"  -NoTypeInformation -Delimiter ";"


    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info

    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace" "

    Dienstag, 7. Februar 2012 12:19
  • Ok, hatte ich mir schon gedacht. Werde mir die Tabelle per select zusammenbauen. Nochmal besten Dank für die Unterstützung.
    Dienstag, 7. Februar 2012 12:53