回答
检查systemFlags属性。 ADS_SYSTEMFLAG_ENUM上的MS页面是C++的例子,应该很容易适应C#。
您需要打开对象的ACL(ntSecurityDescriptor
属性)并查找拒绝所有人删除。 ActiveDirectorySecurity
类为您提供了一个托管包装 - http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectorysecurity.aspx。
您可以在PowerShell中使用活动目录cmdlet执行简单的命令行 Get-ADObject -Filter * -Properties ProtectedFromAccidentalDeletion |其中{$ _。ProtectedFromAccidentalDeletion -eq $ true}
然后如果您想要更改它 - 管它到| Set-ADObject -ProtectedFromAccidentalDeletion:$ false
以下是用于获取OU并查找确定是否防止意外删除的ACL的代码段。
这是通过使用[的System.DirectoryServices],[System.Security.AccessControl]和[System.Security.Principal]命名空间
bool? protected = null;
DirectoryEntry de = new DirectoryEntry("LDAP://OU=TestOu,DC=Test,DC=Local", "Username", "Password");
ActiveDirectorySecurity ads = de.ObjectSecurity;
AuthorizationRuleCollection rules = ads.GetAccessRules(true, true, typeof(NTAccount);
foreach (ActiveDirectoryAccessRule rule in rules)
if (rule.AccessControlType == AccessControlType.Deny)
if (rule.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete))
protected = true;
else
protected = false;
我跑这对我的根的OU与一个超过150施加ACL和它在一两秒钟内回复了答案。
为了保护AD对象,需要两个ACE。一种是必须在要保护的对象上设置的“拒绝Delete + DeleteTree”,第二个“拒绝DeleteChild”必须设置在父对象上。 如果应该删除保护,则只能删除对象上的ACE。父对象上的ACE必须保留,因为否则同一OU中的其他对象将不再受保护!
这里IST我的代码这是工作完美:
//using System.Security.Principal
//using System.DirectoryServices;
public static void SetProtectADObject(DirectoryEntry ent, bool Protect = true)
{
//get parent object
var parentEnt = new DirectoryEntry(ent.Parent.Path);
//refresh objects
ent.RefreshCache();
parentEnt.RefreshCache();
if (Protect)
{
#region Protect
try
{
IdentityReference everyOneAccount = new NTAccount("Everyone").Translate(typeof(SecurityIdentifier)); //S-1-1-0
var objAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.Delete | ActiveDirectoryRights.DeleteTree, AccessControlType.Deny);
var parentAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.DeleteChild, AccessControlType.Deny);
//check if ace present on object
var objACL = ent.ObjectSecurity;
bool acePresent = false;
foreach (ActiveDirectoryAccessRule ace in objACL.GetAccessRules(true, false, typeof(NTAccount)))
{
if (ace.IdentityReference.Value == "Everyone")
{
if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
}
}
if (!acePresent)
{
//set ace to object
objACL.AddAccessRule(objAce);
//commit changes
ent.CommitChanges();
}
//check if ace present on parent object
var parentACL = parentEnt.ObjectSecurity;
bool parentAcePresent = false;
foreach (ActiveDirectoryAccessRule ace in parentACL.GetAccessRules(true, false, typeof(NTAccount)))
{
if (ace.IdentityReference.Value == "Everyone")
{
if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild)) { parentAcePresent = true; break; }
else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { parentAcePresent = true; break; }
}
}
if (!parentAcePresent)
{
//set ace to parent object
parentACL.AddAccessRule(parentAce);
//commit changes
parentEnt.CommitChanges();
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Error protecting object {0}", ent.Path), ex);
}
#endregion
}
else
{
#region Unprotect
//to remove the protection we remove only the ACE from the object, not from the parent.
//The ACE on the parent must be in place because otherwise other objects on the same level will not protected anymore!
try
{
IdentityReference everyOneAccount = new NTAccount("Everyone").Translate(typeof(SecurityIdentifier)); //S - 1 - 1 - 0
var objAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.Delete | ActiveDirectoryRights.DeleteTree, AccessControlType.Deny);
//check if ace present on object
var objACL = ent.ObjectSecurity;
bool acePresent = false;
foreach (ActiveDirectoryAccessRule ace in objACL.GetAccessRules(true, false, typeof(NTAccount)))
{
if (ace.IdentityReference.Value == "Everyone")
{
if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
}
}
//set ace to object
if (acePresent)
{
ent.ObjectSecurity.RemoveAccessRule(objAce);
ent.CommitChanges();
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Error unprotecting object {0}", ent.Path), ex);
}
#endregion
}
}
public static bool IsADObjectProtected(DirectoryEntry ent)
{
//get parent object
var parentEnt = new DirectoryEntry(ent.Parent.Path);
//refresh objects
ent.RefreshCache();
parentEnt.RefreshCache();
//get current ACLs
ActiveDirectorySecurity acl = ent.ObjectSecurity;
ActiveDirectorySecurity parentAcl = ent.Parent.ObjectSecurity;
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
AuthorizationRuleCollection parentRules = parentAcl.GetAccessRules(true, false, typeof(NTAccount));
//check object acl
bool acePresent = false;
foreach (ActiveDirectoryAccessRule ace in rules)
{
Console.WriteLine(ace.AccessControlType.ToString());
if (ace.AccessControlType == AccessControlType.Deny)
{
if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
}
}
//check parent acl
bool parentAcePresent = false;
foreach (ActiveDirectoryAccessRule ace in parentRules)
{
if (ace.AccessControlType == AccessControlType.Deny)
{
if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild)) { parentAcePresent = true; break; }
else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { parentAcePresent = true; break; }
}
}
return parentAcePresent && acePresent;
}
- 1. 检查用户是否存在于ou
- 2. SSIS检查记录是否被删除
- 3. 检查记录是否老删除它
- 4. 是否可以删除“检查元素”?
- 5. 检查是否安全删除一行
- 6. 意外删除mainWindow.xib
- 7. strip意外删除'_'
- 8. Powershell:如何检查组或帐户是否从SID中删除?
- 9. 检查组件是否从JTable中删除
- 10. 检查它是否存在后从表中删除
- 11. 如何检查一个元素是否已从DOM中删除?
- 12. 防止从BigCommerce API中意外删除
- 13. 从MySQL服务器意外删除表
- 14. 意外删除iOS框架
- 15. WPF意外删除了App.xaml
- 16. 防止意外删除
- 17. postgresql:意外删除pg_filenode.map
- 18. 意外删除laravel.log内容
- 19. Python - 检查图是否连接 - 意外的循环行为
- 20. 检查链接是否是外部的
- 21. 意外行为检查
- 22. 检查意向是否存在
- 23. 使用删除键检查下一个项目是否被删除
- 24. 检测通知是否已被删除
- 25. Powershell删除OU中的所有用户
- 26. 检查点是否从PHP
- 27. XSLT:检查值是否为空然后删除标记
- 28. 如何检查文件是否可以被删除
- 29. 如何在删除前检查元素是否含有HTML? jQuery
- 30. 检查领域对象是否被删除
我不是在上面得到任何东西,但我会尽量找在.NET Framework中相同的枚举,并尝试转换代码...任何人做知道更好的东西。 – sunder 2012-08-08 09:52:05
@sunder对不起,我不知道。 – 2012-08-08 14:17:49
这并不反映意外删除复选框的保护。系统标志只会反映该对象是否完全不能被删除(如关键的系统对象)。 – 2012-08-08 19:40:07