当机器不在活动目录中时如何获取本地机器组/用户的列表? [英] How to get a list of local machine groups / users when machine is not in active directory?

查看:20
本文介绍了当机器不在活动目录中时如何获取本地机器组/用户的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当windows机器没有AD成员并且不能使用LDAP搜索时,有没有办法在C#中获取本地组和用户的列表?

Is there a way to get in C# a list of local groups and users, when the windows machine is no AD member and an LDAP search can't be used?

推荐答案

您可以使用 P/Invoke 调用 本机网络管理 API 获取本地用户名和组名:

You can use P/Invoke to call the native network management API to get local user and group names:

static class NativeMethods {

  [DllImport("netapi32.dll")]
  public static extern void NetApiBufferFree(IntPtr bufptr);

  [DllImport("netapi32.dll")]
  public static extern UInt32 NetUserEnum([MarshalAs(UnmanagedType.LPWStr)] String servername, UInt32 level, UInt32 filter, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle);

  [DllImport("netapi32.dll")]
  public static extern UInt32 NetLocalGroupEnum([MarshalAs(UnmanagedType.LPWStr)] String servername, UInt32 level, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle);

  [DllImport("Netapi32.dll")]
  public extern static UInt32 NetLocalGroupGetMembers([MarshalAs(UnmanagedType.LPWStr)] String servername, [MarshalAs(UnmanagedType.LPWStr)] String localgroupname, UInt32 level, ref IntPtr bufptr, UInt32 prefmaxlen, ref UInt32 entriesread, ref UInt32 totalentries, IntPtr resumehandle);

}

API 允许您获取有关用户的各种信息.如果你只想要名字,你可以使用这个函数:

The API allows you to get various information about users. If you only want names you can use this function:

IEnumerable<String> GetUserNames() {
  var buffer = IntPtr.Zero;
  try {
    UInt32 entriesRead = 0;
    UInt32 totalEntries = 0;
    var result = NativeMethods.NetUserEnum(null, 0, 0, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero);
    if (result != 0)
      throw new Win32Exception((Int32) result);
    var userNames = Enumerable
      .Range(0, (Int32) entriesRead)
      .Select(
        i => {
          var userInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size);
          var userName = Marshal.PtrToStringAuto(userInfo);
          return userName;
        }
      )
      .ToList();
    return userNames;
  }
  finally {
    NativeMethods.NetApiBufferFree(buffer);
  }
}

LINQ 语句用于解析"包含 USER_INFO_0 结构.如果您要查询其他信息,则必须进行更详细的解析".

The LINQ statement is used to "parse" the buffer that contains USER_INFO_0 strutures. If you are querying for additional information you will have to do more elaborate "parsing".

同样,您可以获得本地组名称:

Likewise you can get local group names:

IEnumerable<String> GetLocalGroupNames() {
  var buffer = IntPtr.Zero;
  try {
    UInt32 entriesRead = 0;
    UInt32 totalEntries = 0;
    var result = NativeMethods.NetLocalGroupEnum(null, 0, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero);
    if (result != 0)
      throw new Win32Exception((Int32) result);
    var localGroupNames = Enumerable
      .Range(0, (Int32) entriesRead)
      .Select(
        i => {
          var localGroupInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size);
          var groupName = Marshal.PtrToStringAuto(localGroupInfo);
          return groupName;
        }
      )
      .ToList();
    return localGroupNames;
  }
  finally {
    NativeMethods.NetApiBufferFree(buffer);
  }
}

缓冲区中的结构是LOCALGROUP_INFO_0USER_INFO_0 结构具有相同的布局,因此解析"代码是相同的.

The structures in the buffer are LOCALGROUP_INFO_0 with the same layout as the USER_INFO_0 structure so the "parsing" code is identical.

最后,这里是如何使用 LOCALGROUP_MEMBERS_INFO_3 结构:

Finally, here is how to get group membership using the LOCALGROUP_MEMBERS_INFO_3 structure:

IEnumerable<String> GetLocalGroupUsers(String localGroupName) {
  var buffer = IntPtr.Zero;
  try {
    UInt32 entriesRead = 0;
    UInt32 totalEntries = 0;
    var result = NativeMethods.NetLocalGroupGetMembers(null, localGroupName, 3, ref buffer, UInt32.MaxValue, ref entriesRead, ref totalEntries, IntPtr.Zero);
    if (result != 0)
      throw new Win32Exception((Int32) result);
    var userNames = Enumerable
      .Range(0, (Int32) entriesRead)
      .Select(
        i => {
          var membersInfo = Marshal.ReadIntPtr(buffer, i*IntPtr.Size);
          var userName = Marshal.PtrToStringAuto(membersInfo );
          return userName;
        }
      )
      .ToList();
    return userNames;
  }
  finally {
    NativeMethods.NetApiBufferFree(buffer);
  }
}

这篇关于当机器不在活动目录中时如何获取本地机器组/用户的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆