none
Set-ACL, FileSystemRights werden nicht gesetzt RRS feed

  • Frage

  • Ich möchte gerne von einem Pfad auf Server A die ACL kopieren und auf einem Pfad auf Server B einfügen. Dafür habe ich eine PowerShell function geschrieben.

    Erst hatte ich etwas rudimentäres probiert in diesem stil get-acl C:\serverA\inetpub | set-acl D:\serverB\inetpub Das kann jedoch nicht funktionieren, da "IUSR, IISAPPPOOL virtual accounts etc. are all local to the machine's Security Account Manager database. They don't exist across multiple servers."

    Deshalb schreibe ich mir in meiner Function nun alles raus was get-acl outputet. Mein Problem ist nun, dass die FileSystemRights einfach nicht übernommen werden. Ich habe es auch mal mit 2 lokalen Pfaden auf meinem C:\ probiert, auch dort werden die FileSystemRights nicht übernommen. Der User wird aber erstellt in der ACL, jedoch ohne Berechtigung. (Bsp, auf Server A Pfad X hat IUSR "Read, Write" Berechtigung, auf Server B Pfad Y hat der User noch keine Berechtigung, er wird nun hinzugefügt, das "Read, Write" wird jedoch nicht deployed)

    Hier der Code:

    function Equate-ACL {
    param(
        [Parameter(Mandatory=$true,Position=0)]
        [string]$SourcePath,
        [Parameter(Mandatory=$true,Position=1)]
        [string]$DestinationPath
    )
    Begin {
        # Check if path exists and if access rights are correct
        if(!(Test-Path $SourcePath)) {
        Throw "Source Path does not exist or you don't have access rights."
        }
        if(!(Test-Path $DestinationPath)) {
        Throw "Destination Path does not exist or you don't have access rights."
        }
    }
    Process {
    # get ACL from source path
        $gacl = get-acl $SourcePath | select -ExpandProperty Access | % {
        $ErrorActionPreference = "SilentlyContinue"
        [string]$user = ($_.IdentityReference).Value.split('\')[1]
        $AccessType = $_.AccessControlType
        $FSRights = $_.FileSystemRights

        if (!$user) { Write-Warning "User not found. Skipping ACL settings for this user.
                                     Username: $(($_.IdentityReference).Value)`n"}
        else{
        # Create ACL Object
        $colRights = [System.Security.AccessControl.FileSystemRights]$FSRights
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]$AccessType
        $objUser = New-Object System.Security.Principal.NTAccount($user)
        $objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
                  ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)

        # Set the ACL
        Write-Host "Setting ACL for User: $User on $DestinationPath" -ForegroundColor Green
        $objACL = get-acl $DestinationPath
        $ErrorActionPreference = "Stop"
        Try {
            $objACL.AddAccessRule($objACE)
            $objACL | set-acl $DestinationPath
            Write-Host "Success!`n" -ForegroundColor Green
        } Catch {
            Write-Host "Failed! ErrorMessage:" -ForegroundColor Red
            $_.Exception.Message
        }}
    }}}

    Ich habe ernsthaft das Gefühl das ich hier Pionier-Arbeit leiste, da mir Google, Stackoverflow etc. keine Antwort auf meine Frage geben können. Das Technet ist also mein "Last Resort"

    Danke und Grüsse

    Simon

    Mittwoch, 27. Juli 2016 07:37

Antworten

Alle Antworten

  • > Ich habe ernsthaft das Gefühl das ich hier Pionier-Arbeit leiste, da mir
     
    Dann suchst Du anders als ich :-))
     
     
    Der erste Treffer sieht doch vielversprechend aus.
     
    • Als Antwort markiert Simon Stauber Mittwoch, 27. Juli 2016 09:33
    Mittwoch, 27. Juli 2016 09:01
  • Simon, nochh ne kurze Anmerkung zum Gesamtaufbau der Funktion:
     
    function Equate-ACL {
    param(
     
    )
    Begin {
        }
    }
    Process {
        }
    }
     
    Du weißt, wofür Begin und Process benötigt werden? Das nutzt man, wenn
    man eine Funktion braucht, die man per Pipeline mit Werten füttern will
    (oder der man gleich ein ganzes Array von Parametern übergibt).
     
    Begin wird dann nur einmal ausgeführt, Process für jeden Wert in der
    Pipeline. Danach käme optional noch End für ein einmaliges Cleanup.
     
     
    Bei Dir paßt das aber nicht - wenn ich der Funktion ein Array von Source
    und Destination übergebe, dann würde dein Begin-Block für das erste
    Wertepaar das Vorhandensein überprüfen, für alle weiteren nicht mehr :-)
     
    Und da Du die Parameter nicht als Pipeline-Input definiert hast,
    brauchst Du Begin/Process eigentlich gar nicht.
     
    Mittwoch, 27. Juli 2016 09:07
  • > Ich habe ernsthaft das Gefühl das ich hier Pionier-Arbeit leiste, da mir
     
    Dann suchst Du anders als ich :-))
     
     
    Der erste Treffer sieht doch vielversprechend aus.
     

    Oha. Das ist ein unglaublich tolles Modul. aus meiner riesen funktion wurde jetzt ein one liner:

    $sourcepath | Get-NTFSAccess | Add-NTFSAccess $destinationpath

    Zu meiner Verteidigung: Ich habe immer nach "wie behebe ich meinen Fehler" gesucht, du hast eher von 0 gesucht, nach einem Modul das die Arbeit für mich macht. Super Sache. Danke dir

    Das mit dem Begin {} Process {} wusste ich tatsächlich nicht, danke für die Erklärung. Ich dachte immer das sei nur zur Übersicht, eine dunkle Vorahnung in mir wusste jedoch, das dies fast nicht sein kann ;-)

    Danke dir!

    Mittwoch, 27. Juli 2016 09:33
  • > Zu meiner Verteidigung: Ich habe immer nach "wie behebe ich meinen
    > Fehler" gesucht, du hast eher von 0 gesucht, nach einem Modul das die
    > Arbeit für mich macht. Super Sache. Danke dir
     
    Kenn ich - man beißt sich so rein, daß man nicht mehr "Zurück auf Los"
    hinbekommt :-))
     
    Und zu Deiner Verteidigung auch noch: Ich kannte das Modul bereits - wir
    hatten hier auch schon erquickliche Versuche von Kollegen, das mit
    get-acl und set-acl oder sogar direkt mit .NET Klassen zu machen. Der
    Code wird unendlich lang und beliebig kompliziert :-)
     
    Mittwoch, 27. Juli 2016 10:14