【问题标题】:Enabling a Local User Right assignment in PowerShell在 PowerShell 中启用本地用户权限分配
【发布时间】:2014-10-15 21:07:53
【问题描述】:

我之前问过类似的问题,以在某个域用户的 PowerShell 中获取本地用户权限,现在我想启用该权限。我希望启用一些权限,但在此示例中,我将使用 Logon 作为批处理作业。 Windows Server 2008 默认不附带 Ntrights,因此我无法使用该方法。用户的 SID 不是从我正在使用的程序中传递的,我不能使用 secedit,但是域和用户名是通过的,所以我可以使用它。我很难用一种简单的方法来添加多个用户权限,而无需一些神秘的脚本。有没有一种简单的方法来授予用户权限而无需下载 ntrights 或无需知道用户的 SID?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    这应该可以解决问题。

    Add-Type @'
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LSA
    {
        using System.Runtime.InteropServices;
        using System.Security;
        using System.Management;
        using System.Runtime.CompilerServices;
        using System.ComponentModel;
    
        using LSA_HANDLE = IntPtr;
    
        [StructLayout(LayoutKind.Sequential)]
        struct LSA_OBJECT_ATTRIBUTES
        {
            internal int Length;
            internal IntPtr RootDirectory;
            internal IntPtr ObjectName;
            internal int Attributes;
            internal IntPtr SecurityDescriptor;
            internal IntPtr SecurityQualityOfService;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct LSA_UNICODE_STRING
        {
            internal ushort Length;
            internal ushort MaximumLength;
            [MarshalAs(UnmanagedType.LPWStr)]
            internal string Buffer;
        }
        sealed class Win32Sec
        {
            [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
            SuppressUnmanagedCodeSecurityAttribute]
            internal static extern uint LsaOpenPolicy(
            LSA_UNICODE_STRING[] SystemName,
            ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
            int AccessMask,
            out IntPtr PolicyHandle
            );
    
            [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
            SuppressUnmanagedCodeSecurityAttribute]
            internal static extern uint LsaAddAccountRights(
            LSA_HANDLE PolicyHandle,
            IntPtr pSID,
            LSA_UNICODE_STRING[] UserRights,
            int CountOfRights
            );
    
            [DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true),
            SuppressUnmanagedCodeSecurityAttribute]
            internal static extern int LsaLookupNames2(
            LSA_HANDLE PolicyHandle,
            uint Flags,
            uint Count,
            LSA_UNICODE_STRING[] Names,
            ref IntPtr ReferencedDomains,
            ref IntPtr Sids
            );
    
            [DllImport("advapi32")]
            internal static extern int LsaNtStatusToWinError(int NTSTATUS);
    
            [DllImport("advapi32")]
            internal static extern int LsaClose(IntPtr PolicyHandle);
    
            [DllImport("advapi32")]
            internal static extern int LsaFreeMemory(IntPtr Buffer);
    
        }
        /// <summary>
        /// This class is used to grant "Log on as a service", "Log on as a batchjob", "Log on localy" etc.
        /// to a user.
        /// </summary>
        public sealed class LsaWrapper : IDisposable
        {
            [StructLayout(LayoutKind.Sequential)]
            struct LSA_TRUST_INFORMATION
            {
                internal LSA_UNICODE_STRING Name;
                internal IntPtr Sid;
            }
            [StructLayout(LayoutKind.Sequential)]
            struct LSA_TRANSLATED_SID2
            {
                internal SidNameUse Use;
                internal IntPtr Sid;
                internal int DomainIndex;
                uint Flags;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            struct LSA_REFERENCED_DOMAIN_LIST
            {
                internal uint Entries;
                internal LSA_TRUST_INFORMATION Domains;
            }
    
            enum SidNameUse : int
            {
                User = 1,
                Group = 2,
                Domain = 3,
                Alias = 4,
                KnownGroup = 5,
                DeletedAccount = 6,
                Invalid = 7,
                Unknown = 8,
                Computer = 9
            }
    
            enum Access : int
            {
                POLICY_READ = 0x20006,
                POLICY_ALL_ACCESS = 0x00F0FFF,
                POLICY_EXECUTE = 0X20801,
                POLICY_WRITE = 0X207F8
            }
            const uint STATUS_ACCESS_DENIED = 0xc0000022;
            const uint STATUS_INSUFFICIENT_RESOURCES = 0xc000009a;
            const uint STATUS_NO_MEMORY = 0xc0000017;
    
            IntPtr lsaHandle;
    
            public LsaWrapper()
                : this(null)
            { }
            // // local system if systemName is null
            public LsaWrapper(string systemName)
            {
                LSA_OBJECT_ATTRIBUTES lsaAttr;
                lsaAttr.RootDirectory = IntPtr.Zero;
                lsaAttr.ObjectName = IntPtr.Zero;
                lsaAttr.Attributes = 0;
                lsaAttr.SecurityDescriptor = IntPtr.Zero;
                lsaAttr.SecurityQualityOfService = IntPtr.Zero;
                lsaAttr.Length = Marshal.SizeOf(typeof(LSA_OBJECT_ATTRIBUTES));
                lsaHandle = IntPtr.Zero;
                LSA_UNICODE_STRING[] system = null;
                if (systemName != null)
                {
                    system = new LSA_UNICODE_STRING[1];
                    system[0] = InitLsaString(systemName);
                }
    
                uint ret = Win32Sec.LsaOpenPolicy(system, ref lsaAttr,
                (int)Access.POLICY_ALL_ACCESS, out lsaHandle);
                if (ret == 0)
                    return;
                if (ret == STATUS_ACCESS_DENIED)
                {
                    throw new UnauthorizedAccessException();
                }
                if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
                {
                    throw new OutOfMemoryException();
                }
                throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
            }
    
            public void AddPrivileges(string account, string privilege)
            {
                IntPtr pSid = GetSIDInformation(account);
                LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
                privileges[0] = InitLsaString(privilege);
                uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
                if (ret == 0)
                    return;
                if (ret == STATUS_ACCESS_DENIED)
                {
                    throw new UnauthorizedAccessException();
                }
                if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
                {
                    throw new OutOfMemoryException();
                }
                throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
            }
    
            public void Dispose()
            {
                if (lsaHandle != IntPtr.Zero)
                {
                    Win32Sec.LsaClose(lsaHandle);
                    lsaHandle = IntPtr.Zero;
                }
                GC.SuppressFinalize(this);
            }
            ~LsaWrapper()
            {
                Dispose();
            }
            // helper functions
    
            IntPtr GetSIDInformation(string account)
            {
                LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
                LSA_TRANSLATED_SID2 lts;
                IntPtr tsids = IntPtr.Zero;
                IntPtr tdom = IntPtr.Zero;
                names[0] = InitLsaString(account);
                lts.Sid = IntPtr.Zero;
                Console.WriteLine("String account: {0}", names[0].Length);
                int ret = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref tsids);
                if (ret != 0)
                    throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret));
                lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids,
                typeof(LSA_TRANSLATED_SID2));
                Win32Sec.LsaFreeMemory(tsids);
                Win32Sec.LsaFreeMemory(tdom);
                return lts.Sid;
            }
    
            static LSA_UNICODE_STRING InitLsaString(string s)
            {
                // Unicode strings max. 32KB
                if (s.Length > 0x7ffe)
                    throw new ArgumentException("String too long");
                LSA_UNICODE_STRING lus = new LSA_UNICODE_STRING();
                lus.Buffer = s;
                lus.Length = (ushort)(s.Length * sizeof(char));
                lus.MaximumLength = (ushort)(lus.Length + sizeof(char));
                return lus;
            }
        }
        public class Editor
        {
            public static void AddPrivileges(string account, string privilege)
            {
                using (LsaWrapper lsaWrapper = new LsaWrapper())
                {
                    lsaWrapper.AddPrivileges(account, privilege);
                }
            }
        }
    }
    '@
    
    [LSA.Editor]::AddPrivileges("KNUCKLE-DRAGGER", "SeBatchLogonRight")
    secpol.msc
    

    如果有人需要,这个snip可以自己找到sids。

        Function Get-Sid ($User,$Domain){
        If ($Domain -eq $null){$Domain = $ENV:ComputerName}
        (Get-WMIObject Win32_UserAccount | select SID,Name,Domain | where {$_.Name -eq "$User"} | where {$_.Domain -eq "$Domain"} |Select-Object SID).SID
        }
    

    【讨论】:

    • 那是一大堆代码,谢谢。希望我有足够的代表,这样我就可以投票了。
    • 我已经多次看到基本上相同的代码块,有时使用枚举权限的方法。任何想法来自谁/来自哪里?
    • [...时间过去...] 我刚刚找到了这个线程,代码中有 cmets 可能会导致回到原始来源。加上它有枚举方法。 social.technet.microsoft.com/Forums/office/en-US/…
    • 现在只要弄清楚如何删除一个权利。
    猜你喜欢
    • 2014-01-04
    • 2017-01-02
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多