WMI 文件夹添加 ACL 类型不匹配
WMI Folder Add ACL Type Mismatch
我正在尝试编写一个小应用程序来更新文件夹权限。我编写了以下代码来删除 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 管理基础结构的人都可以帮助我吗?提前致谢。
我今天早上弄明白了。一旦我将 SID
和相关属性添加到 Win32_Trustee
CimInstance
对象,我的新组 ACE 就会根据需要添加到文件夹中。 SID
字符串是在我查询新组详细信息时从 Active Directory 中检索到的。
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);
}
我正在尝试编写一个小应用程序来更新文件夹权限。我编写了以下代码来删除 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 管理基础结构的人都可以帮助我吗?提前致谢。
我今天早上弄明白了。一旦我将 SID
和相关属性添加到 Win32_Trustee
CimInstance
对象,我的新组 ACE 就会根据需要添加到文件夹中。 SID
字符串是在我查询新组详细信息时从 Active Directory 中检索到的。
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);
}