É possível alterar as permissões de NTFS em uma grande árvore mais rapidamente?

1

Existe alguma maneira de alterar as permissões para uma árvore enorme mais rapidamente no Windows?

É realmente necessário esperar horas para alterar apenas um proprietário?

Eu estava pensando que tal coisa como "herança" foi inventada para isso, mas parece que eu estava errado ...

    
por Dims 29.11.2016 / 13:00

1 resposta

1

Se você tiver SeRestorePrivilege , poderá alterar a ACL de um arquivo sem ter acesso explícito ou ser seu proprietário. Para aproveitar esse fato, você pode usar o PowerShell!

Primeiro, você precisará deste roteiro gigantesco que eu tirei de Lee Holmes com alguns ajustes para remover espaço em branco extra e permitir várias execuções em uma sessão:

param(    ## The privilege to adjust. This set is taken from
    ## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
    [ValidateSet(
        "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
        "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
        "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
        "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
        "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
        "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
        "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
        "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
        "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
        "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
        "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
    $Privilege,
    ## The process on which to adjust the privilege. Defaults to the current process.
    $ProcessId = $pid,
    ## Switch to disable the privilege, rather than enable it.
    [Switch] $Disable
)

## Taken from P/Invoke.NET with minor adjustments.
$definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv
{

    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
    ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

    [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);

    [DllImport("advapi32.dll", SetLastError = true)]
    internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);

    [StructLayout(LayoutKind.Sequential, Pack = 1)]

    internal struct TokPriv1Luid
    {
        public int Count;
        public long Luid;
        public int Attr;
    }

    internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
    internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
    internal const int TOKEN_QUERY = 0x00000008;
    internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;

    public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
    {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = new IntPtr(processHandle);
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;

        if(disable)
        {
            tp.Attr = SE_PRIVILEGE_DISABLED;
        }
        else
        {
            tp.Attr = SE_PRIVILEGE_ENABLED;
        }

        retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
        retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        return retVal;
    }
}

'@

$processHandle = (Get-Process -id $ProcessId).Handle
try { 
  Add-Type $definition 
} catch {} # Silent failure on re-registration

[AdjPriv]::EnablePrivilege($processHandle, $Privilege, $Disable)

Salve como .ps1 file, adjpriv.ps1 por exemplo. Para permitir a execução de scripts do PowerShell, consulte a seção Habilitando Scripts do wiki de tags do PowerShell .

Agora você pode usar este pequeno script para permitir aos administradores o controle total de tudo no diretório atual:

.\adjpriv.ps1 SeRestorePrivilege
Get-ChildItem -Recurse -Force | % {
    $acl = Get-Acl $_
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule ('Administrators', 'FullControl', 'Allow')
    $acl.AddAccessRule($rule)
    Set-Acl $_ $acl
}

As ACLs são atualizadas, mas o proprietário não é alterado, o que economiza o tempo necessário para fazer isso primeiro.

Se você precisar controlar como a nova regra de acesso se aplica a novos itens em diretórios existentes, ajuste o script para usar este outro construtor de FileSystemAccessRule .

    
por 07.12.2016 / 01:18