-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathGetLocalGroups.ps1
155 lines (136 loc) · 3.76 KB
/
GetLocalGroups.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
Add-Type -TypeDefinition @"
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using NET_API_STATUS = System.UInt32;
namespace WinApi
{
public class LocalGroup
{
private List<string> _members = null;
private string _name;
private string _comment;
public LocalGroup(string Name, string Comment)
{
_name = Name;
_comment = Comment;
}
public string Name { get { return _name; } }
public string Comment { get { return _comment; } }
public List<String> Members
{
get
{
if (null == _members)
{
_members = NetApi32.GetGroupMembers(Name);
}
return _members;
}
}
}
public static class NetApi32
{
const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
const uint NERR_Success = 0;
public static List<LocalGroup> GetLocalGroups()
{
List<LocalGroup> result = new List<LocalGroup>();
IntPtr bufptr;
uint entriesread = 0;
uint totalentries = 0;
NET_API_STATUS nas;
nas = NetLocalGroupEnum(IntPtr.Zero, 1, out bufptr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, IntPtr.Zero);
if (nas == NERR_Success)
{
LOCALGROUP_INFO_1 lgi;
IntPtr current = bufptr;
string name;
string comment;
try
{
for (int i = 0; i < entriesread; i++)
{
lgi = (LOCALGROUP_INFO_1)Marshal.PtrToStructure(current, typeof(LOCALGROUP_INFO_1));
name = Marshal.PtrToStringAuto(lgi.lpszGroupName);
comment = Marshal.PtrToStringAuto(lgi.lpszComment);
result.Add(new LocalGroup(name, comment));
current = new IntPtr(current.ToInt64() + Marshal.SizeOf(lgi));
}
}
finally
{
NetApiBufferFree(bufptr);
}
}
return result;
}
public static List<String> GetGroupMembers(string Groupname)
{
List<String> result = new List<string>();
NET_API_STATUS nas;
IntPtr bufptr;
uint entriesread = 0;
uint totalentries = 0;
nas = NetLocalGroupGetMembers(IntPtr.Zero, Groupname, 1, out bufptr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, IntPtr.Zero);
if (nas == NERR_Success)
{
IntPtr current = bufptr;
string username;
try
{
LOCALGROUP_MEMBERS_INFO_1 lgmi;
for (int i = 0; i < entriesread; i++)
{
lgmi = (LOCALGROUP_MEMBERS_INFO_1)Marshal.PtrToStructure(current, typeof(LOCALGROUP_MEMBERS_INFO_1));
username = Marshal.PtrToStringAuto(lgmi.lgrmi1_name);
result.Add(username);
current = new IntPtr(current.ToInt64() + Marshal.SizeOf(lgmi));
}
}
finally
{
NetApiBufferFree(bufptr);
}
}
return result;
}
[DllImport("netapi32.dll", EntryPoint = "NetApiBufferFree")]
internal static extern void NetApiBufferFree(IntPtr bufptr);
[DllImport("netapi32.dll", EntryPoint = "NetLocalGroupGetMembers", SetLastError = false)]
internal static extern uint NetLocalGroupGetMembers(
IntPtr servername,
[MarshalAs(UnmanagedType.LPWStr)]
string localgroupname,
uint level,
out IntPtr bufptr,
uint prefmaxlen,
ref uint entriesread,
ref uint totalentries,
IntPtr resumehandle);
[DllImport("netapi32.dll", EntryPoint = "NetLocalGroupEnum", SetLastError = false)]
internal static extern uint NetLocalGroupEnum(
IntPtr servername,
uint level,
out IntPtr bufptr,
uint prefmaxlen,
ref uint entriesread,
ref uint totalentries,
IntPtr resumehandle);
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct LOCALGROUP_MEMBERS_INFO_1
{
public IntPtr lgrmi1_sid;
public IntPtr lgrmi1_sidusage;
public IntPtr lgrmi1_name;
}
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct LOCALGROUP_INFO_1
{
public IntPtr lpszGroupName;
public IntPtr lpszComment;
}
}
}
"@
[WinApi.NetApi32]::GetLocalGroups()