PowerShell 更改文件和文件夹的所有者

标签 powershell

在网上搜索,我发现了 2 个能够更改文件和文件夹所有者的脚本。对此进行测试时,它在 PowerShell 1.0 中完美运行。现在我正在尝试将两者结合起来,以便它们递归地工作,因为我们有包含 500 多个子目录和文件的文件夹。这是一项艰巨的工作。

我们要:

  • \\server\C$\Folder 上运行一个脚本(不使用外部工具)
  • 将所有文件和子文件夹的所有者更改为 BUILTIN\Administrators

  • 问题:
  • 每个脚本仅适用于 1 个文件或 1 个文件夹。如何将其组合在一个脚本中,以便将所有子文件夹和文件放在一起?可能将它放在 2 个不同的函数中并循环遍历它,或者..

  • Script1:将文件所有者更改为管理员
    $File = "\\server\c$\Users\dir\Downloads\Target\TargetFile.txt"
    $Account = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
    $FileSecurity = new-object System.Security.AccessControl.FileSecurity
    $FileSecurity.SetOwner($Account)
    [System.IO.File]::SetAccessControl($File, $FileSecurity)
    

    Script2:将文件夹所有者更改为管理员
    $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
    $Folder = Get-Item "C:\Users\dir\Downloads\Target"
    [void][TokenManipulator]::AddPrivilege("SeRestorePrivilege") 
    [void][TokenManipulator]::AddPrivilege("SeBackupPrivilege") 
    [void][TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") 
    $NewOwnerACL = New-Object System.Security.AccessControl.DirectorySecurity
    $Admin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
    $NewOwnerACL.SetOwner($Admin)
    $Folder.SetAccessControl($NewOwnerACL)
    

    最佳答案

    您可以使用 SetOwner()文件夹的方法,就像文件一样。

    # Define the owner account/group
    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList 'BUILTIN\Administrators';
    
    # Get a list of folders and files
    $ItemList = Get-ChildItem -Path c:\test -Recurse;
    
    # Iterate over files/folders
    foreach ($Item in $ItemList) {
        $Acl = $null; # Reset the $Acl variable to $null
        $Acl = Get-Acl -Path $Item.FullName; # Get the ACL from the item
        $Acl.SetOwner($Account); # Update the in-memory ACL
        Set-Acl -Path $Item.FullName -AclObject $Acl;  # Set the updated ACL on the target item
    }
    

    关于PowerShell 更改文件和文件夹的所有者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22988384/

    相关文章:

    powershell - $($variableName) 在 PowerShell 中的可扩展字符串中是什么意思?

    azure - Powershell Connect-AzureAD 错误 "accessing_ws_metadata_exchange_failed"

    Azure 函数核心工具安装卡在 Visual Studio Code 中

    asp.net - 从 ASP.NET 查询远程计算机时出现 WMI 访问被拒绝错误

    c# - 在 C# 中检查远程 PowerShell session 状态

    windows - 如何将 GUID 附加到现有文件名并保存到 CSV

    powershell - 将输入列表分成几列

    powershell - Windows Powershell代码变量的数字顺序递增

    Windows Server 2019 上的 Azure 管道 powershell 和 git 在输出中出现错误

    powershell - 获取 BizTalk 中特定应用程序的所有挂起实例