PowerShell Change owner of files and folders

前端 未结 2 1749
孤城傲影
孤城傲影 2021-02-19 22:18

Searching the web, I found 2 scripts that are able to change the owner of files and folders. When testing this, it functions perfectly in PowerShell 1.0. Now I\'m trying to comb

2条回答
  •  孤独总比滥情好
    2021-02-19 22:30

    After a week of playing around with PowerShell, I found the answer to my own question:

    $Target = "\\domain.net\myFolder"
    $TempFolder = 'C:\TempFolder'
    $TempFile = 'C:\TempFile'
    
    #region Load super powers
    $AdjustTokenPrivileges = @"
    using System;
    using System.Runtime.InteropServices;
    
     public class TokenManipulator
     {
      [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("kernel32.dll", ExactSpelling = true)]
      internal static extern IntPtr GetCurrentProcess();
      [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_DISABLED = 0x00000000;
      internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
      internal const int TOKEN_QUERY = 0x00000008;
      internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
      public static bool AddPrivilege(string privilege)
      {
       try
       {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = GetCurrentProcess();
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;
        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;
       }
       catch (Exception ex)
       {
        throw ex;
       }
      }
      public static bool RemovePrivilege(string privilege)
      {
       try
       {
        bool retVal;
        TokPriv1Luid tp;
        IntPtr hproc = GetCurrentProcess();
        IntPtr htok = IntPtr.Zero;
        retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
        tp.Count = 1;
        tp.Luid = 0;
        tp.Attr = SE_PRIVILEGE_DISABLED;
        retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
        retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        return retVal;
       }
       catch (Exception ex)
       {
        throw ex;
       }
      }
     }
    "@
    Add-Type $AdjustTokenPrivileges
    [void][TokenManipulator]::AddPrivilege("SeRestorePrivilege") 
    [void][TokenManipulator]::AddPrivilege("SeBackupPrivilege") 
    [void][TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") 
    #endregion
    
    $BuiltinAdmin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
    $BuiltinAdminFullControlAcl = New-Object System.Security.AccessControl.FileSystemAccessRule($BuiltinAdmin,"FullControl","Allow")
    
    #region Create temp folder with Admin owner and full control
    $FolderBuiltinAdminOwnerAcl = New-Object System.Security.AccessControl.DirectorySecurity
    $FolderBuiltinAdminOwnerAcl.SetOwner($BuiltinAdmin)
    
    Remove-Item $TempFolder -EA Ignore
    New-Item -Type Directory -Path $TempFolder
    
    $TempFolderAcl = Get-Acl -Path $TempFolder
    $TempFolderAcl.SetAccessRule($BuiltinAdminFullControlAcl)
    #endregion
    
    #region Change folder owners to Admin
    $Folders = @(Get-ChildItem -Path $Target -Directory -Recurse)
    
    foreach ($Folder in $Folders) {
        $Folder.SetAccessControl($FolderBuiltinAdminOwnerAcl)
        Set-Acl -Path $Folder -AclObject $TempFolderAcl
    }
    #endregion
    
    #region Create temp file with Admin owner and full control
    $FileBuiltinAdminOwnerAcl = New-Object System.Security.AccessControl.FileSecurity
    $FileBuiltinAdminOwnerAcl.SetOwner($BuiltinAdmin)
    
    Remove-Item $TempFile -EA Ignore
    New-Item -Type File -Path $TempFile
    
    $TempFileAcl = Get-Acl -Path $TempFile
    $TempFileAcl.SetAccessRule($BuiltinAdminFullControlAcl)
    #endregion
    
    #region Change file owners to Admin
    $Files = @(Get-ChildItem -Path $Target -File -Recurse)
    
    foreach ($File in $Files) {
        $File.SetAccessControl($FileBuiltinAdminOwnerAcl)
        Set-Acl -Path $File -AclObject $TempFileAcl
    }
    #endregion
    
    #region Clean-up
    Remove-Item $TempFile, $TempFolder
    #endregion
    

    Thank you all again for your help. Hopefully, someone else can benefit from my PowerShell research. The only think left is making it a bit more verbose, but that's for another day. It does what it needs to do, and that in the most harsh conditions where permissions are really messed up.

提交回复
热议问题