Skip to content

Commit 802630c

Browse files
PowerShellTeamdaxian-dbw
authored andcommitted
Add source files for Microsoft.PowerShell.LocalAccounts [SD:709776]
Commit 15b1623
1 parent 1829beb commit 802630c

30 files changed

Lines changed: 9894 additions & 0 deletions
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
#region Using directives
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Management.Automation;
5+
using System.Security.Principal;
6+
7+
using System.Management.Automation.SecurityAccountsManager;
8+
using System.Management.Automation.SecurityAccountsManager.Extensions;
9+
10+
using Microsoft.PowerShell.LocalAccounts;
11+
using System.Diagnostics.CodeAnalysis;
12+
#endregion
13+
14+
15+
namespace Microsoft.PowerShell.Commands
16+
{
17+
/// <summary>
18+
/// The Add-LocalGroupMember cmdlet adds one or more users or groups to a local
19+
/// group.
20+
/// </summary>
21+
[Cmdlet(VerbsCommon.Add, "LocalGroupMember",
22+
SupportsShouldProcess = true,
23+
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717987")]
24+
[Alias("algm")]
25+
public class AddLocalGroupMemberCommand : PSCmdlet
26+
{
27+
#region Instance Data
28+
private Sam sam = null;
29+
#endregion Instance Data
30+
31+
#region Parameter Properties
32+
/// <summary>
33+
/// The following is the definition of the input parameter "Group".
34+
/// Specifies a security group from the local Security Accounts Manager.
35+
/// </summary>
36+
[Parameter(Mandatory = true,
37+
Position = 0,
38+
ParameterSetName = "Group")]
39+
[ValidateNotNull]
40+
public Microsoft.PowerShell.Commands.LocalGroup Group
41+
{
42+
get { return this.group;}
43+
set { this.group = value; }
44+
}
45+
private Microsoft.PowerShell.Commands.LocalGroup group;
46+
47+
/// <summary>
48+
/// The following is the definition of the input parameter "Member".
49+
/// Specifies one or more users or groups to add to this local group. You can
50+
/// identify users or groups by specifying their names or SIDs, or by passing
51+
/// Microsoft.PowerShell.Commands.LocalPrincipal objects.
52+
/// </summary>
53+
[Parameter(Mandatory = true,
54+
Position = 1,
55+
ValueFromPipeline = true,
56+
ValueFromPipelineByPropertyName = true)]
57+
[ValidateNotNullOrEmpty]
58+
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
59+
public Microsoft.PowerShell.Commands.LocalPrincipal[] Member
60+
{
61+
get { return this.member;}
62+
set { this.member = value; }
63+
}
64+
private Microsoft.PowerShell.Commands.LocalPrincipal[] member;
65+
66+
/// <summary>
67+
/// The following is the definition of the input parameter "Name".
68+
/// Specifies a security group from the local Security Accounts Manager.
69+
/// </summary>
70+
[Parameter(Mandatory = true,
71+
Position = 0,
72+
ParameterSetName = "Default")]
73+
[ValidateNotNullOrEmpty]
74+
public string Name
75+
{
76+
get { return this.name;}
77+
set { this.name = value; }
78+
}
79+
private string name;
80+
81+
/// <summary>
82+
/// The following is the definition of the input parameter "SID".
83+
/// Specifies a security group from the local Security Accounts Manager.
84+
/// </summary>
85+
[Parameter(Mandatory = true,
86+
Position = 0,
87+
ParameterSetName = "SecurityIdentifier")]
88+
[ValidateNotNull]
89+
public System.Security.Principal.SecurityIdentifier SID
90+
{
91+
get { return this.sid;}
92+
set { this.sid = value; }
93+
}
94+
private System.Security.Principal.SecurityIdentifier sid;
95+
#endregion Parameter Properties
96+
97+
98+
#region Cmdlet Overrides
99+
/// <summary>
100+
/// BeginProcessing method.
101+
/// </summary>
102+
protected override void BeginProcessing()
103+
{
104+
sam = new Sam();
105+
}
106+
107+
108+
/// <summary>
109+
/// ProcessRecord method.
110+
/// </summary>
111+
protected override void ProcessRecord()
112+
{
113+
try
114+
{
115+
if (Group != null)
116+
ProcessGroup(Group);
117+
else if (Name != null)
118+
ProcessName(Name);
119+
else if (SID != null)
120+
ProcessSid(SID);
121+
}
122+
catch (GroupNotFoundException ex)
123+
{
124+
WriteError(ex.MakeErrorRecord());
125+
}
126+
}
127+
128+
129+
/// <summary>
130+
/// EndProcessing method.
131+
/// </summary>
132+
protected override void EndProcessing()
133+
{
134+
if (sam != null)
135+
{
136+
sam.Dispose();
137+
sam = null;
138+
}
139+
}
140+
#endregion Cmdlet Overrides
141+
142+
#region Private Methods
143+
144+
/// <summary>
145+
/// Creates a list of <see cref="LocalPrincipal"/> objects
146+
/// ready to be processed by the cmdlet.
147+
/// </summary>
148+
/// <param name="groupId">
149+
/// Name or SID (as a string) of the group we'll be adding to.
150+
/// This string is used primarily for specifying the target
151+
/// in WhatIf scenarios.
152+
/// </param>
153+
/// <param name="member">
154+
/// LocalPrincipal object to be processed
155+
/// </param>
156+
/// <returns>
157+
/// A LocalPrincipal Object to be added to the group
158+
/// </returns>
159+
/// <remarks>
160+
/// <para>
161+
/// LocalPrincipal objects in the Member parameter may not be complete,
162+
/// particularly those created from a name or a SID string given to the
163+
/// Member cmdlet parameter. The object returned from this method contains
164+
/// , at the very least, a valid SID.
165+
/// </para>
166+
/// <para>
167+
/// Any Member objects provided by name or SID string will be looked up
168+
/// to ensure that such an object exists. If an object is not found,
169+
/// an error message is displayed by PowerShell and null will be returned
170+
/// </para>
171+
/// <para>
172+
/// This method also handles the WhatIf scenario. If the Cmdlet's
173+
/// <b>ShouldProcess</b> method returns false on any Member object,
174+
/// that object will not be included in the returned List.
175+
/// </para>
176+
/// </remarks>
177+
private LocalPrincipal MakePrincipal(string groupId, LocalPrincipal member)
178+
{
179+
LocalPrincipal principal = null;
180+
// if the member has a SID, we can use it directly
181+
if (member.SID != null)
182+
{
183+
principal = member;
184+
}
185+
else // otherwise it must have been constructed by name
186+
{
187+
SecurityIdentifier sid = this.TrySid(member.Name);
188+
189+
if (sid != null)
190+
{
191+
member.SID = sid;
192+
principal = member;
193+
}
194+
else
195+
{
196+
try
197+
{
198+
principal = sam.LookupAccount(member.Name);
199+
}
200+
catch (Exception ex)
201+
{
202+
WriteError(ex.MakeErrorRecord());
203+
}
204+
}
205+
}
206+
if (CheckShouldProcess(principal, groupId))
207+
return principal;
208+
209+
return null;
210+
}
211+
212+
213+
/// <summary>
214+
/// Determine if a principal should be processed.
215+
/// Just a wrapper around Cmdlet.ShouldProcess, with localized string
216+
/// formatting.
217+
/// </summary>
218+
/// <param name="principal">Name of the principal to be added.</param>
219+
/// <param name="groupName">
220+
/// Name of the group to which the members will be added.
221+
/// </param>
222+
/// <returns>
223+
/// True if the principal should be processed, false otherwise.
224+
/// </returns>
225+
private bool CheckShouldProcess(LocalPrincipal principal, string groupName)
226+
{
227+
if (principal == null)
228+
return false;
229+
230+
string msg = StringUtil.Format(Strings.ActionAddGroupMember, principal.ToString());
231+
232+
return ShouldProcess(groupName, msg);
233+
}
234+
235+
/// <summary>
236+
/// Add members to a group.
237+
/// </summary>
238+
/// <param name="group">
239+
/// A <see cref="LocalGroup"/> object representing the group to which
240+
/// the members will be added.
241+
/// </param>
242+
private void ProcessGroup(LocalGroup group)
243+
{
244+
string groupId = group.Name ?? group.SID.ToString();
245+
foreach (var member in this.Member)
246+
{
247+
LocalPrincipal principal = MakePrincipal(groupId, member);
248+
if (null != principal)
249+
{
250+
var ex = sam.AddLocalGroupMember(group, principal);
251+
if (null != ex)
252+
{
253+
WriteError(ex.MakeErrorRecord());
254+
}
255+
}
256+
}
257+
}
258+
259+
/// <summary>
260+
/// Add members to a group specified by name.
261+
/// </summary>
262+
/// <param name="name">
263+
/// The name of the group to which the members will be added.
264+
/// </param>
265+
private void ProcessName(string name)
266+
{
267+
ProcessGroup(sam.GetLocalGroup(name));
268+
}
269+
270+
/// <summary>
271+
/// Add members to a group specified by SID.
272+
/// </summary>
273+
/// <param name="groupSid">
274+
/// A <see cref="SecurityIdentifier"/> object identifying the group
275+
/// to which the members will be added.
276+
/// </param>
277+
private void ProcessSid(SecurityIdentifier groupSid)
278+
{
279+
foreach (var member in this.Member)
280+
{
281+
LocalPrincipal principal = MakePrincipal(groupSid.ToString(), member);
282+
if (null != principal)
283+
{
284+
var ex = sam.AddLocalGroupMember(groupSid, principal);
285+
if (null != ex)
286+
{
287+
WriteError(ex.MakeErrorRecord());
288+
}
289+
}
290+
}
291+
}
292+
293+
#endregion Private Methods
294+
}//End Class
295+
296+
}//End namespace
297+

0 commit comments

Comments
 (0)