【问题标题】:WMI Folder Add ACL Type MismatchWMI 文件夹添加 ACL 类型不匹配
【发布时间】:2018-11-18 06:18:56
【问题描述】:

我正在尝试编写一个小应用程序来更新文件夹权限。我编写了以下代码来删除oldGroup并添加newGroup

当我调用InvokeMethod 时,我发现了一个异常HRESULT 0x80041005 - Type Mismatch。不是很有帮助!如果我注释掉 newAces.Add(newAce); 旧组已成功删除,那么问题出在我的新 ACE (newAce) 或受托人 (trustee) 上。我尝试了几种实例化trustee 的方法,在下面注释掉了。

public void Function()
    {
        CimInstance QueryInstance(CimSession session, string cimNamespace, string query)
        {
            IEnumerable<CimInstance> queryInstances = session.QueryInstances(cimNamespace, "WQL", query);
            return queryInstances.FirstOrDefault();
        }
        string computerName = "localhost";
        string namespaceName = @"root\cimv2";
        string oldGroup = "Everyone";
        string newGroup = "Not Everyone";
        DComSessionOptions sessionOptions = new DComSessionOptions
        {
            Timeout = new TimeSpan(0, 2, 0)
        };
        CimSession cimSession = CimSession.Create(computerName, sessionOptions);

        CimInstance trustee = new CimInstance(cimSession.GetClass(namespaceName, "Win32_Trustee"));
        //CimInstance trustee = new CimInstance("Win32_Trustee");
        trustee.CimInstanceProperties.Single(p => p.Name == "Name").Value = newGroup;
        //trustee.CimInstanceProperties.Add(CimProperty.Create("Name", newGroup, CimType.String, CimFlags.Key));
        trustee.CimInstanceProperties.Single(p => p.Name == "Domain").Value = "GLOBAL";
        //trustee.CimInstanceProperties.Add(CimProperty.Create("Domain", "GLOBAL", CimType.String, CimFlags.Key));

        CimInstance newAce = new CimInstance("Win32_ACE");
        newAce.CimInstanceProperties.Add(CimProperty.Create("AccessMask", 1179817, CimFlags.Key));
        newAce.CimInstanceProperties.Add(CimProperty.Create("AceFlags", 3, CimFlags.Key));
        newAce.CimInstanceProperties.Add(CimProperty.Create("AceType", 0, CimFlags.Key));
        newAce.CimInstanceProperties.Add(CimProperty.Create("Trustee", trustee, CimFlags.Key));

        CimInstance logicalFileSecSetting = QueryInstance(cimSession, namespaceName, @"select * from Win32_LogicalFileSecuritySetting where Path='C:\\dev\\temp\\wmi'");
        CimMethodResult methodResult;
        methodResult = cimSession.InvokeMethod(namespaceName, logicalFileSecSetting, "GetSecurityDescriptor", new CimMethodParametersCollection());
        CimInstance descriptor = (CimInstance)methodResult.OutParameters.SingleOrDefault(p => p.Name == "Descriptor").Value;
        IEnumerable<CimInstance> aces = (IEnumerable<CimInstance>)descriptor.CimInstanceProperties.SingleOrDefault(p => p.Name == "DACL").Value;
        List<CimInstance> newAces = aces.Where(ace =>
        {
            CimInstance aceTrustee = (CimInstance)ace.CimInstanceProperties.Single(p => p.Name == "Trustee").Value;
            string aceTrusteeName = (string)aceTrustee.CimInstanceProperties.Single(p => p.Name == "Name").Value;
            return aceTrusteeName != oldGroup;
        }).ToList();

        newAces.Add(newAce);
        descriptor.CimInstanceProperties.SingleOrDefault(p => p.Name == "DACL").Value = newAces.ToArray();

        CimInstance cimDirectory = QueryInstance(cimSession, namespaceName, @"SELECT * FROM Win32_Directory WHERE Name='C:\\dev\\temp\\wmi'");
        CimMethodParametersCollection methodParameters = new CimMethodParametersCollection
        {
            CimMethodParameter.Create("SecurityDescriptor", descriptor, CimType.Instance, CimFlags.In),
            CimMethodParameter.Create("Option", 4, CimType.UInt32, CimFlags.In)
        };
        methodResult = cimSession.InvokeMethod(namespaceName, cimDirectory, "ChangeSecurityPermissions", methodParameters);
    }

谁能帮助我更熟悉 Microsoft 管理基础架构?提前致谢。

【问题讨论】:

    标签: c# .net-core wmi acl


    【解决方案1】:

    我今天早上想通了。将SID 和相关属性添加到Win32_Trustee CimInstance 对象后,我的新组ACE 将根据需要添加到文件夹中。当我查询新的组详细信息时,会从 Active Directory 中检索到 SID 字符串。

    public void Function()
    {
        CimInstance QueryInstance(CimSession session, string cimNamespace, string query)
        {
            IEnumerable<CimInstance> queryInstances = session.QueryInstances(cimNamespace, "WQL", query);
            return queryInstances.FirstOrDefault();
        }
        byte[] BuildObjectSid(string sid)
        {
            SecurityIdentifier securityIdentifier = new SecurityIdentifier(sid);
            byte[] bytes = new byte[securityIdentifier.BinaryLength];
            securityIdentifier.GetBinaryForm(bytes, 0);
            return bytes;
        }
        string computerName = "localhost";
        string namespaceName = @"root\cimv2";
        string oldGroup = "Everyone";
        string newGroup = "Not Everyone";
        string newGroupSidString = "S-1-5-21";
        byte[] newGroupSid = BuildObjectSid(newGroupSidString);
        DComSessionOptions sessionOptions = new DComSessionOptions
        {
            Timeout = new TimeSpan(0, 2, 0)
        };
        CimSession cimSession = CimSession.Create(computerName, sessionOptions);
        CimInstance trustee = new CimInstance(cimSession.GetClass(namespaceName, "Win32_Trustee"));
        trustee.CimInstanceProperties["Domain"].Value = "GLOBAL";
        trustee.CimInstanceProperties["Name"].Value = newGroup;
        trustee.CimInstanceProperties["SIDString"].Value = newGroupSidString;
        trustee.CimInstanceProperties["SID"].Value = newGroupSid;
        trustee.CimInstanceProperties["SidLength"].Value = newGroupSid.Length;
    
        CimInstance newAce = new CimInstance(cimSession.GetClass(namespaceName, "Win32_ACE"));
        newAce.CimInstanceProperties["AccessMask"].Value = 1179817;
        newAce.CimInstanceProperties["AceFlags"].Value = 3;
        newAce.CimInstanceProperties["AceType"].Value = 0;
        newAce.CimInstanceProperties["Trustee"].Value = trustee;
    
        string lfsQuery = @"select * from Win32_LogicalFileSecuritySetting where Path='C:\\dev\\temp\\wmi'";
        CimInstance logicalFileSecSetting = QueryInstance(cimSession, namespaceName, lfsQuery);
        CimClass cimClass = cimSession.GetClass(namespaceName, "Win32_LogicalFileSecuritySetting");
        CimMethodResult methodResult;
        methodResult = cimSession.InvokeMethod(namespaceName, logicalFileSecSetting, "GetSecurityDescriptor", new CimMethodParametersCollection());
        CimInstance descriptor = (CimInstance)methodResult.OutParameters["Descriptor"].Value;
        CimInstance[] aces = (CimInstance[])descriptor.CimInstanceProperties["DACL"].Value;
        for (int i = 0; i < aces.Length; i++)
        {
            CimInstance aceTrustee = (CimInstance)aces[i].CimInstanceProperties["Trustee"].Value;
            string aceTrusteeName = (string)aceTrustee.CimInstanceProperties["Name"].Value;
            if (aceTrusteeName == oldGroup)
            {
                aces[i] = newAce;
            }
        }
        descriptor.CimInstanceProperties["DACL"].Value = aces;
        CimInstance cimDirectory = QueryInstance(cimSession, namespaceName, @"SELECT * FROM Cim_Directory WHERE Name='C:\\dev\\temp\\wmi'");
        CimMethodParametersCollection methodParameters = new CimMethodParametersCollection
        {
            CimMethodParameter.Create("SecurityDescriptor", descriptor, CimType.Instance, CimFlags.In),
            CimMethodParameter.Create("Option", 4, CimType.UInt32, CimFlags.In)
        };
        methodResult = cimSession.InvokeMethod(namespaceName, cimDirectory, "ChangeSecurityPermissions", methodParameters);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2017-09-30
      • 2021-10-31
      • 2021-06-10
      相关资源
      最近更新 更多