2012-06-10 8 views
5

nicht propagieren Wenn ich eine neue filesystemaccess Regel mit Powershell und Set-acl gesetzt, stelle ich die Vererbungsflags auf Kinder zu propagieren und BlattobjekteÄndern der Berechtigungen mit Powershell nicht auf Kinder

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
    "username","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))) 
Set-Acl -path $filename -aclObject $acl 

Wenn ich mir anschaue, die Erlaubnis in Explorer .. in der Registerkarte Sicherheit .. erweiterte .. die Ausbreitung ist richtig eingestellt. Aber wenn ich die Kinder selbst betrachte, zeigen sie NICHT die neue Sicherheitsregel.

Wenn ich im Explorer, eine andere Regel mit einer anderen SID hinzufügen .. und speichern Sie es (ohne die Option zu erzwingen, "alle untergeordneten Objekt Berechtigungen zu ersetzen ..."). Dann werden sowohl die manuelle als auch die Powershell-Regel auf den Kindern angezeigt. Es ist, als ob irgendeine Art von Kickstart notwendig ist, damit die Kinder die neue propagierte Regel übernehmen. Was fehlt mir, damit die untergeordneten Objekte die hinzugefügte neue Regel anzeigen?

+0

Was ist $ acl? Versuchen Sie, die Sicherheitsbeschreibung von ** $ filename ** in ** $ acl ** zu kopieren? –

Antwort

1

Das ist sehr seltsam. Ich habe ähnlichen Code, der Berechtigungen auf die gleiche Weise setzt. Ich habe nie überprüft, ob die Berechtigungen der Kinder gesetzt sind oder nicht. Es könnte nur etwas seltsam in der Windows Explorer-Benutzeroberfläche sein. Haben Sie PowerShell verwendet, um die ACLs eines der untergeordneten Elemente abzurufen, um zu überprüfen, ob die Berechtigungen angewendet werden oder nicht?

Als Referenz ist hier the code I use to grant permissions:

foreach($permission in $Permissions) 
{ 
    $right = ($permission -as "Security.AccessControl.FileSystemRights") 
    if(-not $right) 
    { 
     throw "Invalid FileSystemRights: $permission. Must be one of $([Enum]::GetNames("Security.AccessControl.FileSystemRights"))." 
    } 
    $rights = $rights -bor $right 
} 

Write-Host "Granting $Identity $Permissions on $Path." 
# We don't use Get-Acl because it returns the whole security descriptor, which includes owner information. 
# When passed to Set-Acl, this causes intermittent errors. So, we just grab the ACL portion of the security descriptor. 
# See http://www.bilalaslam.com/2010/12/14/powershell-workaround-for-the-security-identifier-is-not-allowed-to-be-the-owner-of-this-object-with-set-acl/ 
$currentAcl = (Get-Item $Path).GetAccessControl("Access") 

$inheritanceFlags = [Security.AccessControl.InheritanceFlags]::None 
if(Test-Path $Path -PathType Container) 
{ 
    $inheritanceFlags = ([Security.AccessControl.InheritanceFlags]::ContainerInherit -bor ` 
         [Security.AccessControl.InheritanceFlags]::ObjectInherit) 
} 
$propagationFlags = [Security.AccessControl.PropagationFlags]::None 
$accessRule = New-Object "Security.AccessControl.FileSystemAccessRule" $identity,$rights,$inheritanceFlags,$propagationFlags,"Allow"  
$currentAcl.SetAccessRule($accessRule) 
Set-Acl $Path $currentAcl 
5

Ich habe das gleiche logische Problem hatte ...

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"username","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))) 

Mit diesem letzten 'none' Sie sagen: Sie propagieren nicht ... ändern:

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"username","FullControl", "ContainerInherit, ObjectInherit", "InheritOnly", "Allow"))) 

und es wird Ihre Einstellungen verbreiten. Schauen Sie sich hier die Zugriffsregel Optionen: http://msdn.microsoft.com/en-us/library/ms147785.aspx

Dies sind die Ausbreitungsfahnen: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.propagationflags.aspx

0

ich das Internet und verschiedene Fragen Stackoverflow Scheuern haben versucht, dies aus zu verwirren. Ich habe vielleicht nicht die beste Lösung, aber ich denke, es erfüllt die Frage. Nach meinen Recherchen behandelt Powershells Set-Acl Vererbung nicht richtig. Der Schlüssel zum folgenden Code ist zwei Dinge: das Objekt System.Security.AccessControl.DirectorySecurity und die alternative Methode zum Festlegen der ACL verwenden $dir.SetAccessControl() Die untergeordneten Elemente des Zielordners (sowohl Ordner als auch Dateien) erben erfolgreich die mit Ihrem Zielordner verknüpften Berechtigungen.

aufrufen Beispiel:

[email protected]() 
$newACL+=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @("MyLocalGroup1","ReadAndExecute,Synchronize","ContainerInherit,ObjectInherit","None","Allow") 
$newACL+=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @("MyLocalGroup2","FullControl","ContainerInherit,ObjectInherit","None","Allow") 
Set-FolderPermissions -Path $Path -KeepDefault -ResetOwner -AccessRuleList $newACL 

Funktion:

function Set-FolderPermissions { 
    # The whole point of this script is because Set-Acl bungles inheritance 
    [CmdletBinding(SupportsShouldProcess=$false)] 
    Param ([Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$Path, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$KeepExisting, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$KeepDefault, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$ResetOwner, 
     [Parameter(Mandatory=$true, ValueFromPipeline=$false)] [System.Security.AccessControl.FileSystemAccessRule[]]$AccessRuleList) 

    Process { 
    $aryDefaultACL="NT AUTHORITY\SYSTEM","CREATOR OWNER","BUILTIN\Administrators" 
    [email protected]() 
    $owner=New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators") 
    $acl=Get-Acl -Path $Path 

    # Save only needed individual rules. 
    if ($KeepExisting.IsPresent) { 
     if ($KeepDefault.IsPresent) { 
     # Keep everything 
     $acl.Access | ForEach-Object { $tempACL+=$_ } 
     } 
     else { 
     # Remove the defaults, keep everything else 
     for ($i=0; $i -lt $acl.Access.Count; $i++) { 
     if (!$aryDefaultACL.Contains($acl.Access[$i].IdentityReference.Value)) { $tempACL+=$acl.Access[$i] } 
     } 
     } 
    } 
    else { 
     if ($KeepDefault.IsPresent) { 
     # Keep only the default, drop everything else 
     for ($i=0; $i -lt $acl.Access.Count; $i++) { 
     if ($aryDefaultACL.Contains($acl.Access[$i].IdentityReference.Value)) { $tempACL+=$acl.Access[$i] } 
     } 
     } 
     #else { # Do nothing, because $TempACL is already empty. } 
    } 

    # Add the new rules 
    # I could have been modifying $acl this whole time, but it turns out $tempACL=$acl doesn't work so well. 
    # As the rules are removed from $acl, they are also removed from $tempACL 
    for ($i=0; $i -lt $AccessRuleList.Count; $i++) { $tempACL+=$AccessRuleList[$i] } 

    # This is the object that you're looking for... 
    $aclDS=New-Object System.Security.AccessControl.DirectorySecurity -ArgumentList @($Path,[System.Security.AccessControl.AccessControlSections]::None) 
    # The object, apparently, comes with a bonus rule... 
    $aclDS.RemoveAccessRuleSpecific($aclDS.Access[0]) 
    # Add the rules to our new object 
    for ($i=0; $i -lt $tempACL.Count; $i++) { 
     # I tried adding the rules directly but they didn't work. I have to re-create them. 
     $tempRule=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @($tempACL[$i].IdentityReference,$tempACL[$i].FileSystemRights,$tempACL[$i].InheritanceFlags,$tempACL[$i].PropagationFlags,$tempACL[$i].AccessControlType) 
     $aclDS.AddAccessRule($tempRule) 
    } 
    # This has to be done after all the rules are added, otherwise it doesn't work 
    $aclDS.SetAccessRuleProtection($true,$false) 

    if ($ResetOwner.IsPresent) { 
     # Often, the default owner is SYSTEM. This ownership will prevent you from making any changes. 
     # So, we change owner to the local Administrator 
     $acl.SetOwner($owner) 
     # We have to apply it now because we are applying our ACLs in two stages. We won't be using Set-Acl again. 
     Set-Acl -Path $Path -AclObject $acl 
    } 

    # Lastly, apply our ACls 
    $dir=Get-Item -Path $Path 
    $dir.SetAccessControl($aclDS) 
    } 
} 
Verwandte Themen