在 powershell 中获取文件夹所有权并向域帐户添加完全权限?

在 powershell 中获取文件夹所有权并向域帐户添加完全权限?

我有一个 Powershell 函数可以完成部分工作,但它不使用域帐户来获取所有权并添加权限...它使用本地管理员。在 Powershell 中有没有更好的方法可以做到这一点?

<#

.SYNOPSIS
    Take ownership of a folder giving the ownership to ourdomain\myuser

.DESCRIPTION
    Takes ownership of a file the way my boss said to do when deleting a user's home directory.
    Using the GUI:
    1. Right click the folder and select properties.
    2. Click the "Security" tab.
    3. Click the "Advanced" button.
    4. Next to the "Owner:" label, click "Change"
    5. Enter ourdomain\myuser
    6. Click OK, OK, OK
    7. Right click the folder and select properties.
    8. Click the "Security" tab.
    9. Click the "Advanced" button.
    10. Click "Add"
    11. Next to "Principal:" click "Select a principal"
    12. Enter ourdomain\myuser
    13. Click OK
    14. Check "Full control"
    15. Click OK, OK, OK
    16. You should now be able to manipulate or delete the folder.
.NOTES
    File Name : Microsoft.PowerShell_profile.ps1
.EXAMPLE
    Take-Ownership R:\Redirected\Users\<username>
#>
function Take-Ownership {
   param(
     [String]$Folder
   )

   # Take ownership of the folder...  
   # (though I'd prefer if I could specify a user or group instead) 
   takeown.exe /A /F $Folder

   # Obtain the current ACL for this folder.
   $CurrentACL = Get-Acl $Folder

   # Add FullControl permissions to the ACL for the user.
   Write-Host ...Adding ourdomain\myuser to $Folder -Fore Yellow
   $SystemACLPermission = "ourdomain\myuser","FullControl","ContainerInherit,ObjectInherit","None","Allow"
   $SystemAccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $SystemACLPermission
   $CurrentACL.AddAccessRule($SystemAccessRule)

   #Write-Host ...Adding Infrastructure Services to $Folder -Fore Yellow
   #$AdminACLPermission = "ourdomain\myuser","FullControl","ContainerInherit,ObjectInherit"."None","Allow"
   #$SystemAccessRule = new-object System.Security.AccessControl.FilesystemAccessRule $AdminACLPermission
   #$CurrentACL.AddAccessRule($SystemAccessRule)

   # Set the ACL again.
   Set-Acl -Path $Folder -AclObject $CurrentACL
}

答案1

如果您将对象的所有者设置为管理员组,则您必须是本地管理员。否则,人们可以轻易规避磁盘配额,因为配额计算基于文件所有权,而配额不会影响管理员。

如果您以管理员身份运行该脚本,只需稍加调整即可将对象的所有者设置为任何安全主体。您需要这个权限调整脚本来自 Lee Holmes,我对其进行了少许编辑,删除了多余的空格并允许它在一个会话中多次运行:

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)

我将其保存为privs.ps1。然后您可以调用来为您的进程打开.\privs.ps1 SeRestorePrivilegeSeRestorePrivilege这允许您将文件所有权设置为您想要的任何人。

然后,takeown您可以使用已有的 ACL 对象,而不必进行调用:

$ownerPrincipal = New-Object System.Security.Principal.NTAccount($newOwnerName)
$CurrentACL.SetOwner($ownerPrincipal)

应用新的 ACL 时将同时设置新的所有者。

最后,你可以禁用额外的权限:

.\privs.ps1 SeRestorePrivilege -Disable

相关内容