首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PowerShell更改文件和文件夹的所有者

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

Stack Overflow用户
提问于 2014-04-10 12:41:29
回答 2查看 74K关注 0票数 16

搜索网页,我发现了两个脚本,可以改变文件和文件夹的所有者。在测试这一点时,它在PowerShell 1.0中运行得很好。现在我尝试将两者结合起来,这样它们就可以递归地工作了,因为我们有超过500个子目录和文件的文件夹。这是一项了不起的工作。

我们想要:

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

问题:

  • 每个脚本只适用于一个文件或一个文件夹。如何将它合并到一个脚本中,以便将所有的子文件夹和文件合并在一起?也许把它放在两个不同的函数中,然后循环它或者..

Script1 :将文件所有者更改为Admin

代码语言:javascript
运行
复制
$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 :将文件夹所有者更改为Admin

代码语言:javascript
运行
复制
$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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-14 13:37:23

在和PowerShell玩了一周之后,我找到了我自己问题的答案:

代码语言:javascript
运行
复制
$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

再次感谢你们的帮助。希望其他人能从我的PowerShell研究中获益。剩下的唯一的想法就是让它变得更冗长,但这是另一天的事情。它完成了它需要做的事情,并且在最恶劣的条件下,权限确实被搞砸了。

票数 9
EN

Stack Overflow用户

发布于 2014-04-10 12:52:03

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

代码语言:javascript
运行
复制
# 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
}
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22988384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档