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

Netplwiz如何获取邮箱格式用户名?当前登录用户相关技术问询

解答:获取邮箱格式的Windows用户名

Netplwiz的实现逻辑

Netplwiz并非依赖.NET的WindowsIdentity类,而是直接调用Windows底层的安全与账户管理API:它会通过本地安全授权子系统(LSASS) 读取用户对象的用户主体名称(UPN) 属性,或者针对域用户直接查询Active Directory(AD)的userPrincipalName字段,以此拿到邮箱格式的用户名,而非常规的DOMAIN\UserName SAM账户格式。

对当前登录用户实现该功能的方法

可以通过.NET类库或者原生Win32 API两种方式实现,以下是具体方案:

1. .NET类库实现(推荐)

方式一:使用AccountManagement命名空间(简化版)

这个命名空间封装了AD和本地账户的操作逻辑,能直接获取UPN:

using System.DirectoryServices.AccountManagement;

public string GetCurrentUserUpn()
{
    // 本地用户用ContextType.Machine,域用户用ContextType.Domain
    using var context = new PrincipalContext(ContextType.Domain);
    using var currentUser = UserPrincipal.Current;
    
    return currentUser.UserPrincipalName; // 返回xxx@domain.com格式的用户名
}

注意:本地账户需要Windows 10/11及以上版本,且已正确设置UPN属性才能返回对应值。

方式二:直接查询Active Directory(域用户专用)

如果需要更精细的控制,可以通过LDAP查询AD获取用户的UPN:

using System.DirectoryServices;

public string GetCurrentUserUpnFromAd()
{
    var currentSamName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    var splitName = currentSamName.Split('\\');
    var domain = splitName[0];
    var samAccountName = splitName[1];

    using var adEntry = new DirectoryEntry($"LDAP://{domain}");
    using var searcher = new DirectorySearcher(adEntry)
    {
        Filter = $"(&(objectClass=user)(sAMAccountName={samAccountName}))",
        PropertiesToLoad = { "userPrincipalName" }
    };

    var result = searcher.FindOne();
    return result?.Properties["userPrincipalName"][0]?.ToString();
}

2. 原生Win32 API实现(底层方案)

如果需要更贴近Netplwiz的底层逻辑,可以调用Win32 API,比如NetUserGetInfo(获取本地/域用户信息):

using System;
using System.Runtime.InteropServices;

public static class Win32UserApi
{
    [DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
    private static extern int NetUserGetInfo(string serverName, string userName, int infoLevel, out IntPtr bufferPtr);

    [DllImport("netapi32.dll")]
    private static extern void NetApiBufferFree(IntPtr bufferPtr);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct USER_INFO_10
    {
        public string usri10_name;
        public string usri10_comment;
        public string usri10_user_comment;
        public string usri10_full_name;
        public string usri10_user_principal_name;
        // 其他字段按需定义,此处仅保留关键属性
    }

    public static string GetUserUpn(string userName)
    {
        IntPtr buffer = IntPtr.Zero;
        try
        {
            // infoLevel=10 表示获取包含UPN的用户信息
            var resultCode = NetUserGetInfo(null, userName, 10, out buffer);
            if (resultCode == 0)
            {
                var userInfo = Marshal.PtrToStructure<USER_INFO_10>(buffer);
                return userInfo.usri10_user_principal_name;
            }
            return null;
        }
        finally
        {
            if (buffer != IntPtr.Zero)
                NetApiBufferFree(buffer);
        }
    }
}

// 调用示例:
var currentSamName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\')[1];
var upn = Win32UserApi.GetUserUpn(currentSamName);

可用的关键类、方法与字段

.NET生态

  • UserPrincipal(System.DirectoryServices.AccountManagement):UserPrincipalName 属性直接返回用户的UPN。
  • DirectorySearcher(System.DirectoryServices):通过LDAP查询AD用户的userPrincipalName属性。
  • WindowsIdentity(System.Security.Principal):虽然Name返回SAM格式,但可用于提取当前用户的SID或SAM账户名,作为后续查询的基础。

原生Win32 API

  • NetUserGetInfo:指定infoLevel=10时可获取包含UPN的用户详细信息。
  • DsGetUserPrincipalName:直接通过用户SID或SAM账户名获取UPN。
  • LsaGetLogonSessionData:获取当前登录会话的完整数据,其中包含用户的UPN信息。

内容的提问来源于stack exchange,提问作者Marc George

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:53:18