2012-06-10 10 views
5

Kiedy ustawić nową regułę filesystemaccess z PowerShell i ustawienie ACL, ustawić flagi dziedziczenia propagować dzieciom i liści obiektówZmiana uprawnień z PowerShell nie propogate dzieciom

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

Kiedy patrzę na uprawnienia w eksploratorze .. na karcie zabezpieczeń .. zaawansowane ... propagacja jest ustawiona poprawnie. Ale jeśli patrzę na same dzieci, NIE wyświetlają nowej reguły bezpieczeństwa.

Jeśli w eksploratorze dodaję inną regułę z innym identyfikatorem SID .. i zapisz go (bez wymuszania opcji "zastąp wszystkie uprawnienia obiektu podrzędnego ..."). Następnie pojawia się zarówno instrukcja, jak i zasada powershell dla dzieci. To tak, jakby potrzebny był jakiś rodzaj kickstartu, by spowodować, że dzieci będą podnosić nową propagowaną zasadę. Czego mi brakuje, aby obiekty podrzędne pokazywały nową regułę?

+0

Co jest $ ACL? Czy próbujesz skopiować deskryptor bezpieczeństwa ** $ filename ** do ** $ acl **? –

Odpowiedz

1

To bardzo dziwne. Mam podobny kod, który ustawia uprawnienia w ten sam sposób. Nigdy nie sprawdzałem, czy uprawnienia dzieci są ustawione, czy nie. Może to być po prostu dziwaczność w interfejsie użytkownika Eksploratora Windows. Czy użyłeś PowerShell, aby uzyskać listy ACL na jednym z dzieci, aby sprawdzić, czy uprawnienia są lub nie są stosowane?

Dla porównania, oto 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

miałem ten sam problem logiczny ...

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

Z tym ostatnim 'none' mówisz: nie propogate ... Przejdź do:

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

i będzie propagować swoje ustawienia. Sprawdź opcje reguły dostępu tutaj: http://msdn.microsoft.com/en-us/library/ms147785.aspx

Są flagi Rozmnażanie: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.propagationflags.aspx

0

I zostały szorowania internecie i kilka StackOverflow pytania próbuje puzzle to. Być może nie mam najlepszego rozwiązania, ale myślę, że spełnia to pytanie. Zgodnie z moimi badaniami, Powershell's Set-Acl po prostu nie obsługuje poprawnie dziedziczenia. Klucz do poniższego kodu to dwie rzeczy: obiekt System.Security.AccessControl.DirectorySecurity i użycie alternatywnej metody ustawiania ACL $dir.SetAccessControl() Elementy potomne folderu docelowego (zarówno foldery, jak i pliki) pomyślnie dziedziczą uprawnienia dołączone do folderu docelowego.

Wywołanie przykład:

[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 

Funkcja:

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) 
    } 
} 
Powiązane problemy