powershell - 如何使用 PowerShell 取得文件所有权?

标签 powershell permissions file-permissions

问题 :我希望以编程方式(使用 PowerShell)获得我绝对没有权限的文件的所有权。

更新 :我已经彻底重写了问题,以给出重现问题的步骤。这是我在做什么:

##########################################################
# Logon as UserA
##########################################################

$file = "C:\temp\file.txt"
new-item C:\temp -type dir
new-item $file -type file

# Remove inheritence
$isProtected = $true
$preserveInheritance = $true
$FileSecurity = Get-ACL $file
$FileSecurity.SetAccessRuleProtection($isProtected, $preserveInheritance)
Set-ACL $file -AclObject $FileSecurity

# Remove authenticated users
$user = "Authenticated Users"
$permission = "Modify"
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]$permission
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]"None"
$AccessControlType =[System.Security.AccessControl.AccessControlType]::Allow
$FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType)
$FileSecurity = Get-ACL $file
$FileSecurity.RemoveAccessRuleAll($FileSystemAccessRule)
Set-ACL $file -AclObject $FileSecurity

# Remove local users
$user = "BUILTIN\Users"
$permission = "ReadAndExecute"
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]$permission
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]"None"
$AccessControlType =[System.Security.AccessControl.AccessControlType]::Allow
$FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType)
$FileSecurity = Get-ACL $file
$FileSecurity.RemoveAccessRuleAll($FileSystemAccessRule)
Set-ACL $file -AclObject $FileSecurity

# Give the current user Full Control
$user = $env:username
$permission = "FullControl"
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]$permission
$AccessControlType =[System.Security.AccessControl.AccessControlType]::Allow
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $FileSystemRights, $AccessControlType)
$FileSecurity = Get-ACL $file
$FileSecurity.AddAccessRule($FileSystemAccessRule)
Set-ACL $file -AclObject $FileSecurity

# Remove local administrators
$user = "BUILTIN\Administrators"
$permission = "FullControl"
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]$permission
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]"None"
$AccessControlType =[System.Security.AccessControl.AccessControlType]::Allow
$FileSystemAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType)
$FileSecurity = Get-ACL $file
$FileSecurity.RemoveAccessRuleAll($FileSystemAccessRule)
Set-ACL $file -AclObject $FileSecurity

# Set the owner to be the current user
$user = $env:username
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSecurity = new-object System.Security.AccessControl.FileSecurity
$FileSecurity.SetOwner($Account)
[System.IO.File]::SetAccessControl($file, $FileSecurity)

##########################################################
# Log off the server as UserA and logon as UserB
##########################################################

$file = "C:\temp\file.txt"

# Take ownership
$user = $env:username
$Account = New-Object System.Security.Principal.NTAccount($user)
$FileSecurity = new-object System.Security.AccessControl.FileSecurity
$FileSecurity.SetOwner($Account)
[System.IO.File]::SetAccessControl($file, $FileSecurity)

这是抛出错误:
Exception calling "SetAccessControl" with "2" argument(s): "Attempted to perform an unauthorized operation."
At line:1 char:35
+ [System.IO.File]::SetAccessControl <<<< ($path, $FileSecurity)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

补充说明:
  • $error[0].innerexception 为空。
  • 作为 UserA 采取的步骤确保了 userB 对 C:\temp\file.txt 绝对没有权限。 .
  • 运行 [System.IO.File]::GetAccessControl($path)抛出一个类似的
    错误(这是预期的)
  • 我当然是右键单击 PowerShell 并选择“以管理员身份运行”。
  • 我试过禁用 UAC,但这并没有什么区别。
  • 我可以通过 GUI 获得所有权,因此应该有一种方法可以使用 PowerShell 以编程方式执行此操作。

  • 我究竟做错了什么?

    更新及解答:

    我发布的接受的答案有效,但似乎有点矫枉过正。简单地通过 UNC 路径引用文件似乎可以解决问题:
    $file = "\\localhost\\c$\temp\file.txt"
    
    # Take ownership
    $user = $env:username
    $Account = New-Object System.Security.Principal.NTAccount($user)
    $FileSecurity = new-object System.Security.AccessControl.FileSecurity
    $FileSecurity.SetOwner($Account)
    [System.IO.File]::SetAccessControl($file, $FileSecurity)
    

    最佳答案

    我已经想通了。我只能使用 SE_RESTORE_NAME 权限完成。

    我学会了如何做到这一点:
    http://cosmoskey.blogspot.com/2010/07/setting-owner-on-acl-in-powershell.html

    并附上来自:http://fixingitpro.com/2011/07/08/set-owner-with-powershell-%E2%80%9Cthe-security-identifier-is-not-allowed-to-be-the-owner-of-this-object%E2%80%9D/ 的评论

    这是对我有用的完整命令:

    $code = @"
    using System;
    using System.Runtime.InteropServices;
    
    namespace CosmosKey.Utils
    {
    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 const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
      public const string SE_AUDIT_NAME = "SeAuditPrivilege";
      public const string SE_BACKUP_NAME = "SeBackupPrivilege";
      public const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";
      public const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";
      public const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";
      public const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";
      public const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";
      public const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";
      public const string SE_DEBUG_NAME = "SeDebugPrivilege";
      public const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";
      public const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";
      public const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";
      public const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
      public const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";
      public const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";
      public const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";
      public const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";
      public const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";
      public const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";
      public const string SE_RELABEL_NAME = "SeRelabelPrivilege";
      public const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";
      public const string SE_RESTORE_NAME = "SeRestorePrivilege";
      public const string SE_SECURITY_NAME = "SeSecurityPrivilege";
      public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
      public const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";
      public const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";
      public const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";
      public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
      public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
      public const string SE_TCB_NAME = "SeTcbPrivilege";
      public const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";
      public const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";
      public const string SE_UNDOCK_NAME = "SeUndockPrivilege";
      public const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";
    
      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;
       }
    
      }
    }
    }
    "@
    
    # Take ownership
    add-type $code
    [void][CosmosKey.Utils.TokenManipulator]::AddPrivilege([CosmosKey.Utils.TokenManipulator]::SE_RESTORE_NAME)
    $file = "\\$env:computername\c$\temp\file.txt"
    $user = $env:username
    $Account = New-Object System.Security.Principal.NTAccount($user)
    $FileSecurity = new-object System.Security.AccessControl.FileSecurity
    $FileSecurity.SetOwner($Account)
    [System.IO.File]::SetAccessControl($file, $FileSecurity)
    [void][CosmosKey.Utils.TokenManipulator]::RemovePrivilege([CosmosKey.Utils.TokenManipulator]::SE_RESTORE_NAME)
    

    关于powershell - 如何使用 PowerShell 取得文件所有权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17031552/

    相关文章:

    windows - LogonSessionId 帐户在新证书中分配了读取权限?

    android - Marshmallow 中的存储权限错误

    .net - Vista 上的 HttpListener.Start() AccessDenied 错误

    python - tempfile.mkstemp 权限设置

    node.js - 仅从已安装的可执行文件在 Windows 上从 Electron 进程 fork 失败

    Powershell v3 New-JobTrigger 每天重复

    azure - 通过 PowerShell 获取 Azure 中资源的资源创建者

    windows - wmic 可以获取路径或物理名称的模型信息吗?

    ios - 您如何在 iOS 中第二次请求照片库权限

    php - 如何获得文件访问权限