You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ntrights.exe授予用户权限后无法启用权限的技术咨询

使用Ntrights.exe授予用户权限后无法启用权限的技术咨询

你好!首先得明确一点:Ntrights.exe的作用仅仅是把权限添加到用户的权限集合中(也就是授予权限),它本身并不会自动启用这些权限——这是Windows权限机制的正常设计,不是工具的问题。

在Windows系统里,用户被授予的权限默认在登录会话中都是Disabled状态,这是出于安全考虑:权限只有在需要使用它的程序主动通过系统API(比如AdjustTokenPrivileges)申请启用时,才会变成Enabled状态。你用whoami /priv看到的Disabled,只是说明当前会话里这个权限没被激活,但你的用户已经拥有了该权限,当你运行需要它的程序(比如shutdown.exe)时,程序会自动启用这个权限完成操作。

至于你问的有没有Sysinternals工具能直接启用权限:遗憾的是Sysinternals套件里没有专门做这件事的工具,但我们可以用PowerShell脚本调用Windows API来实现临时启用当前会话中的权限,比如针对SeShutdownPrivilege的示例脚本:

$privilegeName = "SeShutdownPrivilege"
$token = [System.Security.Principal.WindowsIdentity]::GetCurrent().Token
$privilege = New-Object System.Security.Principal.WindowsPrincipal($token)
if (-not $privilege.HasPrivilege($privilegeName)) {
    Write-Host "该用户未被授予$privilegeName权限"
    exit
}
$tokenHandle = [IntPtr]::Zero
if ([Advapi32]::OpenProcessToken([System.Diagnostics.Process]::GetCurrentProcess().Handle, [TokenAccessLevels]::AdjustPrivileges -bor [TokenAccessLevels]::Query, [ref]$tokenHandle)) {
    $luid = New-Object Interop.LUID
    if ([Advapi32]::LookupPrivilegeValue($null, $privilegeName, [ref]$luid)) {
        $privilegeSet = New-Object Interop.TOKEN_PRIVILEGES
        $privilegeSet.PrivilegeCount = 1
        $privilegeSet.Privileges = New-Object Interop.LUID_AND_ATTRIBUTES[] 1
        $privilegeSet.Privileges[0].Luid = $luid
        $privilegeSet.Privileges[0].Attributes = [PrivilegeAttributes]::Enabled
        $previousPrivilegeSet = New-Object Interop.TOKEN_PRIVILEGES
        $returnLength = [UInt32]::Zero
        if ([Advapi32]::AdjustTokenPrivileges($tokenHandle, $false, [ref]$privilegeSet, [System.Runtime.InteropServices.Marshal]::SizeOf($previousPrivilegeSet), [ref]$previousPrivilegeSet, [ref]$returnLength)) {
            Write-Host "$privilegeName权限已在当前会话中启用"
        } else {
            Write-Host "启用权限失败,错误码: $([System.Runtime.InteropServices.Marshal]::GetLastWin32Error())"
        }
    }
    [Kernel32]::CloseHandle($tokenHandle)
}
# 提前定义所需的API调用结构体和函数
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Interop {
    [StructLayout(LayoutKind.Sequential)]
    public struct LUID {
        public uint LowPart;
        public int HighPart;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct LUID_AND_ATTRIBUTES {
        public LUID Luid;
        public uint Attributes;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct TOKEN_PRIVILEGES {
        public uint PrivilegeCount;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        public LUID_AND_ATTRIBUTES[] Privileges;
    }
}
public enum TokenAccessLevels : uint {
    AdjustPrivileges = 0x0020,
    Query = 0x0008
}
public enum PrivilegeAttributes : uint {
    Enabled = 0x00000002
}
public class Advapi32 {
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessLevels DesiredAccess, ref IntPtr TokenHandle);
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref Interop.LUID lpLuid);
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref Interop.TOKEN_PRIVILEGES NewState, uint BufferLength, ref Interop.TOKEN_PRIVILEGES PreviousState, ref uint ReturnLength);
}
public class Kernel32 {
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool CloseHandle(IntPtr hObject);
}
"@

如果想要让权限在用户登录后自动启用,其实不太推荐(会增加安全风险),但如果确实有需求,可以通过组策略配置登录脚本,在用户登录时运行类似上述的代码来激活权限。

备注:内容来源于stack exchange,提问作者k1dfr0std

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 11:43:04