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

如何在SSIS(VS10)中获取AD用户memberof属性完整成员信息?

嘿,刚好我之前在SSIS(VS2010)里处理过一模一样的需求——获取AD用户的完整成员身份,输出成空格分隔的组DN格式,和你用dsget user "cn=...." -memberof命令得到的效果一致。给你分享两种靠谱的实现方式,你可以根据自己的习惯选:

方案1:在SSIS C#脚本转换中直接调用ADSI获取成员组

这种方法不需要依赖外部命令,直接在脚本里操作AD,稳定性和可控性更好。

  1. 打开脚本转换编辑器,先添加输入列(就是你存储用户DN的列,比如命名为UserDN),再添加输出列(比如叫MemberOfGroups,数据类型选DT_WSTR,长度设4000足够用)。
  2. 在脚本编辑器的“引用”里,添加System.DirectoryServices和System.DirectoryServices.AccountManagement两个程序集。
  3. 替换Input0_ProcessInputRow方法为以下代码:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.DirectoryServices.AccountManagement;
using System.Linq;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    private PrincipalContext _adContext;

    public override void PreExecute()
    {
        base.PreExecute();
        // 初始化AD上下文,默认用当前域,也可以指定域名比如new PrincipalContext(ContextType.Domain, "yourdomain.com")
        _adContext = new PrincipalContext(ContextType.Domain);
    }

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        if (string.IsNullOrEmpty(Row.UserDN))
        {
            Row.MemberOfGroups = string.Empty;
            return;
        }

        try
        {
            // 通过用户DN查找AD用户
            using (UserPrincipal user = UserPrincipal.FindByIdentity(_adContext, IdentityType.DistinguishedName, Row.UserDN))
            {
                if (user != null)
                {
                    // 获取用户直接所属的所有组的DN,用空格拼接成目标格式
                    var groupDNs = user.GetGroups().Select(g => g.DistinguishedName);
                    Row.MemberOfGroups = string.Join(" ", groupDNs);
                }
                else
                {
                    Row.MemberOfGroups = string.Empty;
                }
            }
        }
        catch (Exception ex)
        {
            // 异常处理:可以输出空值,也可以用FireError记录错误日志
            Row.MemberOfGroups = string.Empty;
            // ComponentMetaData.FireError(0, "GetADMemberOf", ex.Message, string.Empty, 0, out bool cancel);
        }
    }

    public override void PostExecute()
    {
        base.PostExecute();
        _adContext.Dispose();
    }
}

如果需要获取嵌套组(用户所属组的父组),把user.GetGroups()换成user.GetAuthorizationGroups()就行,不过这个方法会返回所有授权组(包括内置组),按需调整。

方案2:在SSIS脚本中执行dsget命令并处理输出

如果你更习惯用dsget命令,也可以在脚本里调用cmd执行命令,再捕获输出处理成目标格式:

同样在脚本转换的Input0_ProcessInputRow方法里用以下代码:

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Diagnostics;
using System.Text;
using System.Linq;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        if (string.IsNullOrEmpty(Row.UserDN))
        {
            Row.MemberOfGroups = string.Empty;
            return;
        }

        try
        {
            // 构造dsget命令
            string command = $"dsget user \"{Row.UserDN}\" -memberof";
            ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", $"/c {command}")
            {
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                StandardOutputEncoding = Encoding.Unicode
            };

            using (Process process = Process.Start(psi))
            {
                string output = process.StandardOutput.ReadToEnd();
                string error = process.StandardError.ReadToEnd();
                process.WaitForExit();

                if (!string.IsNullOrEmpty(error))
                {
                    Row.MemberOfGroups = string.Empty;
                    return;
                }

                // 处理输出:跳过表头、空行,用空格拼接组DN
                string[] lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                var groupDNs = lines.Skip(1).Select(line => line.Trim());
                Row.MemberOfGroups = string.Join(" ", groupDNs);
            }
        }
        catch (Exception ex)
        {
            Row.MemberOfGroups = string.Empty;
            // 异常处理逻辑
            // ComponentMetaData.FireError(0, "ExecuteDsget", ex.Message, string.Empty, 0, out bool cancel);
        }
    }
}

额外小贴士

  • 确保SSIS运行的账户有AD的读取权限,否则会出现访问被拒绝的错误。
  • 如果VS2010里引用AccountManagement程序集有兼容性问题,可以改用更轻量的DirectoryEntry方式:
    using (DirectoryEntry userEntry = new DirectoryEntry($"LDAP://{Row.UserDN}"))
    {
        userEntry.RefreshCache(new[] { "memberOf" });
        var groupDNs = userEntry.Properties["memberOf"].Cast<string>();
        Row.MemberOfGroups = string.Join(" ", groupDNs);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:28:40