在C#中调用动态PSObject属性返回RuntimeBinderException

时间:2016-04-05 09:39:03

标签: c# powershell dynamic active-directory

我在我的C#代码中集成了PowerShell脚本,并使用C#调用它。

脚本的作用是从 Active Directory 中获取一些组及其成员,并将其作为 PSObject 返回到我的C#代码中。此对象具有名为“Member”的属性,该属性包含该组包含的成员的 Array 。这些成员中的每一个都有其他属性,如EmailAddress,Name等,我通过PowerShell添加,我也测试了脚本,它按预期工作。

这是我在C#中的代码,我尝试使用动态变量来获取组成员:

GetGroupMembers(PSObject groupObject) {
    // These are the group members, an object Array with 4 objects gets returned
    dynamic members = groupObject.Properties["Member"].Value;

    foreach (var member in members) {
        string objectClass = member.ObjectClass;
        ADObject memberObject;

        switch (objectClass) {
            case "user":
                // This is where the exception gets thrown, since the "EmailAddress" value is null
                string email = member.Properties["EmailAddress"].Value.ToString();
            [...]

这里的问题是,在调试时,我实际上可以看到动态成员变量中存在该属性,但是在成员变量中它被删除了foreach循环。 Here's a screenshot I made during debugging, which shows clearly that the property is available in the members variable.

我得到的异常是一个RuntimeBinderException,消息“无法对空引用执行运行时绑定” 在CallSite.Target(Closure,CallSite,Object,String)         在System.Dynamic.UpdateDelegates.UpdateAndExecute2 [T0,T1,TRet](CallSite站点,T0 arg0,T1 arg1)

也许错误很明显,但我似乎无法弄清楚我做错了什么。非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

我设法解决了这个问题。我根本没有使用dynamic类型,如果有人仍在寻找解决方案,我就是这样解决的:

GetGroupMembers(PSObject groupObject) {
        object membersValue = groupObject.Properties["Member"].Value;
        object[] members;

        // Does the group have any members?
        if (membersValue == null)
            return null;

        // If the group has only one member, then it won't be an object array but rather a PSObject
        if (membersValue.GetType() == typeof(PSObject))
        {
            members = new object[] {membersValue};
        }
        else
        {
            // The group has more than one member, in this case we can cast it to an object array
            members = ((object[])membersValue);
        }

        // use PSObject to access the object's properties
        foreach (PSObject member in members)
        {
            string objectClass = member.Properties["ObjectClass"].Value.ToString();
            Guid objectGuid = new Guid (member.Properties["objectGuid"].Value.ToString());

            ADObject memberObject;

            switch (objectClass)
            {
                case "user":
                    // You might want to check for null here as well before getting the values from these properties
                    string givenName = member.Properties["GivenName"].Value.ToString();
                    string surname = member.Properties["Surname"].Value.ToString();
                    string displayName = member.Properties["DisplayName"].Value.ToString();
                    [...]