摘点以前写的一个权限管理工具里比较关键的代码,涉及到Windows用户、用户组、权限操作、共享管理。
- 目录:
- 1. 遍历用户和组(ShcemaClassName: User, Group, Service)
- 2. 查找用户、组(查询条件:sid、name、description)
- 3. 创建用户组
- 4. 从用户组中添加/删除用户
- 5. 遍历用户组成员
- 6. 修改用户密码(ChangePassword: 旧密码,新密码)
- 7. 重置用户密码(SetPassword: 只提供新密码)
- 8. 修改/创建用户
- 9. 创建共享
首先获取顶级DirectoryEntry
var LocalMachineEntries =
new System.DirectoryServices.DirectoryEntry(
"WinNT://" + Environment.MachineName + ",computer");
ActionResult类仅用于保存操作结果,没有特殊东西,老项目里摘的代码,懒得改了。
1. 遍历用户和组(ShcemaClassName: User, Group, Service)
var LocalMachineEntries =
new System.DirectoryServices.DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
foreach (System.DirectoryServices.DirectoryEntry gentry in LocalMachineEntries.Children)
{
string schema = gentry.SchemaClassName;
string sid = schema.Equals("service", StringComparison.OrdinalIgnoreCase) ?
"" : BitConverter.ToString((byte[])gentry.InvokeGet("objectSid"));
Console.WriteLine($"{sid} - {gentry.SchemaClassName} - {gentry.Name}");
}
2. 查找用户、组(sid、name、description)
/// <summary>
/// 查找用户
/// </summary>
/// <param name="loginname"></param>
/// <param name="DescLimit">是否限定Description查询(是:只查询Description符合要求的用户;否:查询所有系统用户)</param>
/// <param name="uentry"></param>
/// <returns></returns>
public static DirectoryEntry FindUser(string loginname,string desc, bool descLimit = true)
{
try
{
DirectoryEntry uentry = LocalMachineEntry.Children.Find(loginname, "user");
if (uentry.InvokeGet("Description").ToString().ToUpper() == desc || !descLimit)
{
return uentry;
}
else
{
return null;
}
}
catch (Exception)
{
return null;
}
}
public static DirectoryEntry FindGroupByName(string groupname,string desc, bool descLimit = true)
{
try
{
DirectoryEntry gentry = LocalMachineEntry.Children.Find(groupname, "group");
if (gentry.InvokeGet("Description").ToString().ToUpper() == desc || !descLimit)
{
return gentry;
}
else
{
return null;
}
}
catch (Exception)
{
return null;
}
}
public static Group FindGroupBySid(string sid)
{
try
{
foreach (DirectoryEntry gentry in LocalMachineEntry.Children)
{
if (gentry.SchemaClassName.ToUpper() == "GROUP" && BitConverter.ToString((byte[])gentry.InvokeGet("objectSid")).ToUpper() == sid)
{
if (DicGroups.ContainsKey(gentry.Name))
{
return DicGroups[gentry.Name];
}
else
{
Group g = new Group() { Entry = gentry, Name = gentry.Name, Sid = sid, Users = new List<User>() };
DicGroups.Add(g.Name, g);
return g;
}
}
}
return null;
}
catch (Exception)
{
return null;
}
}
3. 创建用户组
public static DirectoryEntry CreateGroup(string groupname)
{
DirectoryEntry gEntry = LocalMachineEntry.Children.Add(groupname, "Group");
gEntry.CommitChanges();
return gEntry;
}
4. 从用户组中添加/删除用户
public static void SetGroup(string user, string group, DepartmentRole role)
{
DirectoryEntry userEntry = FindUser(user, "");
DirectoryEntry gEntry = FindGroupByName(group, "");
gEntry.Invoke("Add", userEntry.Path);
gEntry.Invoke("Remove", userEntry.Path);
}
5. 遍历用户组成员
public static IEnumerable GetGroupUsers(string groupname)
{
DirectoryEntry g = LocalMachineEntry.Children.Find(groupname, "Group");
return g.Invoke("Members") as IEnumerable;
}
6. 修改用户密码(旧密码,新密码)
public static ActionResult ChangePassword(string loginname, string oldPass, string newPass)
{
DirectoryEntry ue = FindUser(loginname);
if (ue is null) return new ActionResult() { Result = false, Message = "修改失败:用户不存在。" };
try
{
object[] password = new object[] { oldPass, newPass };
object ret = ue.Invoke("ChangePassword", password);
ue.CommitChanges();
ue.Close();
return new ActionResult();
}
catch (Exception ex)
{
WriteLog("WINFORM", "CHANGEPASSWD", "EXCEPTION", ex.ToString());
return new ActionResult() { Result = false, Message = $"修改失败:ERR_EX0" };
}
}
7. 重置用户密码(只提供新密码)
public static ActionResult ResetPassword(string loginname, string newPassword)
{
try
{
DirectoryEntry ue = FindUser(loginname);
if (ue is null)
{
return new ActionResult() { Result = false, Message = "找不到该用户" };
}
object ret = ue.Invoke("SetPassword", newPassword);
ue.CommitChanges();
ue.Close();
return new ActionResult();
}
catch (Exception ex)
{
return new ActionResult() { Result = false, Message = ex.Message };
}
}
8. 修改/创建用户
/// <summary>
/// 创建/修改用户
/// </summary>
/// <param name="loginname">登录账号</param>
/// <param name="password">密码</param>
/// <param name="group">所在用户组</param>
/// <param name="fullname">全名</param>
/// <returns></returns>
public static ActionResult UpdateUser(string loginname, string password, string group, string fullname = "")
{
var gEntry = FindGroupByName(group, "", false);
DirectoryEntry uEntry = null;
try
{
uEntry = FindUser(loginname, "", false);
}
catch (Exception)
{
}
if (uEntry is null)
{//用户不存在时,操作类型为:新建用户
if (string.IsNullOrEmpty(password)) return new ActionResult() { Message = "创建用户失败,密码不能为空", Result = false };
uEntry = LocalMachineEntry.Children.Add(loginname, "User");
uEntry.Properties["FullName"].Add(fullname); //用户全称
uEntry.Invoke("SetPassword", password); //用户密码
uEntry.InvokeSet("Description", DescriptionFlag);
uEntry.InvokeSet("UserFlags", PRIV_UNBLOCK);
try
{
uEntry.CommitChanges();
return new ActionResult() { Message = $"用户{loginname}创建成功。" };
}
catch (Exception ex)
{
return new ActionResult() { Result = false, Message = $"用户创建失败:\r\n{ex.Message}" };
}
}
else
{
//密码参数不为空时才修改密码
if (!string.IsNullOrEmpty(password)) uEntry.Invoke("SetPassword", password);
uEntry.InvokeSet("FullName", new object[] { fullname });
uEntry.InvokeSet("UserFlags", new object[] { PRIV_UNBLOCK });
uEntry.CommitChanges();
return new ActionResult() { Message = $"用户{loginname}修改成功。" };
}
}
9. 创建共享
public static ActionResult CreateShare(string pathroot, string group, string sid)
{
//NTFS权限
DirectoryInfo dir = new DirectoryInfo(pathroot);
DirectorySecurity dirSecurity = new DirectorySecurity();
InheritanceFlags inherits = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
FileSystemAccessRule rule1 =//普通权限
new FileSystemAccessRule(group, FileSystemRights.ReadAndExecute, inherits, PropagationFlags.None, AccessControlType.Allow);
FileSystemAccessRule rule2 =//所有权限
new FileSystemAccessRule(group, FileSystemRights.FullControl, inherits, PropagationFlags.None, AccessControlType.Allow);
//共享权限
List<string> msg = new List<string>();
dirSecurity.ModifyAccessRule(AccessControlModification.Add, rule1, out bool res1);
dirSecurity.ModifyAccessRule(AccessControlModification.Add, rule2, out bool res2);
dir.SetAccessControl(dirSecurity);
ManagementObject trustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);
trustee["Name"] = group;
trustee["SID"] = sid;
//ACE0, ACE1, ACE2对应禁用、普通、管理,按需取用
ManagementObject ACE0 = new ManagementClass(new ManagementPath("Win32_Ace"), null);//禁用
ManagementObject ACE1 = new ManagementClass(new ManagementPath("Win32_Ace"), null);//普通
ManagementObject ACE2 = new ManagementClass(new ManagementPath("Win32_Ace"), null);//管理
ACE0["AccessMask"] = 2032127;
ACE0["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
ACE0["AceType"] = AceType.AccessDenied;
ACE0["Trustee"] = trustee;
ACE1["AccessMask"] = 1179817;
ACE1["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
ACE1["AceType"] = AceType.AccessAllowed;
ACE0["Trustee"] = trustee;
ACE2["AccessMask"] = 2032127;
ACE2["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
ACE2["AceType"] = AceType.AccessAllowed;
ACE0["Trustee"] = trustee;
ManagementObject secDescriptor = new ManagementClass(new ManagementPath("Win32_SecurityDescriptor"), null);
secDescriptor["ControlFlags"] = 4;
secDescriptor["DACL"] = new object[] { ACE0, ACE1, ACE2 };
ManagementClass managementClass = new ManagementClass("Win32_Share");
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
inParams["Name"] = group;
inParams["Description"] = $"{group} 共享目录";
inParams["Path"] = pathroot;
inParams["Type"] = 0x0; // Disk Drive
inParams["Access"] = secDescriptor;
outParams = managementClass.InvokeMethod("Create", inParams, null);
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
{
throw new Exception("创建共享失败");
}
if (res1 && res2)
{
return new ActionResult();
}
else
{
return new ActionResult() { Result = false, Message = string.Join("\r\n", msg) };
}
}