Add source files for Microsoft.PowerShell.LocalAccounts [SD:709776]

Commit 15b1623
This commit is contained in:
PowerShell Team 2016-06-14 17:01:25 -07:00 committed by Dongbo Wang
parent 1829beb917
commit 802630c261
30 changed files with 9894 additions and 0 deletions

View file

@ -0,0 +1,297 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security.Principal;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Add-LocalGroupMember cmdlet adds one or more users or groups to a local
/// group.
/// </summary>
[Cmdlet(VerbsCommon.Add, "LocalGroupMember",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717987")]
[Alias("algm")]
public class AddLocalGroupMemberCommand : PSCmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Group".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "Group")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalGroup Group
{
get { return this.group;}
set { this.group = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup group;
/// <summary>
/// The following is the definition of the input parameter "Member".
/// Specifies one or more users or groups to add to this local group. You can
/// identify users or groups by specifying their names or SIDs, or by passing
/// Microsoft.PowerShell.Commands.LocalPrincipal objects.
/// </summary>
[Parameter(Mandatory = true,
Position = 1,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalPrincipal[] Member
{
get { return this.member;}
set { this.member = value; }
}
private Microsoft.PowerShell.Commands.LocalPrincipal[] member;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (Group != null)
ProcessGroup(Group);
else if (Name != null)
ProcessName(Name);
else if (SID != null)
ProcessSid(SID);
}
catch (GroupNotFoundException ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Creates a list of <see cref="LocalPrincipal"/> objects
/// ready to be processed by the cmdlet.
/// </summary>
/// <param name="groupId">
/// Name or SID (as a string) of the group we'll be adding to.
/// This string is used primarily for specifying the target
/// in WhatIf scenarios.
/// </param>
/// <param name="member">
/// LocalPrincipal object to be processed
/// </param>
/// <returns>
/// A LocalPrincipal Object to be added to the group
/// </returns>
/// <remarks>
/// <para>
/// LocalPrincipal objects in the Member parameter may not be complete,
/// particularly those created from a name or a SID string given to the
/// Member cmdlet parameter. The object returned from this method contains
/// , at the very least, a valid SID.
/// </para>
/// <para>
/// Any Member objects provided by name or SID string will be looked up
/// to ensure that such an object exists. If an object is not found,
/// an error message is displayed by PowerShell and null will be returned
/// </para>
/// <para>
/// This method also handles the WhatIf scenario. If the Cmdlet's
/// <b>ShouldProcess</b> method returns false on any Member object,
/// that object will not be included in the returned List.
/// </para>
/// </remarks>
private LocalPrincipal MakePrincipal(string groupId, LocalPrincipal member)
{
LocalPrincipal principal = null;
// if the member has a SID, we can use it directly
if (member.SID != null)
{
principal = member;
}
else // otherwise it must have been constructed by name
{
SecurityIdentifier sid = this.TrySid(member.Name);
if (sid != null)
{
member.SID = sid;
principal = member;
}
else
{
try
{
principal = sam.LookupAccount(member.Name);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
if (CheckShouldProcess(principal, groupId))
return principal;
return null;
}
/// <summary>
/// Determine if a principal should be processed.
/// Just a wrapper around Cmdlet.ShouldProcess, with localized string
/// formatting.
/// </summary>
/// <param name="principal">Name of the principal to be added.</param>
/// <param name="groupName">
/// Name of the group to which the members will be added.
/// </param>
/// <returns>
/// True if the principal should be processed, false otherwise.
/// </returns>
private bool CheckShouldProcess(LocalPrincipal principal, string groupName)
{
if (principal == null)
return false;
string msg = StringUtil.Format(Strings.ActionAddGroupMember, principal.ToString());
return ShouldProcess(groupName, msg);
}
/// <summary>
/// Add members to a group.
/// </summary>
/// <param name="group">
/// A <see cref="LocalGroup"/> object representing the group to which
/// the members will be added.
/// </param>
private void ProcessGroup(LocalGroup group)
{
string groupId = group.Name ?? group.SID.ToString();
foreach (var member in this.Member)
{
LocalPrincipal principal = MakePrincipal(groupId, member);
if (null != principal)
{
var ex = sam.AddLocalGroupMember(group, principal);
if (null != ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Add members to a group specified by name.
/// </summary>
/// <param name="name">
/// The name of the group to which the members will be added.
/// </param>
private void ProcessName(string name)
{
ProcessGroup(sam.GetLocalGroup(name));
}
/// <summary>
/// Add members to a group specified by SID.
/// </summary>
/// <param name="groupSid">
/// A <see cref="SecurityIdentifier"/> object identifying the group
/// to which the members will be added.
/// </param>
private void ProcessSid(SecurityIdentifier groupSid)
{
foreach (var member in this.Member)
{
LocalPrincipal principal = MakePrincipal(groupSid.ToString(), member);
if (null != principal)
{
var ex = sam.AddLocalGroupMember(groupSid, principal);
if (null != ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,215 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Disable-LocalUser cmdlet disables local user accounts. When a user
/// account is disabled, the user is not permitted to log on. When a user
/// account is enabled, the user is permitted to log on normally.
/// </summary>
[Cmdlet(VerbsLifecycle.Disable, "LocalUser",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717986")]
[Alias("dlu")]
public class DisableLocalUserCommand : Cmdlet
{
#region Constants
private const Enabling enabling = Enabling.Disable;
#endregion Constants
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local user accounts to disable in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalUser[] InputObject
{
get { return this.inputobject; }
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalUser[] inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the names of the local user accounts to disable in the local
/// Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies the LocalUser accounts to disable by
/// System.Security.Principal.SecurityIdentifier.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessUsers();
ProcessNames();
ProcessSids();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process users requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var name in Name)
{
try
{
if (CheckShouldProcess(name))
sam.EnableLocalUser(sam.GetLocalUser(name), enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var sid in SID)
{
try
{
if (CheckShouldProcess(sid.ToString()))
sam.EnableLocalUser(sid, enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -InputObject
/// </summary>
private void ProcessUsers()
{
if (InputObject != null)
{
foreach (var user in InputObject)
{
try
{
if (CheckShouldProcess(user.Name))
sam.EnableLocalUser(user, enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionDisableUser);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,217 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Enable-LocalUser cmdlet enables local user accounts. When a user account
/// is disabled, the user is not permitted to log on. When a user account is
/// enabled, the user is permitted to log on normally.
/// </summary>
[Cmdlet(VerbsLifecycle.Enable, "LocalUser",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717985")]
[Alias("elu")]
public class EnableLocalUserCommand : Cmdlet
{
#region Constants
private const Enabling enabling = Enabling.Enable;
#endregion Constants
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local user accounts to enable in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalUser[] InputObject
{
get { return this.inputobject; }
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalUser[] inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local user accounts to enable in the local Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies the LocalUser accounts to enable by
/// System.Security.Principal.SecurityIdentifier.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessUsers();
ProcessNames();
ProcessSids();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process users requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var name in Name)
{
try
{
if (CheckShouldProcess(name))
sam.EnableLocalUser(sam.GetLocalUser(name), enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var sid in SID)
{
try
{
if (CheckShouldProcess(sid.ToString()))
sam.EnableLocalUser(sid, enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -InputObject
/// </summary>
private void ProcessUsers()
{
if (InputObject != null)
{
foreach (var user in InputObject)
{
try
{
if (CheckShouldProcess(user.Name))
sam.EnableLocalUser(user, enabling);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionEnableUser);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,170 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Security.Principal;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Get-LocalGroup cmdlet gets local groups from the Windows Security
/// Accounts manager.
/// </summary>
[Cmdlet(VerbsCommon.Get, "LocalGroup",
DefaultParameterSetName = "Default",
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717974")]
[Alias("glg")]
public class GetLocalGroupCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local groups to get from the local Security Accounts Manager.
/// </summary>
[Parameter(Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNull]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a local group from the local Security Accounts Manager.
/// </summary>
[Parameter(Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
if (Name == null && SID == null)
{
foreach (var group in sam.GetAllLocalGroups())
WriteObject(group);
return;
}
ProcessNames();
ProcessSids();
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process groups requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// Groups may be specified using wildcards.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var name in Name)
{
try
{
if (WildcardPattern.ContainsWildcardCharacters(name))
{
var pattern = new WildcardPattern(name, WildcardOptions.Compiled
| WildcardOptions.IgnoreCase);
foreach (var group in sam.GetMatchingLocalGroups(n => pattern.IsMatch(n)))
WriteObject(group);
}
else
{
WriteObject(sam.GetLocalGroup(name));
}
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process groups requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var sid in SID)
{
try
{
WriteObject(sam.GetLocalGroup(sid));
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,229 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security.Principal;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Get-LocalGroupMember cmdlet gets the members of a local group.
/// </summary>
[Cmdlet(VerbsCommon.Get, "LocalGroupMember",
DefaultParameterSetName = "Default",
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717988")]
[Alias("glgm")]
public class GetLocalGroupMemberCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Group".
/// The security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Group")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalGroup Group
{
get { return this.group;}
set { this.group = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup group;
/// <summary>
/// The following is the definition of the input parameter "Member".
/// Specifies the name of the user or group that is a member of this group. If
/// this parameter is not specified, all members of the specified group are
/// returned. This accepts a name, SID, or wildcard string.
/// </summary>
[Parameter(Position = 1)]
[ValidateNotNullOrEmpty]
public string Member
{
get { return this.member;}
set { this.member = value; }
}
private string member;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// The security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// The security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
IEnumerable<LocalPrincipal> principals = null;
if (Group != null)
principals = ProcessGroup(Group);
else if (Name != null)
principals = ProcessName(Name);
else if (SID != null)
principals = ProcessSid(SID);
if (principals != null)
WriteObject(principals, true);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
private IEnumerable<LocalPrincipal> ProcessesMembership(IEnumerable<LocalPrincipal> membership)
{
List<LocalPrincipal> rv;
// if no members are specified, return all of them
if (Member == null)
{
//return membership;
rv = new List<LocalPrincipal>(membership);
}
else
{
//var rv = new List<LocalPrincipal>();
rv = new List<LocalPrincipal>();
if (WildcardPattern.ContainsWildcardCharacters(Member))
{
var pattern = new WildcardPattern(Member, WildcardOptions.Compiled
| WildcardOptions.IgnoreCase);
foreach (var m in membership)
if (pattern.IsMatch(sam.StripMachineName(m.Name)))
rv.Add(m);
}
else
{
var sid = this.TrySid(Member);
if (sid != null)
{
foreach (var m in membership)
{
if (m.SID == sid)
{
rv.Add(m);
break;
}
}
}
else
{
foreach (var m in membership)
{
if (sam.StripMachineName(m.Name).Equals(Member, StringComparison.CurrentCultureIgnoreCase))
{
rv.Add(m);
break;
}
}
}
if (rv.Count == 0)
{
var ex = new PrincipalNotFoundException(member, member);
WriteError(ex.MakeErrorRecord());
}
}
}
// sort the resulting principals by mane
rv.Sort((p1, p2) => string.Compare(p1.Name, p2.Name, StringComparison.CurrentCultureIgnoreCase));
return rv;
}
private IEnumerable<LocalPrincipal> ProcessGroup(LocalGroup group)
{
return ProcessesMembership(sam.GetLocalGroupMembers(group));
}
private IEnumerable<LocalPrincipal> ProcessName(string name)
{
return ProcessGroup(sam.GetLocalGroup(name));
}
private IEnumerable<LocalPrincipal> ProcessSid(SecurityIdentifier groupSid)
{
return ProcessesMembership(sam.GetLocalGroupMembers(groupSid));
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,172 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Get-LocalUser cmdlet gets local user accounts from the Windows Security
/// Accounts Manager. This includes local accounts that have been connected to a
/// Microsoft account.
/// </summary>
[Cmdlet(VerbsCommon.Get, "LocalUser",
DefaultParameterSetName = "Default",
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717980")]
[Alias("glu")]
public class GetLocalUserCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local user accounts to get from the local Security Accounts
/// Manager. This accepts a name or wildcard string.
/// </summary>
[Parameter(Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNull]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a user from the local Security Accounts Manager.
/// </summary>
[Parameter(Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid; }
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
if (Name == null && SID == null)
{
foreach (var user in sam.GetAllLocalUsers())
WriteObject(user);
return;
}
ProcessNames();
ProcessSids();
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process users requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// Users may be specified using wildcards.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var nm in Name)
{
try
{
if (WildcardPattern.ContainsWildcardCharacters(nm))
{
var pattern = new WildcardPattern(nm, WildcardOptions.Compiled
| WildcardOptions.IgnoreCase);
foreach (var user in sam.GetMatchingLocalUsers(n => pattern.IsMatch(n)))
WriteObject(user);
}
else
{
WriteObject(sam.GetLocalUser(nm));
}
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var s in SID)
{
try
{
WriteObject(sam.GetLocalUser(s));
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,120 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The New-LocalGroup Cmdlet can be used to create a new local security group
/// in the Windows Security Accounts Manager.
/// </summary>
[Cmdlet(VerbsCommon.New, "LocalGroup",
SupportsShouldProcess = true,
HelpUri ="http://go.microsoft.com/fwlink/?LinkId=717990")]
[Alias("nlg")]
public class NewLocalGroupCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Description".
/// A descriptive comment (48 characters).
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNull]
[ValidateLength(0, 48)]
public string Description
{
get { return this.description;}
set { this.description = value; }
}
private string description;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// The group name for the local security group.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[ValidateLength(1, 256)]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (CheckShouldProcess(Name))
{
var group = sam.CreateLocalGroup(new LocalGroup
{
Description = Description,
Name = Name
});
WriteObject(group);
}
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionNewGroup);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,277 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The New-LocalUser cmdlet creates a new local user account.
/// </summary>
[Cmdlet(VerbsCommon.New, "LocalUser",
DefaultParameterSetName = "Password",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717981")]
[Alias("nlu")]
public class NewLocalUserCommand : PSCmdlet
{
#region Static Data
// Names of object- and boolean-type parameters.
// Switch parameters don't need to be included.
private static string[] parameterNames = new string[]
{
"AccountExpires",
"Description",
"Disabled",
"FullName",
"Password",
"UserMayNotChangePassword"
};
#endregion Static Data
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "AccountExpires".
/// Specifies when the user account will expire.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public System.DateTime AccountExpires
{
get { return this.accountexpires;}
set { this.accountexpires = value; }
}
private System.DateTime accountexpires;
// This parameter added by hand (copied from SetLocalUserCommand), not by Cmdlet Designer
/// <summary>
/// The following is the definition of the input parameter "AccountNeverExpires".
/// Specifies that the account will not expire.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public System.Management.Automation.SwitchParameter AccountNeverExpires
{
get { return this.accountneverexpires;}
set { this.accountneverexpires = value; }
}
private System.Management.Automation.SwitchParameter accountneverexpires;
/// <summary>
/// The following is the definition of the input parameter "Description".
/// A descriptive comment for this user account (48 characters).
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNull]
[ValidateLength(0, 48)]
public string Description
{
get { return this.description;}
set { this.description = value; }
}
private string description;
/// <summary>
/// The following is the definition of the input parameter "Disabled".
/// Specifies whether this user account is enabled or disabled.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public System.Management.Automation.SwitchParameter Disabled
{
get { return this.disabled;}
set { this.disabled = value; }
}
private System.Management.Automation.SwitchParameter disabled;
/// <summary>
/// The following is the definition of the input parameter "FullName".
/// Specifies the full name of the user account. This is different from the
/// username of the user account.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNull]
public string FullName
{
get { return this.fullname;}
set { this.fullname = value; }
}
private string fullname;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the user name for the local user account. This can be a local user
/// account or a local user account that is connected to a Microsoft Account.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[ValidateLength(1, 20)]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "Password".
/// Specifies the password for the local user account. A password can contain up
/// to 127 characters.
/// </summary>
[Parameter(Mandatory = true,
ParameterSetName = "Password",
ValueFromPipelineByPropertyName = true)]
[ValidateNotNull]
public System.Security.SecureString Password
{
get { return this.password;}
set { this.password = value; }
}
private System.Security.SecureString password;
/// <summary>
/// The following is the definition of the input parameter "PasswordChangeableDate".
/// Specifies that the new User account has no password.
/// </summary>
[Parameter(Mandatory = true,
ParameterSetName = "NoPassword",
ValueFromPipelineByPropertyName = true)]
public System.Management.Automation.SwitchParameter NoPassword
{
get { return this.nopassword; }
set { this.nopassword = value; }
}
private System.Management.Automation.SwitchParameter nopassword;
/// <summary>
/// The following is the definition of the input parameter "PasswordNeverExpires".
/// Specifies that the password will not expire.
/// </summary>
[Parameter(ParameterSetName = "Password",
ValueFromPipelineByPropertyName = true)]
public System.Management.Automation.SwitchParameter PasswordNeverExpires
{
get { return this.passwordneverexpires; }
set { this.passwordneverexpires = value; }
}
private System.Management.Automation.SwitchParameter passwordneverexpires;
/// <summary>
/// The following is the definition of the input parameter "UserMayNotChangePassword".
/// Specifies whether the user is allowed to change the password on this
/// account. The default value is True.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
public System.Management.Automation.SwitchParameter UserMayNotChangePassword
{
get { return this.usermaynotchangepassword;}
set { this.usermaynotchangepassword = value; }
}
private System.Management.Automation.SwitchParameter usermaynotchangepassword;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
if (this.HasParameter("AccountExpires") && AccountNeverExpires.IsPresent)
{
InvalidParametersException ex = new InvalidParametersException("AccountExpires", "AccountNeverExpires");
ThrowTerminatingError(ex.MakeErrorRecord());
}
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (CheckShouldProcess(Name))
{
var user = new LocalUser
{
Name = Name,
Description = Description,
Enabled = true,
FullName = FullName,
UserMayChangePassword = true
};
foreach (var paramName in parameterNames)
{
if (this.HasParameter(paramName))
{
switch (paramName)
{
case "AccountExpires":
user.AccountExpires = AccountExpires;
break;
case "Disabled":
user.Enabled = !Disabled;
break;
case "UserMayNotChangePassword":
user.UserMayChangePassword = !UserMayNotChangePassword;
break;
}
}
}
if (AccountNeverExpires.IsPresent)
user.AccountExpires = null;
// Password will be null if NoPassword was given
user = sam.CreateLocalUser(user, Password, PasswordNeverExpires.IsPresent);
WriteObject(user);
}
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionNewUser);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,208 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Remove-LocalGroup cmdlet deletes a security group from the Windows
/// Security Accounts manager.
/// </summary>
[Cmdlet(VerbsCommon.Remove, "LocalGroup",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717975")]
[Alias("rlg")]
public class RemoveLocalGroupCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies security groups from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalGroup[] InputObject
{
get { return this.inputobject; }
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup[] inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local groups to be deleted from the local Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies the LocalGroup accounts to remove by
/// System.Security.Principal.SecurityIdentifier.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid; }
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessGroups();
ProcessNames();
ProcessSids();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process groups requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var name in Name)
{
try
{
if (CheckShouldProcess(name))
sam.RemoveLocalGroup(sam.GetLocalGroup(name));
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process groups requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var sid in SID)
{
try
{
if (CheckShouldProcess(sid.ToString()))
sam.RemoveLocalGroup(sid);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process groups given through -InputObject
/// </summary>
private void ProcessGroups()
{
if (InputObject != null)
{
foreach (var group in InputObject)
{
try
{
if (CheckShouldProcess(group.Name))
sam.RemoveLocalGroup(group);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionRemoveGroup);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,295 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Security.Principal;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Remove-LocalGroupMember cmdlet removes one or more members (users or
/// groups) from a local security group.
/// </summary>
[Cmdlet(VerbsCommon.Remove, "LocalGroupMember",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717989")]
[Alias("rlgm")]
public class RemoveLocalGroupMemberCommand : PSCmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Group".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "Group")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalGroup Group
{
get { return this.group;}
set { this.group = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup group;
/// <summary>
/// The following is the definition of the input parameter "Member".
/// Specifies one or more users or groups to remove from this local group. You can
/// identify users or groups by specifying their names or SIDs, or by passing
/// Microsoft.PowerShell.Commands.LocalPrincipal objects.
/// </summary>
[Parameter(Mandatory = true,
Position = 1,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalPrincipal[] Member
{
get { return this.member;}
set { this.member = value; }
}
private Microsoft.PowerShell.Commands.LocalPrincipal[] member;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// The security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
if (Group != null)
ProcessGroup(Group);
else if (Name != null)
ProcessName(Name);
else if (SID != null)
ProcessSid(SID);
}
catch (GroupNotFoundException ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Creates a list of <see cref="LocalPrincipal"/> objects
/// ready to be processed by the cmdlet.
/// </summary>
/// <param name="groupId">
/// Name or SID (as a string) of the group we'll be removing from.
/// This string is used primarily for specifying the target
/// in WhatIf scenarios.
/// </param>
/// <param name="member">
/// LocalPrincipal object to be processed
/// </param>
/// <returns>
/// LocalPrincipal object processed and ready to be removed
/// </returns>
/// <remarks>
/// <para>
/// LocalPrincipal object in the Member parameter may not be complete,
/// particularly those created from a name or a SID string given to the
/// Member cmdlet parameter. The object returned from this method contains at the very least, contain a valid SID.
/// </para>
/// <para>
/// Any Member object provided by name or SID string will be looked up
/// to ensure that such an object exists. If an object is not found,
/// an error message is displayed by PowerShell and null will be returned from this method
/// </para>
/// <para>
/// This method also handles the WhatIf scenario. If the Cmdlet's
/// <b>ShouldProcess</b> method returns false on any Member object
/// </para>
/// </remarks>
private LocalPrincipal MakePrincipal(string groupId, LocalPrincipal member)
{
LocalPrincipal principal = null;
// if the member has a SID, we can use it directly
if (member.SID != null)
{
principal = member;
}
else // otherwise it must have been constructed by name
{
SecurityIdentifier sid = this.TrySid(member.Name);
if (sid != null)
{
member.SID = sid;
principal = member;
}
else
{
try
{
principal = sam.LookupAccount(member.Name);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
if (CheckShouldProcess(principal, groupId))
return principal;
return null;
}
/// <summary>
/// Determine if a principal should be processed.
/// Just a wrapper around Cmdlet.ShouldProcess, with localized string
/// formatting.
/// </summary>
/// <param name="principal">Name of the principal to be removed.</param>
/// <param name="groupName">
/// Name of the group from which the members will be removed.
/// </param>
/// <returns>
/// True if the principal should be processed, false otherwise.
/// </returns>
private bool CheckShouldProcess(LocalPrincipal principal, string groupName)
{
if (principal == null)
return false;
string msg = StringUtil.Format(Strings.ActionRemoveGroupMember, principal.ToString());
return ShouldProcess(groupName, msg);
}
/// <summary>
/// Remove members from a group.
/// </summary>
/// <param name="group">
/// A <see cref="LocalGroup"/> object representing the group from which
/// the members will be removed.
/// </param>
private void ProcessGroup(LocalGroup group)
{
string groupId = group.Name ?? group.SID.ToString();
foreach (var member in this.Member)
{
LocalPrincipal principal = MakePrincipal(groupId, member);
if (null != principal)
{
var ex = sam.RemoveLocalGroupMember(group, principal);
if (null != ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Remove members from a group specified by name.
/// </summary>
/// <param name="name">
/// The name of the group from which the members will be removed.
/// </param>
private void ProcessName(string name)
{
ProcessGroup(sam.GetLocalGroup(name));
}
/// <summary>
/// Remove members from a group specified by SID.
/// </summary>
/// <param name="groupSid">
/// A <see cref="SecurityIdentifier"/> object identifying the group
/// from which the members will be removed.
/// </param>
private void ProcessSid(SecurityIdentifier groupSid)
{
foreach (var member in this.Member)
{
LocalPrincipal principal = MakePrincipal(groupSid.ToString(), member);
if (null != principal)
{
var ex = sam.RemoveLocalGroupMember(groupSid, principal);
if (null != ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,210 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
using System.Diagnostics.CodeAnalysis;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Remove-LocalUser cmdlet deletes a user account from the Windows Security
/// Accounts manager.
/// </summary>
[Cmdlet(VerbsCommon.Remove, "LocalUser",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717982")]
[Alias("rlu")]
public class RemoveLocalUserCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local user accounts to remove in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Microsoft.PowerShell.Commands.LocalUser[] InputObject
{
get { return this.inputobject;}
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalUser[] inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the user accounts to be deleted from the local Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] Name
{
get { return this.name; }
set { this.name = value; }
}
private string[] name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies the local user accounts to remove by
/// System.Security.Principal.SecurityIdentifier.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public System.Security.Principal.SecurityIdentifier[] SID
{
get { return this.sid; }
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier[] sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessUsers();
ProcessNames();
ProcessSids();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process users requested by -Name
/// </summary>
/// <remarks>
/// All arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessNames()
{
if (Name != null)
{
foreach (var name in Name)
{
try
{
if (CheckShouldProcess(name))
sam.RemoveLocalUser(sam.GetLocalUser(name));
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users requested by -SID
/// </summary>
private void ProcessSids()
{
if (SID != null)
{
foreach (var sid in SID)
{
try
{
if (CheckShouldProcess(sid.ToString()))
sam.RemoveLocalUser(sid);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
/// <summary>
/// Process users given through -InputObject
/// </summary>
private void ProcessUsers()
{
if (InputObject != null)
{
foreach (var user in InputObject)
{
try
{
if (CheckShouldProcess(user.Name))
sam.RemoveLocalUser(user);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
}
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionRemoveUser);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,226 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Rename-LocalGroup cmdlet renames a local security group in the Security
/// Accounts Manager.
/// </summary>
[Cmdlet(VerbsCommon.Rename, "LocalGroup",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717978")]
[Alias("rnlg")]
public class RenameLocalGroupCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local group account to rename in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNullOrEmpty]
public Microsoft.PowerShell.Commands.LocalGroup InputObject
{
get { return this.inputobject;}
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local group to be renamed in the local Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "NewName".
/// Specifies the new name for the local security group in the Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public string NewName
{
get { return this.newname;}
set { this.newname = value; }
}
private string newname;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNullOrEmpty]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessGroup();
ProcessName();
ProcessSid();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process group requested by -Name
/// </summary>
/// <remarks>
/// Arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessName()
{
if (Name != null)
{
try
{
if (CheckShouldProcess(Name, NewName))
sam.RenameLocalGroup(sam.GetLocalGroup(Name), NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Process group requested by -SID
/// </summary>
private void ProcessSid()
{
if (SID != null)
{
try
{
if (CheckShouldProcess(SID.ToString(), NewName))
sam.RenameLocalGroup(SID, NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Process group given through -InputObject
/// </summary>
private void ProcessGroup()
{
if (InputObject != null)
{
try
{
if (CheckShouldProcess(InputObject.Name, NewName))
sam.RenameLocalGroup(InputObject, NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Determine if a group should be processed.
/// Just a wrapper around Cmdlet.ShouldProcess, with localized string
/// formatting.
/// </summary>
/// <param name="groupName">
/// Name of the group to rename.
/// </param>
/// <param name="newName">
/// New name for the group.
/// </param>
/// <returns>
/// True if the group should be processed, false otherwise.
/// </returns>
private bool CheckShouldProcess(string groupName, string newName)
{
string msg = StringUtil.Format(Strings.ActionRenameGroup, newName);
return ShouldProcess(groupName, msg);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,227 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Rename-LocalUser cmdlet renames a local user account in the Security
/// Accounts Manager.
/// </summary>
[Cmdlet(VerbsCommon.Rename, "LocalUser",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=717983")]
[Alias("rnlu")]
public class RenameLocalUserCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local user account to rename in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalUser InputObject
{
get { return this.inputobject;}
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalUser inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local user account to be renamed in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "NewName".
/// Specifies the new name for the local user account in the Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 1)]
[ValidateNotNullOrEmpty]
public string NewName
{
get { return this.newname;}
set { this.newname = value; }
}
private string newname;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies the local user to rename.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
ProcessUser();
ProcessName();
ProcessSid();
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
/// <summary>
/// Process user requested by -Name
/// </summary>
/// <remarks>
/// Arguments to -Name will be treated as names,
/// even if a name looks like a SID.
/// </remarks>
private void ProcessName()
{
if (Name != null)
{
try
{
if (CheckShouldProcess(Name, NewName))
sam.RenameLocalUser(sam.GetLocalUser(Name), NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Process user requested by -SID
/// </summary>
private void ProcessSid()
{
if (SID != null)
{
try
{
if (CheckShouldProcess(SID.ToString(), NewName))
sam.RenameLocalUser(SID, NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Process group given through -InputObject
/// </summary>
private void ProcessUser()
{
if (InputObject != null)
{
try
{
if (CheckShouldProcess(InputObject.Name, NewName))
sam.RenameLocalUser(InputObject, NewName);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
}
/// <summary>
/// Determine if a user should be processed.
/// Just a wrapper around Cmdlet.ShouldProcess, with localized string
/// formatting.
/// </summary>
/// <param name="userName">
/// Name of the user to rename.
/// </param>
/// <param name="newName">
/// New name for the user.
/// </param>
/// <returns>
/// True if the user should be processed, false otherwise.
/// </returns>
private bool CheckShouldProcess(string userName, string newName)
{
string msg = StringUtil.Format(Strings.ActionRenameUser, newName);
return ShouldProcess(userName, msg);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,175 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Set-LocalGroup cmdlet modifies the properties of a local security group
/// in the Windows Security Accounts Manager.
/// </summary>
[Cmdlet(VerbsCommon.Set, "LocalGroup",
SupportsShouldProcess = true,
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717979")]
[Alias("slg")]
public class SetLocalGroupCommand : Cmdlet
{
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "Description".
/// A descriptive comment (48 characters).
/// </summary>
[Parameter(Mandatory = true)]
[ValidateNotNull]
[ValidateLength(0, 48)]
public string Description
{
get { return this.description;}
set { this.description = value; }
}
private string description;
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the local group account to modify in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalGroup InputObject
{
get { return this.inputobject;}
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalGroup inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local group to be renamed in the local Security Accounts
/// Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Default")]
[ValidateNotNull]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a security group from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
LocalGroup group = null;
if (InputObject != null)
{
if (CheckShouldProcess(InputObject.ToString()))
group = InputObject;
}
else if (Name != null)
{
group = sam.GetLocalGroup(Name);
if (!CheckShouldProcess(Name))
group = null;
}
else if (SID != null)
{
group = sam.GetLocalGroup(SID);
if (!CheckShouldProcess(SID.ToString()))
group = null;
}
if (group != null)
{
var delta = group.Clone();
delta.Description = Description;
sam.UpdateLocalGroup(group, delta);
}
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionSetGroup);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,314 @@
#region Using directives
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Management.Automation.SecurityAccountsManager.Extensions;
using Microsoft.PowerShell.LocalAccounts;
#endregion
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// The Set-LocalUser cmdlet changes the properties of a user account in the
/// local Windows Security Accounts Manager. It can also reset the password of a
/// local user account.
/// </summary>
[Cmdlet(VerbsCommon.Set, "LocalUser",
SupportsShouldProcess = true,
DefaultParameterSetName = "Name",
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=717984")]
[Alias("slu")]
public class SetLocalUserCommand : PSCmdlet
{
#region Static Data
// Names of object- and boolean-type parameters.
// Switch parameters don't need to be included.
private static string[] parameterNames = new string[]
{
"AccountExpires",
"Description",
"FullName",
"Password",
"UserMayChangePassword",
"PasswordNeverExpires"
};
#endregion Static Data
#region Instance Data
private Sam sam = null;
#endregion Instance Data
#region Parameter Properties
/// <summary>
/// The following is the definition of the input parameter "AccountExpires".
/// Specifies when the user account will expire. Set to null to indicate that
/// the account will never expire. The default value is null (account never
/// expires).
/// </summary>
[Parameter]
public System.DateTime AccountExpires
{
get { return this.accountexpires;}
set { this.accountexpires = value; }
}
private System.DateTime accountexpires;
/// <summary>
/// The following is the definition of the input parameter "AccountNeverExpires".
/// Specifies that the account will not expire.
/// </summary>
[Parameter]
public System.Management.Automation.SwitchParameter AccountNeverExpires
{
get { return this.accountneverexpires;}
set { this.accountneverexpires = value; }
}
private System.Management.Automation.SwitchParameter accountneverexpires;
/// <summary>
/// The following is the definition of the input parameter "Description".
/// A descriptive comment for this user account (48 characters).
/// </summary>
[Parameter]
[ValidateNotNull]
[ValidateLength(0, 48)]
public string Description
{
get { return this.description;}
set { this.description = value; }
}
private string description;
/// <summary>
/// The following is the definition of the input parameter "FullName".
/// Specifies the full name of the user account. This is different from the
/// username of the user account.
/// </summary>
[Parameter]
[ValidateNotNull]
public string FullName
{
get { return this.fullname;}
set { this.fullname = value; }
}
private string fullname;
/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies the of the local user account to modify in the local Security
/// Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "InputObject")]
[ValidateNotNull]
public Microsoft.PowerShell.Commands.LocalUser InputObject
{
get { return this.inputobject;}
set { this.inputobject = value; }
}
private Microsoft.PowerShell.Commands.LocalUser inputobject;
/// <summary>
/// The following is the definition of the input parameter "Name".
/// Specifies the local user account to change.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "Name")]
[ValidateNotNullOrEmpty]
public string Name
{
get { return this.name;}
set { this.name = value; }
}
private string name;
/// <summary>
/// The following is the definition of the input parameter "Password".
/// Specifies the password for the local user account.
/// </summary>
[Parameter]
[ValidateNotNull]
public System.Security.SecureString Password
{
get { return this.password;}
set { this.password = value; }
}
private System.Security.SecureString password;
/// <summary>
/// The following is the definition of the input parameter "PasswordNeverExpires".
/// Specifies that the password will not expire.
/// </summary>
[Parameter]
public System.Boolean PasswordNeverExpires
{
get { return this.passwordneverexpires; }
set { this.passwordneverexpires = value; }
}
private System.Boolean passwordneverexpires;
/// <summary>
/// The following is the definition of the input parameter "SID".
/// Specifies a user from the local Security Accounts Manager.
/// </summary>
[Parameter(Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
ParameterSetName = "SecurityIdentifier")]
[ValidateNotNull]
public System.Security.Principal.SecurityIdentifier SID
{
get { return this.sid;}
set { this.sid = value; }
}
private System.Security.Principal.SecurityIdentifier sid;
/// <summary>
/// The following is the definition of the input parameter "UserMayChangePassword".
/// Specifies whether the user is allowed to change the password on this
/// account. The default value is True.
/// </summary>
[Parameter]
public System.Boolean UserMayChangePassword
{
get { return this.usermaychangepassword;}
set { this.usermaychangepassword = value; }
}
private System.Boolean usermaychangepassword;
#endregion Parameter Properties
#region Cmdlet Overrides
/// <summary>
/// BeginProcessing method.
/// </summary>
protected override void BeginProcessing()
{
if (this.HasParameter("AccountExpires") && AccountNeverExpires.IsPresent)
{
InvalidParametersException ex = new InvalidParametersException("AccountExpires", "AccountNeverExpires");
ThrowTerminatingError(ex.MakeErrorRecord());
}
sam = new Sam();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
LocalUser user = null;
if (InputObject != null)
{
if (CheckShouldProcess(InputObject.ToString()))
user = InputObject;
}
else if (Name != null)
{
user = sam.GetLocalUser(Name);
if (!CheckShouldProcess(Name))
user = null;
}
else if (SID != null)
{
user = sam.GetLocalUser(SID);
if (!CheckShouldProcess(SID.ToString()))
user = null;
}
if (user == null)
return;
// We start with what already exists
var delta = user.Clone();
bool? passwordNeverExpires = null;
foreach (var paramName in parameterNames)
{
if (this.HasParameter(paramName))
{
switch (paramName)
{
case "AccountExpires":
delta.AccountExpires = this.AccountExpires;
break;
case "Description":
delta.Description = this.Description;
break;
case "FullName":
delta.FullName = this.FullName;
break;
case "UserMayChangePassword":
delta.UserMayChangePassword = this.UserMayChangePassword;
break;
case "PasswordNeverExpires":
passwordNeverExpires = this.PasswordNeverExpires;
break;
}
}
}
if (AccountNeverExpires.IsPresent)
delta.AccountExpires = null;
sam.UpdateLocalUser(user, delta, Password, passwordNeverExpires);
}
catch (Exception ex)
{
WriteError(ex.MakeErrorRecord());
}
}
/// <summary>
/// EndProcessing method.
/// </summary>
protected override void EndProcessing()
{
if (sam != null)
{
sam.Dispose();
sam = null;
}
}
#endregion Cmdlet Overrides
#region Private Methods
private LocalUser GetUser()
{
if (InputObject != null)
return InputObject;
return SID != null ? sam.GetLocalUser(SID)
: sam.GetLocalUser(Name);
}
private bool CheckShouldProcess(string target)
{
return ShouldProcess(target, Strings.ActionSetUser);
}
#endregion Private Methods
}//End Class
}//End namespace

View file

@ -0,0 +1,695 @@
using System;
using System.Management.Automation;
using System.Management.Automation.SecurityAccountsManager;
using System.Runtime.Serialization;
using Microsoft.PowerShell.LocalAccounts;
#if CORECLR
using Microsoft.PowerShell.CoreClr.Stubs;
#endif
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Base class for cmdlet-specific exceptions.
/// </summary>
public class LocalAccountsException : Exception
{
#region Public Properties
/// <summary>
/// Gets the <see cref="System.Management.Automation.ErrorCategory"/>
/// value for this exception.
/// </summary>
public ErrorCategory ErrorCategory
{
get;
private set;
}
/// <summary>
/// Gets the target object for this exception. This is used as
/// the TargetObject member of a PowerShell
/// <see cref="System.Management.Automation.ErrorRecord"/> object.
/// </summary>
public object Target
{
get;
private set;
}
/// <summary>
/// Gets the error name. This is used as the ErrorId parameter when
/// constructing a PowerShell <see cref="System.Management.Automation.ErrorRecord"/>
/// oject.
/// </summary>
public string ErrorName
{
get
{
string exname = "Exception";
var exlen = exname.Length;
var name = this.GetType().Name;
if (name.EndsWith(exname, StringComparison.OrdinalIgnoreCase) && name.Length > exlen)
name = name.Substring(0, name.Length - exlen);
return name;
}
}
#endregion Public Properties
internal LocalAccountsException(string message, object target, ErrorCategory errorCategory)
: base(message)
{
ErrorCategory = errorCategory;
Target = target;
}
/// <summary>
/// Compliance Constructor
/// </summary>
public LocalAccountsException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public LocalAccountsException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public LocalAccountsException(String message, Exception ex) : base(message, ex) { }
#if CORECLR
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
// This is not supported for CoreCLR
protected LocalAccountsException(SerializationInfo info, StreamingContext ctx) : base() { }
#else
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected LocalAccountsException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
#endif
}
/// <summary>
/// Exception indicating an error occurred during one of the internal
/// operations such as opening or closing a handle.
/// </summary>
public class InternalException : LocalAccountsException
{
#region Public Properties
/// <summary>
/// Gets the NTSTATUS code for this exception.
/// </summary>
public UInt32 StatusCode
{
get;
private set;
}
#endregion Public Properties
internal InternalException(UInt32 ntStatus,
string message,
object target,
ErrorCategory errorCategory = ErrorCategory.NotSpecified)
: base(message, target, errorCategory)
{
StatusCode = ntStatus;
}
internal InternalException(UInt32 ntStatus,
object target,
ErrorCategory errorCategory = ErrorCategory.NotSpecified)
: this(ntStatus,
StringUtil.Format(Strings.UnspecifiedErrorNtStatus, ntStatus),
target,
errorCategory)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public InternalException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public InternalException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public InternalException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected InternalException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating an error occurred when a native function
/// is called that returns a Win32 error code as opposed to an
/// NT Status code.
/// </summary>
public class Win32InternalException : LocalAccountsException
{
#region Public Properties
/// <summary>
/// The Win32 error code for this exception.
/// </summary>
public int NativeErrorCode
{
get;
private set;
}
#endregion Public Properties
internal Win32InternalException(int errorCode,
string message,
object target,
ErrorCategory errorCategory = ErrorCategory.NotSpecified)
: base(message, target, errorCategory)
{
NativeErrorCode = errorCode;
}
internal Win32InternalException(int errorCode,
object target,
ErrorCategory errorCategory = ErrorCategory.NotSpecified)
: this(errorCode,
StringUtil.Format(Strings.UnspecifiedErrorWin32Error, errorCode),
target,
errorCategory)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public Win32InternalException() : base() {}
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public Win32InternalException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public Win32InternalException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected Win32InternalException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating an invalid password.
/// </summary>
public class InvalidPasswordException : LocalAccountsException
{
/// <summary>
/// Generates with a default invalid password message.
/// </summary>
public InvalidPasswordException()
: base(Strings.InvalidPassword, null, ErrorCategory.InvalidArgument)
{
}
/// <summary>
/// Generates the exception with the specified message.
/// </summary>
/// <param name="message"></param>
public InvalidPasswordException(string message)
: base(message, null, ErrorCategory.InvalidArgument)
{
}
/// <summary>
/// Creates a message from the specified error code.
/// </summary>
/// <param name="errorCode"></param>
public InvalidPasswordException(uint errorCode)
: base(StringUtil.GetSystemMessage(errorCode), null, ErrorCategory.InvalidArgument)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public InvalidPasswordException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected InvalidPasswordException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception thrown when invalid parameter pairing is detected.
/// </summary>
public class InvalidParametersException : LocalAccountsException
{
internal InvalidParametersException(string message)
: base(message, null, ErrorCategory.InvalidArgument)
{
}
internal InvalidParametersException(string parameterA, string parameterB)
: this(StringUtil.Format(Strings.InvalidParameterPair, parameterA, parameterB))
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public InvalidParametersException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public InvalidParametersException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected InvalidParametersException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating permission denied.
/// </summary>
public class AccessDeniedException : LocalAccountsException
{
internal AccessDeniedException(object target)
: base(Strings.AccessDenied, target, ErrorCategory.PermissionDenied)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public AccessDeniedException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public AccessDeniedException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public AccessDeniedException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected AccessDeniedException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that the name of a user or group is invalid.
/// </summary>
public class InvalidNameException : LocalAccountsException
{
internal InvalidNameException(string name, object target)
: base(StringUtil.Format(Strings.InvalidName, name), target, ErrorCategory.InvalidArgument)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public InvalidNameException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public InvalidNameException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public InvalidNameException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected InvalidNameException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that the specified name is already in use.
/// </summary>
public class NameInUseException : LocalAccountsException
{
internal NameInUseException(string name, object target)
: base(StringUtil.Format(Strings.NameInUse, name), target, ErrorCategory.InvalidArgument)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public NameInUseException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public NameInUseException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public NameInUseException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected NameInUseException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that an entity of some kind was not found.
/// Also serves as a base class for more specific object-not-found errors.
/// </summary>
public class NotFoundException : LocalAccountsException
{
internal NotFoundException(string message, object target)
: base(message, target, ErrorCategory.ObjectNotFound)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public NotFoundException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public NotFoundException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public NotFoundException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected NotFoundException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a principal was not Found
/// </summary>
public class PrincipalNotFoundException : NotFoundException
{
internal PrincipalNotFoundException(string principal, object target)
: base(StringUtil.Format(Strings.PrincipalNotFound, principal), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public PrincipalNotFoundException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public PrincipalNotFoundException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public PrincipalNotFoundException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected PrincipalNotFoundException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a group was not found.
/// </summary>
public class GroupNotFoundException : NotFoundException
{
internal GroupNotFoundException(string group, object target)
: base(StringUtil.Format(Strings.GroupNotFound, group), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public GroupNotFoundException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public GroupNotFoundException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public GroupNotFoundException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected GroupNotFoundException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a user was not found.
/// </summary>
public class UserNotFoundException : NotFoundException
{
internal UserNotFoundException(string user, object target)
: base(StringUtil.Format(Strings.UserNotFound, user), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public UserNotFoundException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public UserNotFoundException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public UserNotFoundException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected UserNotFoundException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a group member was not found.
/// </summary>
public class MemberNotFoundException : NotFoundException
{
internal MemberNotFoundException(string member, string group)
: base(StringUtil.Format(Strings.MemberNotFound, member, group), member)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public MemberNotFoundException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public MemberNotFoundException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public MemberNotFoundException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected MemberNotFoundException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that an entity of some kind already exists.
/// Also serves as a base class for more specific object-exists errors.
/// </summary>
public class ObjectExistsException : LocalAccountsException
{
internal ObjectExistsException(string message, object target)
: base(message, target, ErrorCategory.ResourceExists)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public ObjectExistsException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public ObjectExistsException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public ObjectExistsException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected ObjectExistsException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a group already exists.
/// </summary>
public class GroupExistsException : ObjectExistsException
{
internal GroupExistsException(string group, object target)
: base(StringUtil.Format(Strings.GroupExists, group), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public GroupExistsException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public GroupExistsException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public GroupExistsException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected GroupExistsException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that a group already exists.
/// </summary>
public class UserExistsException : ObjectExistsException
{
internal UserExistsException(string user, object target)
: base(StringUtil.Format(Strings.UserExists, user), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public UserExistsException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public UserExistsException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public UserExistsException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected UserExistsException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
/// <summary>
/// Exception indicating that an object already exists as a group member.
/// </summary>
public class MemberExistsException : ObjectExistsException
{
internal MemberExistsException(string member, string group, object target)
: base(StringUtil.Format(Strings.MemberExists, member, group), target)
{
}
/// <summary>
/// Compliance Constructor
/// </summary>
public MemberExistsException() : base() { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
public MemberExistsException(String message) : base(message) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="message"></param>
/// <param name="ex"></param>
public MemberExistsException(String message, Exception ex) : base(message, ex) { }
/// <summary>
/// Compliance Constructor
/// </summary>
/// <param name="info"></param>
/// <param name="ctx"></param>
protected MemberExistsException(SerializationInfo info, StreamingContext ctx) : base(info, ctx) { }
}
}

View file

@ -0,0 +1,217 @@
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text.RegularExpressions;
using Microsoft.PowerShell.Commands;
using Microsoft.PowerShell.LocalAccounts;
namespace System.Management.Automation.SecurityAccountsManager.Extensions
{
/// <summary>
/// Provides extension methods for the Cmdlet class
/// </summary>
internal static class CmdletExtensions
{
/// <summary>
/// Attempt to create a SID from a string.
/// </summary>
/// <param name="cmdlet">The cmdlet being extended with this method.</param>
/// <param name="s">The string to be converted to a SID.</param>
/// <param name="allowSidConstants">
/// A boolean indicating whether SID constants, such as "BA", are considered.
/// </param>
/// <returns>
/// A <see cref="SecurityIdentifier"/> object if the conversion was successful,
/// null otherwise.
/// </returns>
internal static SecurityIdentifier TrySid(this Cmdlet cmdlet,
string s,
bool allowSidConstants = false)
{
if (!allowSidConstants)
if (!(s.Length > 2 && s.StartsWith("S-") && Char.IsDigit(s[2])))
return null;
SecurityIdentifier sid = null;
try
{
sid = new SecurityIdentifier(s);
}
catch (ArgumentException)
{
// do nothing here, just fall through to the return
}
return sid;
}
}
/// <summary>
/// Provides extension methods for the PSCmdlet class
/// </summary>
internal static class PSExtensions
{
/// <summary>
/// Determine if a given parameter was provided to the cmdlet
/// </summary>
/// <param name="cmdlet">
/// The <see cref="PSCmdlet"/> object to check.
/// </param>
/// <param name="parameterName">
/// A string containing the name of the parameter. This should be in the
/// same letter-casing as the defined parameter.
/// </param>
/// <returns>
/// True if the specified parameter was given on the cmdlet invocation,
/// false otherwise.
/// </returns>
internal static bool HasParameter(this PSCmdlet cmdlet, string parameterName)
{
var invocation = cmdlet.MyInvocation;
if (invocation != null)
{
var parameters = invocation.BoundParameters;
if (parameters != null)
{
// PowerShell sets the parameter names in the BoundParameters dictionary
// to their "proper" casing, so we don't have to do a case-insensitive search.
if (parameters.ContainsKey(parameterName))
return true;
}
}
return false;
}
}
/// <summary>
/// Provides extension methods for the SecurityIdentifier class.
/// </summary>
internal static class SidExtensions
{
/// <summary>
/// Get the Relative ID (RID) from a <see cref="SecurityIdentifier"/> object.
/// </summary>
/// <param name="sid">The SecurityIdentifier containing the desired Relative ID.</param>
/// <returns>
/// A UInt32 value containing the Relative ID in the SecurityIdentifier.
/// </returns>
internal static UInt32 GetRid(this SecurityIdentifier sid)
{
byte[] sidBinary = new byte[sid.BinaryLength];
sid.GetBinaryForm(sidBinary, 0);
return System.BitConverter.ToUInt32(sidBinary, sidBinary.Length-4);
}
/// <summary>
/// Gets the Identifier Authority portion of a <see cref="SecurityIdentifier"/>
/// </summary>
/// <param name="sid">The SecurityIdentifier containing the desired Authority.</param>
/// <returns>
/// A long integer value containing the SecurityIdentifier's Identifier Authority value.
/// </returns>
/// <remarks>
/// This method is used primarily for determining the Source of a Principal.
/// The Win32 API LsaLookupUserAccountType function does not (yet) properly
/// identify MicrosoftAccount principals.
/// </remarks>
internal static long GetIdentifierAuthority(this SecurityIdentifier sid)
{
byte[] sidBinary = new byte[sid.BinaryLength];
sid.GetBinaryForm(sidBinary, 0);
// The Identifier Authority is six bytes wide,
// in big-endian format, starting at the third byte
long authority = (long) (((long)sidBinary[2]) << 40) +
(((long)sidBinary[3]) << 32) +
(((long)sidBinary[4]) << 24) +
(((long)sidBinary[5]) << 16) +
(((long)sidBinary[6]) << 8) +
(((long)sidBinary[7]) );
return authority;
}
internal static bool IsMsaAccount(this SecurityIdentifier sid)
{
return sid.GetIdentifierAuthority() == 11;
}
}
internal static class SecureStringExtensions
{
private static Regex pwRegex = new Regex(@"^[^\x00-\x1F""/\\\[\]:;\|=,+\*?<>@]{0,127}$",
RegexOptions.Compiled | RegexOptions.CultureInvariant);
internal static bool IsValidPassword(this SecureString str)
{
return str.Length == 0 || pwRegex.IsMatch(str.AsString());
}
internal static void ValidatePassword(this SecureString str)
{
if (!str.IsValidPassword())
throw new InvalidPasswordException();
}
/// <summary>
/// Extension method to extract clear text from a
/// <see cref="System.Security.SecureString"/> object.
/// </summary>
/// <param name="str">
/// This SecureString object, containing encrypted text.
/// </param>
/// <returns>
/// A string containing the SecureString object's original text.
/// </returns>
internal static string AsString(this SecureString str)
{
#if CORECLR
IntPtr buffer = SecureStringMarshal.SecureStringToCoTaskMemUnicode(str);
string clear = Marshal.PtrToStringUni(buffer);
SecureStringMarshal.ZeroFreeCoTaskMemUnicode(buffer);
#else
var bstr = Marshal.SecureStringToBSTR(str);
string clear = Marshal.PtrToStringAuto(bstr);
Marshal.ZeroFreeBSTR(bstr);
#endif
return clear;
}
}
internal static class ExceptionExtensions
{
internal static ErrorRecord MakeErrorRecord(this Exception ex,
string errorId,
ErrorCategory errorCategory,
object target = null)
{
return new ErrorRecord(ex, errorId, errorCategory, target);
}
internal static ErrorRecord MakeErrorRecord(this Exception ex, object target = null)
{
// This part is somewhat less than beautiful, but it prevents
// having to have multiple exception handlers in every cmdlet command.
var exTemp = ex as LocalAccountsException;
if (exTemp != null)
return MakeErrorRecord(exTemp, target ?? exTemp.Target);
return new ErrorRecord(ex,
Strings.UnspecifiedError,
ErrorCategory.NotSpecified,
target);
}
internal static ErrorRecord MakeErrorRecord(this LocalAccountsException ex, object target = null)
{
return ex.MakeErrorRecord(ex.ErrorName, ex.ErrorCategory, target ?? ex.Target);
}
}
}

View file

@ -0,0 +1,79 @@
using System;
using Microsoft.PowerShell.LocalAccounts;
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Describes a Local Group.
/// Objects of this type are provided to and returned from group-related Cmdlets.
/// </summary>
public class LocalGroup : LocalPrincipal
{
#region Public Properties
/// <summary>
/// A short description of the Group.
/// </summary>
public String Description { get; set; }
#endregion Public Properties
#region Construction
/// <summary>
/// Initializes a new LocalGroup object.
/// </summary>
public LocalGroup()
{
ObjectClass = Strings.ObjectClassGroup;
}
/// <summary>
/// Initializes a new LocalUser object with the specified name.
/// </summary>
/// <param name="name">Name of the new LocalGroup.</param>
public LocalGroup(string name)
: base(name)
{
ObjectClass = Strings.ObjectClassGroup;
}
/// <summary>
/// Construct a new LocalGroup object that is a copy of another
/// </summary>
/// <param name="other"></param>
private LocalGroup(LocalGroup other)
: this(other.Name)
{
Description = other.Description;
}
#endregion Construction
#region Public Methods
/// <summary>
/// Provides a string representation of the LocalGroup object.
/// </summary>
/// <returns>
/// A string containing the Group Name.
/// </returns>
public override string ToString()
{
return Name ?? SID.ToString();
}
/// <summary>
/// Create a copy of a LocalGroup object.
/// </summary>
/// <returns>
/// A new LocalGroup object with the same property values as this one.
/// </returns>
public LocalGroup Clone()
{
if (null == this)
{
throw new NullReferenceException();
}
return new LocalGroup(this);
}
#endregion Public Methods
}
}

View file

@ -0,0 +1,97 @@
using System.Security.Principal;
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Defines the source of a Principal
/// </summary>
public enum PrincipalSource
{
/// <summary>
/// The principal source is unknown or could not be determined
/// </summary>
Unknown = 0,
/// <summary>
/// The principal is sourced from the local Windows Security Accounts Manager.
/// </summary>
Local,
/// <summary>
/// The principal is sourced from an Active Directory domain.
/// </summary>
ActiveDirectory,
/// <summary>
/// The principal is sourced from Azure Active Directory.
/// </summary>
AzureAD,
/// <summary>
/// The principal is a Microsoft Account, such as
/// <b>MicrosoftAccount\user@domain.com</b>
/// </summary>
MicrosoftAccount
}
/// <summary>
/// Represents a Principal. Serves as a base class for Users and Groups.
/// </summary>
public class LocalPrincipal
{
#region Public Properties
/// <summary>
/// The account name of the Principal.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The Security Identifier that uniquely identifies the Principal/
/// </summary>
public SecurityIdentifier SID { get; set; }
/// <summary>
/// Indicates the account store from which the principal is sourced.
/// One of the PrincipalSource enumerations.
/// </summary>
public PrincipalSource? PrincipalSource { get; set; }
/// <summary>
/// The object class that represents this principal.
/// This can be User or Group.
/// </summary>
public string ObjectClass { get; set; }
#endregion Public Properties
#region Construction
/// <summary>
/// Initializes a new LocalPrincipal object.
/// </summary>
public LocalPrincipal()
{
}
/// <summary>
/// Initializes a new LocalPrincipal object with the specified name.
/// </summary>
/// <param name="name">Name of the new LocalPrincipal.</param>
public LocalPrincipal(string name)
{
Name = name;
}
#endregion Construction
#region Public Methods
/// <summary>
/// Provides a string representation of the Principal.
/// </summary>
/// <returns>
/// A string, in SDDL form, representing the Principal.
/// </returns>
public override string ToString()
{
return Name ?? SID.ToString();
}
#endregion Public Methods
}
}

View file

@ -0,0 +1,145 @@
using System;
using Microsoft.PowerShell.LocalAccounts;
namespace Microsoft.PowerShell.Commands
{
/// <summary>
/// Describes a Local User.
/// Objects of this type are provided to and returned from user-related Cmdlets.
/// </summary>
public class LocalUser : LocalPrincipal
{
#region Public Properties
/// <summary>
/// The date and time at which this user account expires.
/// A value of null indicates that the account never expires.
/// </summary>
public DateTime? AccountExpires { get; set; }
/// <summary>
/// A short description of the User.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Indicates whether the user account is enabled (true) or disabled (false).
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// The user's full name. Not the same as the User name.
/// </summary>
public string FullName { get; set; }
/// <summary>
/// The date and time at which this user account password is allowed
/// to be changed. The password cannot be changed before this time.
/// A value of null indicates that the password can be changed anytime.
/// </summary>
public DateTime? PasswordChangeableDate { get; set; }
/// <summary>
/// The date and time at which this user account password must be changed
/// to a new password. A value of null indicates that the password will
/// never expire.
/// </summary>
public DateTime? PasswordExpires { get; set; }
/// <summary>
/// Indicates whether the user is allowed to change the password (true)
/// or not (false).
/// </summary>
public bool UserMayChangePassword { get; set; }
/// <summary>
/// Indicates whether the user must have a password (true) or not (false).
/// </summary>
public bool PasswordRequired { get; set; }
/// <summary>
/// The date and time at which this user last changed the account password.
/// </summary>
public DateTime? PasswordLastSet { get; set; }
/// <summary>
/// The date and time at which the user last logged on to the machine.
/// </summary>
public DateTime? LastLogon { get; set; }
#endregion Public Properties
#region Construction
/// <summary>
/// Initializes a new LocalUser object.
/// </summary>
public LocalUser()
{
ObjectClass = Strings.ObjectClassUser;
}
/// <summary>
/// Initializes a new LocalUser object with the specified name.
/// </summary>
/// <param name="name">Name of the new LocalUser.</param>
public LocalUser(string name)
: base(name)
{
ObjectClass = Strings.ObjectClassUser;
}
/// <summary>
/// Construct a new LocalUser object that is a copy of another.
/// </summary>
/// <param name="other">The LocalUser object to copy.</param>
private LocalUser(LocalUser other)
: this(other.Name)
{
SID = other.SID;
PrincipalSource = other.PrincipalSource;
ObjectClass = other.ObjectClass;
AccountExpires = other.AccountExpires;
Description = other.Description;
Enabled = other.Enabled;
FullName = other.FullName;
PasswordChangeableDate = other.PasswordChangeableDate;
PasswordExpires = other.PasswordExpires;
UserMayChangePassword = other.UserMayChangePassword;
PasswordRequired = other.PasswordRequired;
PasswordLastSet = other.PasswordLastSet;
LastLogon = other.LastLogon;
}
#endregion Construction
#region Public Methods
/// <summary>
/// Provides a string representation of the LocalUser object.
/// </summary>
/// <returns>
/// A string containing the User Name.
/// </returns>
public override string ToString()
{
return Name ?? SID.ToString();
}
/// <summary>
/// Create a copy of a LocalUser object.
/// </summary>
/// <returns>
/// A new LocalUser object with the same property values as this one.
/// </returns>
public LocalUser Clone()
{
if (null == this)
{
throw new NullReferenceException();
}
return new LocalUser(this);
}
#endregion Public Methods
}
}

View file

@ -0,0 +1,523 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace System.Management.Automation.SecurityAccountsManager.Native
{
#region Enums
internal enum POLICY_INFORMATION_CLASS
{
PolicyAuditLogInformation = 1,
PolicyAuditEventsInformation,
PolicyPrimaryDomainInformation,
PolicyPdAccountInformation,
PolicyAccountDomainInformation,
PolicyLsaServerRoleInformation,
PolicyReplicaSourceInformation,
PolicyDefaultQuotaInformation,
PolicyModificationInformation,
PolicyAuditFullSetInformation,
PolicyAuditFullQueryInformation,
PolicyDnsDomainInformation
}
[Flags]
internal enum LSA_AccessPolicy : long
{
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
POLICY_TRUST_ADMIN = 0x00000008L,
POLICY_CREATE_ACCOUNT = 0x00000010L,
POLICY_CREATE_SECRET = 0x00000020L,
POLICY_CREATE_PRIVILEGE = 0x00000040L,
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
POLICY_SERVER_ADMIN = 0x00000400L,
POLICY_LOOKUP_NAMES = 0x00000800L,
POLICY_NOTIFICATION = 0x00001000L
}
internal enum SID_NAME_USE
{
SidTypeUser = 1,
SidTypeGroup,
SidTypeDomain,
SidTypeAlias,
SidTypeWellKnownGroup,
SidTypeDeletedAccount,
SidTypeInvalid,
SidTypeUnknown,
SidTypeComputer,
SidTypeLabel
}
internal enum LSA_USER_ACCOUNT_TYPE
{
UnknownUserAccountType = 0,
LocalUserAccountType,
PrimaryDomainUserAccountType,
ExternalDomainUserAccountType,
LocalConnectedUserAccountType, // Microsoft Account
AADUserAccountType,
InternetUserAccountType, // Generic internet User (eg. if the SID supplied is MSA's internet SID)
MSAUserAccountType // !!! NOT YET IN THE ENUM SPECIFIED IN THE C API !!!
}
#endregion Enums
#region Structures
[StructLayout(LayoutKind.Sequential)]
internal struct SECURITY_DESCRIPTOR
{
public byte Revision;
public byte Sbz1;
public UInt16 Control; // SECURITY_DESCRIPTOR_CONTROL
public IntPtr Owner;
public IntPtr Group;
public IntPtr Sacl;
public IntPtr Dacl;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ACL
{
public byte AclRevision;
public byte Sbz1;
public UInt16 AclSize;
public UInt16 AceCount;
public UInt16 Sbz2;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct USER_INFO_1
{
public string name;
public string password;
public int password_age;
public int priv;
public string home_dir;
public string comment;
public uint flags;
public string script_path;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_INFO_1008
{
public uint flags;
}
/// <summary>
/// The UNICODE_STRING structure is passed to a number of the SAM and LSA
/// API functions. This adds cleanup and managed-string conversion behaviors.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
private string buffer;
public UNICODE_STRING(string s)
{
buffer = String.IsNullOrEmpty(s) ? String.Empty : s;
Length = (UInt16)(2 * buffer.Length);
MaximumLength = Length;
}
public override string ToString()
{
// UNICODE_STRING structures that were populated by unmanaged code
// often have buffers that point to junk if Length = 0, or that
// point to non-null-terminated strings, resulting in marshaled
// String objects that have more characters than they should.
return Length == 0 ? String.Empty
: buffer.Substring(0, Length / 2);
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct OBJECT_ATTRIBUTES : IDisposable
{
public int Length;
public IntPtr RootDirectory;
public uint Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
private IntPtr objectName;
public OBJECT_ATTRIBUTES(string name, uint attrs)
{
Length = 0;
RootDirectory = IntPtr.Zero;
objectName = IntPtr.Zero;
Attributes = attrs;
SecurityDescriptor = IntPtr.Zero;
SecurityQualityOfService = IntPtr.Zero;
Length = ClrFacade.SizeOf<OBJECT_ATTRIBUTES>();
ObjectName = new UNICODE_STRING(name);
}
public UNICODE_STRING ObjectName
{
get
{
return ClrFacade.PtrToStructure<UNICODE_STRING>(objectName);
}
set
{
bool fDeleteOld = objectName != IntPtr.Zero;
if (!fDeleteOld)
objectName = Marshal.AllocHGlobal(Marshal.SizeOf(value));
Marshal.StructureToPtr(value, objectName, fDeleteOld);
}
}
public void Dispose()
{
if (objectName != IntPtr.Zero)
{
ClrFacade.DestroyStructure<UNICODE_STRING>(objectName);
Marshal.FreeHGlobal(objectName);
objectName = IntPtr.Zero;
}
}
}
// These structures are filled in by Marshalling, so fields will be initialized
// invisibly to the C# compiler, and some fields will not be used in C# code.
#pragma warning disable 0649, 0169
[StructLayout(LayoutKind.Explicit, Size = 8)]
struct LARGE_INTEGER
{
[FieldOffset(0)]
public Int64 QuadPart;
[FieldOffset(0)]
public UInt32 LowPart;
[FieldOffset(4)]
public Int32 HighPart;
}
#pragma warning restore 0649, 0169
#endregion Structures
/// <summary>
/// Wraps calls to Marshal functions that differ between .Net 4.5 and CoreCLR. .Net 4.5.1 types are not allowed for PowerShell.
/// </summary>
internal class ClrFacade
{
/// <summary>
/// Private constructor to prevent auto-generation of a default constructor
/// </summary>
private ClrFacade()
{
}
/// <summary>
/// Facade for Marshal.SizeOf
/// </summary>
internal static int SizeOf<T>()
{
#if CORECLR
// Marshal.SizeOf(Type) is obsolete in CoreCLR
return Marshal.SizeOf<T>();
#else
return Marshal.SizeOf(typeof(T));
#endif
}
/// <summary>
/// Facade for Marshal.DestroyStructure
/// </summary>
internal static void DestroyStructure<T>(IntPtr ptr)
{
#if CORECLR
// Marshal.DestroyStructure(IntPtr, Type) is obsolete in CoreCLR
Marshal.DestroyStructure<T>(ptr);
#else
Marshal.DestroyStructure(ptr, typeof(T));
#endif
}
/// <summary>
/// Facade for Marshal.PtrToStructure
/// </summary>
internal static T PtrToStructure<T>(IntPtr ptr)
{
#if CORECLR
// Marshal.PtrToStructure(IntPtr, Type) is obsolete in CoreCLR
return Marshal.PtrToStructure<T>(ptr);
#else
return (T)Marshal.PtrToStructure(ptr, typeof(T));
#endif
}
/// <summary>
/// Wraps Marshal.StructureToPtr to hide differences between the CLRs.
/// </summary>
internal static void StructureToPtr<T>(
T structure,
IntPtr ptr,
bool deleteOld)
{
#if CORECLR
Marshal.StructureToPtr<T>( structure, ptr, deleteOld );
#else
Marshal.StructureToPtr(structure, ptr, deleteOld);
#endif
}
}
internal static class Win32
{
#region Constants
// The following are masks for the predefined standard access types
internal const UInt32 DELETE = 0x00010000;
internal const UInt32 READ_CONTROL = 0x00020000;
internal const UInt32 WRITE_DAC = 0x00040000;
internal const UInt32 WRITE_OWNER = 0x00080000;
internal const UInt32 SYNCHRONIZE = 0x00100000;
internal const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
internal const UInt32 STANDARD_RIGHTS_READ = READ_CONTROL;
internal const UInt32 STANDARD_RIGHTS_WRITE = READ_CONTROL;
internal const UInt32 STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
internal const UInt32 STANDARD_RIGHTS_ALL = 0x001F0000;
internal const UInt32 SPECIFIC_RIGHTS_ALL = 0x0000FFFF;
internal const UInt32 ACCESS_SYSTEM_SECURITY = 0x01000000;
internal const UInt32 MAXIMUM_ALLOWED = 0x02000000;
internal const UInt32 GENERIC_READ = 0x80000000;
internal const UInt32 GENERIC_WRITE = 0x40000000;
internal const UInt32 GENERIC_EXECUTE = 0x20000000;
internal const UInt32 GENERIC_ALL = 0x10000000;
// These constants control the behavior of the FormatMessage Windows API function
internal const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
internal const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
internal const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
internal const uint FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
internal const uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
internal const uint FORMAT_MESSAGE_FROM_STRING = 0x00000400;
#region Win32 Error Codes
//
// MessageText:
//
// The operation completed successfully.
//
internal const Int32 ERROR_SUCCESS = 0;
internal const Int32 NO_ERROR = ERROR_SUCCESS;
//
// MessageId: ERROR_ACCESS_DENIED
//
// MessageText:
//
// Access is denied.
//
internal const int ERROR_ACCESS_DENIED = 5;
//
// MessageId: ERROR_BAD_NETPATH
//
// MessageText:
//
// The network path was not found.
//
internal const int ERROR_BAD_NETPATH = 53;
//
// MessageId: ERROR_NETWORK_ACCESS_DENIED
//
// MessageText:
//
// Network access is denied.
//
internal const int ERROR_NETWORK_ACCESS_DENIED = 65;
//
// MessageId: ERROR_INVALID_PARAMETER
//
// MessageText:
//
// The parameter is incorrect.
//
internal const int ERROR_INVALID_PARAMETER = 87;
//
// MessageText:
//
// The file name is too long.
//
internal const Int32 ERROR_BUFFER_OVERFLOW = 111;
//
// MessageText:
//
// The data area passed to a system call is too small.
//
internal const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
//
// MessageId: ERROR_INVALID_LEVEL
//
// MessageText:
//
// The system call level is not correct.
//
internal const int ERROR_INVALID_LEVEL = 124;
//
// MessageId: ERROR_INVALID_FLAGS
//
// MessageText:
//
// Invalid flags.
//
internal const Int32 ERROR_INVALID_FLAGS = 1004;
//
// MessageId: ERROR_ILL_FORMED_PASSWORD
//
// MessageText:
//
// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords.
//
internal const UInt32 ERROR_ILL_FORMED_PASSWORD = 1324;
//
// MessageId: ERROR_PASSWORD_RESTRICTION
//
// MessageText:
//
// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirements of the domain.
//
internal const UInt32 ERROR_PASSWORD_RESTRICTION = 1325;
//
// MessageText:
//
// No mapping between account names and security IDs was done.
//
internal const Int32 ERROR_NONE_MAPPED = 1332;
internal const int NERR_Success = 0;
// NERR_BASE is the base of error codes from network utilities,
// chosen to avoid conflict with system and redirector error codes.
// 2100 is a value that has been assigned to us by system.
internal const int NERR_BASE = 2100;
internal const int NERR_BadPassword = NERR_BASE + 103; // The password parameter is invalid.
internal const int NERR_UserNotFound = NERR_BASE + 121; // The user name could not be found.
internal const int NERR_NotPrimary = NERR_BASE + 126; // This operation is only allowed on the primary domain controller of the domain.
internal const int NERR_SpeGroupOp = NERR_BASE + 134; // This operation is not allowed on this special group.
internal const int NERR_PasswordTooShort = NERR_BASE + 145; // The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements.
internal const int NERR_InvalidComputer = NERR_BASE + 251; // This computer name is invalid.
internal const int NERR_LastAdmin = NERR_BASE + 352; // This operation is not allowed on the last administrative account.
#endregion Win32 Error Codes
#region SECURITY_DESCRIPTOR Control Flags
internal const UInt16 SE_DACL_PRESENT = 0x0004;
internal const UInt16 SE_SELF_RELATIVE = 0x8000;
#endregion SECURITY_DESCRIPTOR Control Flags
#region SECURITY_INFORMATION Values
internal const int DACL_SECURITY_INFORMATION = 0x00000004;
#endregion SECURITY_INFORMATION Values
#endregion Constants
#region Win32 Functions
[DllImport(PInvokeDllNames.LookupAccountSidDllName, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool LookupAccountSid(string systemName,
byte[] accountSid,
StringBuilder accountName,
ref Int32 nameLength,
StringBuilder domainName,
ref Int32 domainNameLength,
out SID_NAME_USE use);
[DllImport(PInvokeDllNames.LookupAccountNameDllName, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool LookupAccountName(string systemName,
string accountName,
[MarshalAs(UnmanagedType.LPArray)]
byte[] sid,
ref uint sidLength,
StringBuilder domainName,
ref uint domainNameLength,
out SID_NAME_USE peUse);
[DllImport(PInvokeDllNames.GetComputerNameDllName, CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern bool GetComputerName(StringBuilder name, ref uint size);
[DllImport(PInvokeDllNames.GetSecurityDescriptorDaclDllName, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetSecurityDescriptorDacl(IntPtr pSecurityDescriptor,
[MarshalAs(UnmanagedType.Bool)]
out bool bDaclPresent,
out IntPtr pDacl,
[MarshalAs(UnmanagedType.Bool)]
out bool bDaclDefaulted);
[DllImport(PInvokeDllNames.SetSecurityDescriptorDaclDllName, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetSecurityDescriptorDacl(IntPtr pSecurityDescriptor,
[MarshalAs(UnmanagedType.Bool)]
bool bDaclPresent,
IntPtr pDacl,
[MarshalAs(UnmanagedType.Bool)]
bool bDaclDefaulted);
[DllImport(PInvokeDllNames.FormatMessageDllName, SetLastError = true)]
internal static extern uint FormatMessage(uint dwFlags,
IntPtr lpSource,
uint dwMessageId,
uint dwLanguageId,
[Out] StringBuilder lpBuffer,
uint nSize,
string[] Arguments);
[DllImport("ntdll.dll")]
internal static extern uint RtlNtStatusToDosError(uint ntStatus);
#endregion Win32 Functions
#region LSA Functions
[DllImport(PInvokeDllNames.LsaOpenPolicyDllName, CharSet = CharSet.Unicode)]
internal static extern UInt32 LsaOpenPolicy(ref UNICODE_STRING SystemName,
ref OBJECT_ATTRIBUTES ObjectAttributes,
uint DesiredAccess,
out IntPtr PolicyHandle);
[DllImport(PInvokeDllNames.LsaQueryInformationPolicyDllName, CharSet = CharSet.Unicode)]
internal static extern UInt32 LsaQueryInformationPolicy(IntPtr lsaHandle,
POLICY_INFORMATION_CLASS infoClass,
out IntPtr buffer);
[DllImport(PInvokeDllNames.LsaFreeMemoryDllName)]
internal static extern UInt32 LsaFreeMemory(IntPtr buffer);
[DllImport(PInvokeDllNames.LsaCloseDllName)]
internal static extern UInt32 LsaClose(IntPtr handle);
[DllImport("api-ms-win-security-lsalookup-l1-1-2.dll")]
internal static extern UInt32 LsaLookupUserAccountType([MarshalAs(UnmanagedType.LPArray)] byte[] Sid,
out LSA_USER_ACCOUNT_TYPE accountType);
#endregion LSA Functions
}
}

View file

@ -0,0 +1,516 @@

namespace System.Management.Automation.SecurityAccountsManager.Native
{
internal static class NtStatus
{
#region Constants
//
// These values are taken from ntstatus.h
//
//
// Severity codes
//
public const UInt32 STATUS_SEVERITY_WARNING = 0x2;
public const UInt32 STATUS_SEVERITY_SUCCESS = 0x0;
public const UInt32 STATUS_SEVERITY_INFORMATIONAL = 0x1;
public const UInt32 STATUS_SEVERITY_ERROR = 0x3;
public const UInt32 STATUS_SUCCESS = 0x00000000;
//
// MessageText:
//
// Returned by enumeration APIs to indicate more information is available to successive calls.
//
public const UInt32 STATUS_MORE_ENTRIES = 0x00000105;
/////////////////////////////////////////////////////////////////////////
//
// Standard Information values
//
/////////////////////////////////////////////////////////////////////////
//
// MessageText:
//
// {Object Exists}
// An attempt was made to create an object and the object name already existed.
//
public const UInt32 STATUS_OBJECT_NAME_EXISTS = 0x40000000;
//
// MessageText:
//
// {Password Too Complex}
// The Windows password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string.
//
public const UInt32 STATUS_NULL_LM_PASSWORD = 0x4000000D;
//
// MessageText:
//
// {Access Denied}
// A process has requested access to an object, but has not been granted those access rights.
//
public const UInt32 STATUS_ACCESS_DENIED = 0xC0000022;
//
// MessageText:
//
// The name provided is not a properly formed account name.
//
public const UInt32 STATUS_INVALID_ACCOUNT_NAME = 0xC0000062;
//
// MessageText:
//
// The specified account already exists.
//
public const UInt32 STATUS_USER_EXISTS = 0xC0000063;
//
// MessageText:
//
// The specified account does not exist.
//
public const UInt32 STATUS_NO_SUCH_USER = 0xC0000064; // ntsubauth
//
// MessageText:
//
// The specified group already exists.
//
public const UInt32 STATUS_GROUP_EXISTS = 0xC0000065;
//
// MessageText:
//
// The specified group does not exist.
//
public const UInt32 STATUS_NO_SUCH_GROUP = 0xC0000066;
//
// MessageText:
//
// The specified user account is already in the specified group account. Also used to indicate a group cannot be deleted because it contains a member.
//
public const UInt32 STATUS_MEMBER_IN_GROUP = 0xC0000067;
//
// MessageText:
//
// The specified user account is not a member of the specified group account.
//
public const UInt32 STATUS_MEMBER_NOT_IN_GROUP = 0xC0000068;
//
// MessageText:
//
// Indicates the requested operation would disable, delete or could prevent logon for an administration account.
// This is not allowed to prevent creating a situation in which the system cannot be administrated.
//
public const UInt32 STATUS_LAST_ADMIN = 0xC0000069;
//
// MessageText:
//
// When trying to update a password, this return status indicates that the value provided as the current password is not correct.
//
public const UInt32 STATUS_WRONG_PASSWORD = 0xC000006A; // ntsubauth
//
// MessageText:
//
// When trying to update a password, this return status indicates that the value provided for the new password contains values that are not allowed in passwords.
//
public const UInt32 STATUS_ILL_FORMED_PASSWORD = 0xC000006B;
//
// MessageText:
//
// When trying to update a password, this status indicates that some password update rule has been violated. For example, the password may not meet length criteria.
//
public const UInt32 STATUS_PASSWORD_RESTRICTION = 0xC000006C; // ntsubauth
//
// MessageText:
//
// The user account's password has expired.
//
public const UInt32 STATUS_PASSWORD_EXPIRED = 0xC0000071; // ntsubauth
//
// MessageText:
//
// The referenced account is currently disabled and may not be logged on to.
//
public const UInt32 STATUS_ACCOUNT_DISABLED = 0xC0000072; // ntsubauth
//
// MessageText:
//
// None of the information to be translated has been translated.
//
public const UInt32 STATUS_NONE_MAPPED = 0xC0000073;
//
// MessageText:
//
// Indicates the sub-authority value is invalid for the particular use.
//
public const UInt32 STATUS_INVALID_SUB_AUTHORITY = 0xC0000076;
//
// MessageText:
//
// Indicates the ACL structure is not valid.
//
public const UInt32 STATUS_INVALID_ACL = 0xC0000077;
//
// MessageText:
//
// Indicates the SID structure is not valid.
//
public const UInt32 STATUS_INVALID_SID = 0xC0000078;
//
// MessageText:
//
// Indicates the SECURITY_DESCRIPTOR structure is not valid.
//
public const UInt32 STATUS_INVALID_SECURITY_DESCR = 0xC0000079;
//
// Network specific errors.
//
//
//
// MessageText:
//
// The request is not supported.
//
public const UInt32 STATUS_NOT_SUPPORTED = 0xC00000BB;
//
// MessageText:
//
// This remote computer is not listening.
//
public const UInt32 STATUS_REMOTE_NOT_LISTENING = 0xC00000BC;
//
// MessageText:
//
// Network access is denied.
//
public const UInt32 STATUS_NETWORK_ACCESS_DENIED = 0xC00000CA;
//
// MessageText:
//
// Indicates an attempt was made to operate on the security of an object that does not have security associated with it.
//
public const UInt32 STATUS_NO_SECURITY_ON_OBJECT = 0xC00000D7;
//
// MessageText:
//
// An internal error occurred.
//
public const UInt32 STATUS_INTERNAL_ERROR = 0xC00000E5;
//
// MessageText:
//
// Indicates a security descriptor is not in the necessary format (absolute or self-relative).
//
public const UInt32 STATUS_BAD_DESCRIPTOR_FORMAT = 0xC00000E7;
//
// MessageText:
//
// A specified name string is too long for its intended use.
//
public const UInt32 STATUS_NAME_TOO_LONG = 0xC0000106;
//
// MessageText:
//
// Indicates a name specified as a remote computer name is syntactically invalid.
//
public const UInt32 STATUS_INVALID_COMPUTER_NAME = 0xC0000122;
//
// MessageText:
//
// Indicates an operation has been attempted on a built-in (special) SAM account which is incompatible with built-in accounts. For example, built-in accounts cannot be deleted.
//
public const UInt32 STATUS_SPECIAL_ACCOUNT = 0xC0000124;
//
// MessageText:
//
// The operation requested may not be performed on the specified group because it is a built-in special group.
//
public const UInt32 STATUS_SPECIAL_GROUP = 0xC0000125;
//
// MessageText:
//
// The operation requested may not be performed on the specified user because it is a built-in special user.
//
public const UInt32 STATUS_SPECIAL_USER = 0xC0000126;
//
// MessageText:
//
// Indicates a member cannot be removed from a group because the group is currently the member's primary group.
//
public const UInt32 STATUS_MEMBERS_PRIMARY_GROUP = 0xC0000127;
//
// MessageText:
//
// The specified local group does not exist.
//
public const UInt32 STATUS_NO_SUCH_ALIAS = 0xC0000151;
//
// MessageText:
//
// The specified account name is not a member of the group.
//
public const UInt32 STATUS_MEMBER_NOT_IN_ALIAS = 0xC0000152;
//
// MessageText:
//
// The specified account name is already a member of the group.
//
public const UInt32 STATUS_MEMBER_IN_ALIAS = 0xC0000153;
//
// MessageText:
//
// The specified local group already exists.
//
public const UInt32 STATUS_ALIAS_EXISTS = 0xC0000154;
//
// MessageText:
//
// A member could not be added to or removed from the local group because the member does not exist.
//
public const UInt32 STATUS_NO_SUCH_MEMBER = 0xC000017A;
//
// MessageText:
//
// A new member could not be added to a local group because the member has the wrong account type.
//
public const UInt32 STATUS_INVALID_MEMBER = 0xC000017B;
//
// MessageText:
//
// The user's account has expired.
//
public const UInt32 STATUS_ACCOUNT_EXPIRED = 0xC0000193; // ntsubauth
//
// MessageText:
//
// {Invalid ACE Condition}
// The specified access control entry (ACE) contains an invalid condition.
//
public const UInt32 STATUS_INVALID_ACE_CONDITION = 0xC00001A2;
//
// MessageText:
//
// The user's password must be changed before signing in.
//
public const UInt32 STATUS_PASSWORD_MUST_CHANGE = 0xC0000224; // ntsubauth
//
// MessageText:
//
// The object was not found.
//
public const UInt32 STATUS_NOT_FOUND = 0xC0000225;
//
// MessageText:
//
// Could not find a domain controller for this domain.
//
public const UInt32 STATUS_DOMAIN_CONTROLLER_NOT_FOUND = 0xC0000233;
//
// MessageText:
//
// The user account has been automatically locked because too many invalid logon attempts or password change attempts have been requested.
//
public const UInt32 STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234; // ntsubauth
//
// MessageText:
//
// The password provided is too short to meet the policy of your user account. Please choose a longer password.
//
public const UInt32 STATUS_PWD_TOO_SHORT = 0xC000025A;
//
// MessageText:
//
// The policy of your user account does not allow you to change passwords too frequently. This is done to prevent users from changing back to a familiar, but potentially discovered, password. If you feel your password has been compromised then please contact your administrator immediately to have a new one assigned.
//
public const UInt32 STATUS_PWD_TOO_RECENT = 0xC000025B;
//
// MessageText:
//
// You have attempted to change your password to one that you have used in the past. The policy of your user account does not allow this. Please select a password that you have not previously used.
//
public const UInt32 STATUS_PWD_HISTORY_CONFLICT = 0xC000025C;
//
// MessageText:
//
// The password provided is too long to meet the policy of your user account. Please choose a shorter password.
//
public const UInt32 STATUS_PWD_TOO_LONG = 0xC000027A;
//
// MessageText:
//
// Only an administrator can modify the membership list of an administrative group.
//
public const UInt32 STATUS_DS_SENSITIVE_GROUP_VIOLATION = 0xC00002CD;
//
// MessageText:
//
// The specified group type is invalid.
//
public const UInt32 STATUS_DS_INVALID_GROUP_TYPE = 0xC00002D4;
//
// MessageText:
//
// A local group cannot have another cross domain local group as a member.
//
public const UInt32 STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 0xC00002DB;
//
// MessageText:
//
// Cannot change to security disabled group because of having primary members in this group.
//
public const UInt32 STATUS_DS_HAVE_PRIMARY_MEMBERS = 0xC00002DC;
//
// MessageText:
//
// EAS policy requires that the user change their password before this operation can be performed.
//
public const UInt32 STATUS_PASSWORD_CHANGE_REQUIRED = 0xC000030C;
#endregion Constants
#region Public Methods
/// <summary>
/// Determine if an NTSTATUS value indicates Success
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// True if the NTSTATUS value indicates success, false otherwise.
/// </returns>
public static bool IsSuccess(UInt32 ntstatus)
{
return Severity(ntstatus) == STATUS_SEVERITY_SUCCESS;
}
/// <summary>
/// Determine if an NTSTATUS value indicates an Error
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// True if the NTSTATUS value indicates an error, false otherwise.
/// </returns>
public static bool IsError(UInt32 ntstatus)
{
return Severity(ntstatus) == STATUS_SEVERITY_ERROR;
}
/// <summary>
/// Determine if an NTSTATUS value indicates a Warning
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// True if the NTSTATUS value indicates a warning, false otherwise.
/// </returns>
public static bool IsWarning(UInt32 ntstatus)
{
return Severity(ntstatus) == STATUS_SEVERITY_WARNING;
}
/// <summary>
/// Determine if an NTSTATUS value indicates that the value is Informational.
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// True if the NTSTATUS value indicates that it is informational, false otherwise.
/// </returns>
public static bool IsInformational(UInt32 ntstatus)
{
return Severity(ntstatus) == STATUS_SEVERITY_INFORMATIONAL;
}
/// <summary>
/// Return the Severity part of an NTSTATUS value
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// One of the STATUS_SEVERITY_* values
/// </returns>
public static uint Severity(UInt32 ntstatus)
{
return ntstatus >> 30;
}
/// <summary>
/// Return the Facility part of an NSTATUS value
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// The value of the Facility portion of an NTSTATUS value.
/// </returns>
public static uint Facility(UInt32 ntstatus)
{
return (ntstatus >> 16) & 0x0FFF;
}
/// <summary>
/// Return the Code part of an NTSTATUS value
/// </summary>
/// <param name="ntstatus">The NTSTATUS value returned from native functions.</param>
/// <returns>
/// The value of the Code portion of an NTSTATUS value.
/// </returns>
public static uint Code(UInt32 ntstatus)
{
return ntstatus & 0xFFFF;
}
#endregion Public Methods
}
}

View file

@ -0,0 +1,48 @@
//
// Copyright (C) Microsoft. All rights reserved.
//
namespace System.Management.Automation
{
/// <summary>
/// PinvokeDllNames contains the DLL names to be use for PInvoke in FullCLR/CoreCLR powershell.
///
/// * When adding a new DLL name here, make sure that you add both the FullCLR and CoreCLR version
/// of it. Add the comment '/*COUNT*/' with the new DLL name, and make sure the 'COUNT' is the
/// same for both FullCLR and CoreCLR DLL names.
/// </summary>
internal static class PInvokeDllNames
{
#if CORECLR
internal const string GetLastErrorDllName = "api-ms-win-core-errorhandling-l1-1-0.dll"; /* 1*/
internal const string LookupAccountSidDllName = "api-ms-win-security-lsalookup-l2-1-1.dll"; /* 2*/
internal const string IsValidSidDllName = "api-ms-win-security-base-l1-2-0.dll"; /* 3*/
internal const string GetLengthSidDllName = "api-ms-win-security-base-l1-2-0.dll"; /* 4*/
internal const string LsaFreeMemoryDllName = "api-ms-win-security-lsapolicy-l1-1-0.dll"; /* 5*/
internal const string LsaOpenPolicyDllName = "api-ms-win-security-lsapolicy-l1-1-0.dll"; /* 6*/
internal const string LsaQueryInformationPolicyDllName = "api-ms-win-security-lsapolicy-l1-1-0.dll"; /* 7*/
internal const string LsaCloseDllName = "api-ms-win-security-lsapolicy-l1-1-0.dll"; /* 8*/
internal const string LookupAccountNameDllName = "api-ms-win-security-lsalookup-l2-1-1.dll"; /* 9*/
internal const string GetComputerNameDllName = "api-ms-win-downlevel-kernel32-l2-1-0.dll"; /*10*/
internal const string GetSecurityDescriptorDaclDllName = "api-ms-win-security-base-l1-2-0"; /*11*/
internal const string SetSecurityDescriptorDaclDllName = "api-ms-win-security-base-l1-2-0"; /*12*/
internal const string FormatMessageDllName = "api-ms-win-core-localization-l1-2-1"; /*13*/
internal const string GetVersionExDllName = "api-ms-win-core-sysinfo-l1-2-1.dll"; /*14*/
#else
internal const string GetLastErrorDllName = "kernel32.dll"; /* 1*/
internal const string LookupAccountSidDllName = "advapi32.dll"; /* 2*/
internal const string IsValidSidDllName = "advapi32.dll"; /* 3*/
internal const string GetLengthSidDllName = "advapi32.dll"; /* 4*/
internal const string LsaFreeMemoryDllName = "advapi32.dll"; /* 5*/
internal const string LsaOpenPolicyDllName = "advapi32.dll"; /* 6*/
internal const string LsaQueryInformationPolicyDllName = "advapi32.dll"; /* 7*/
internal const string LsaCloseDllName = "advapi32.dll"; /* 8*/
internal const string LookupAccountNameDllName = "advapi32.dll"; /* 9*/
internal const string GetComputerNameDllName = "kernel32.dll"; /*10*/
internal const string GetSecurityDescriptorDaclDllName = "advapi32.dll"; /*11*/
internal const string SetSecurityDescriptorDaclDllName = "advapi32.dll"; /*12*/
internal const string FormatMessageDllName = "kernel32.dll"; /*13*/
internal const string GetVersionExDllName = "kernel32.dll"; /*14*/
#endif
}
}

View file

@ -0,0 +1,7 @@
using System.Reflection;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LocalAccounts")]
[assembly: AssemblyDescription("PowerShell cmdlet for local accounts.")]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,530 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
//using System.Management.Automation.SecurityAccountsManager.Native;
namespace System.Management.Automation.SecurityAccountsManager.Native.NtSam
{
#region Enums
internal enum ALIAS_INFORMATION_CLASS
{
AliasGeneralInformation = 1,
AliasNameInformation,
AliasAdminCommentInformation,
AliasReplicationInformation,
AliasExtendedInformation,
}
internal enum GROUP_INFORMATION_CLASS
{
GroupGeneralInformation = 1,
GroupNameInformation,
GroupAttributeInformation,
GroupAdminCommentInformation,
GroupReplicationInformation
}
internal enum USER_INFORMATION_CLASS
{
UserGeneralInformation = 1,
UserPreferencesInformation,
UserLogonInformation,
UserLogonHoursInformation,
UserAccountInformation,
UserNameInformation,
UserAccountNameInformation,
UserFullNameInformation,
UserPrimaryGroupInformation,
UserHomeInformation,
UserScriptInformation,
UserProfileInformation,
UserAdminCommentInformation,
UserWorkStationsInformation,
UserSetPasswordInformation,
UserControlInformation,
UserExpiresInformation,
UserInternal1Information,
UserInternal2Information,
UserParametersInformation,
UserAllInformation,
UserInternal3Information,
UserInternal4Information,
UserInternal5Information,
UserInternal4InformationNew,
UserInternal5InformationNew,
UserInternal6Information,
UserExtendedInformation,
UserLogonUIInformation,
}
#endregion Enums
#region Structures
[StructLayout(LayoutKind.Sequential)]
internal struct SR_SECURITY_DESCRIPTOR
{
public UInt32 Length;
public IntPtr SecurityDescriptor;
}
[StructLayout(LayoutKind.Sequential)]
internal struct LOGON_HOURS
{
public UInt16 UnitsPerWeek;
//
// UnitsPerWeek is the number of equal length time units the week is
// divided into. This value is used to compute the length of the bit
// string in logon_hours. Must be less than or equal to
// SAM_UNITS_PER_WEEK (10080) for this release.
//
// LogonHours is a bit map of valid logon times. Each bit represents
// a unique division in a week. The largest bit map supported is 1260
// bytes (10080 bits), which represents minutes per week. In this case
// the first bit (bit 0, byte 0) is Sunday, 00:00:00 - 00-00:59; bit 1,
// byte 0 is Sunday, 00:01:00 - 00:01:59, etc. A NULL pointer means
// DONT_CHANGE for SamSetInformationUser() calls.
//
public IntPtr LogonHours;
}
[StructLayout(LayoutKind.Sequential, Pack=4)]
internal struct USER_ALL_INFORMATION
{
public LARGE_INTEGER LastLogon;
public LARGE_INTEGER LastLogoff;
public LARGE_INTEGER PasswordLastSet;
public LARGE_INTEGER AccountExpires;
public LARGE_INTEGER PasswordCanChange;
public LARGE_INTEGER PasswordMustChange;
public UNICODE_STRING UserName;
public UNICODE_STRING FullName;
public UNICODE_STRING HomeDirectory;
public UNICODE_STRING HomeDirectoryDrive;
public UNICODE_STRING ScriptPath;
public UNICODE_STRING ProfilePath;
public UNICODE_STRING AdminComment;
public UNICODE_STRING WorkStations;
public UNICODE_STRING UserComment;
public UNICODE_STRING Parameters;
public UNICODE_STRING LmPassword;
public UNICODE_STRING NtPassword;
public UNICODE_STRING PrivateData;
public SR_SECURITY_DESCRIPTOR SecurityDescriptor;
public UInt32 UserId;
public UInt32 PrimaryGroupId;
public UInt32 UserAccountControl;
public UInt32 WhichFields;
public LOGON_HOURS LogonHours;
public UInt16 BadPasswordCount;
public UInt16 LogonCount;
public UInt16 CountryCode;
public UInt16 CodePage;
[MarshalAs(UnmanagedType.I1)]
public bool LmPasswordPresent;
[MarshalAs(UnmanagedType.I1)]
public bool NtPasswordPresent;
[MarshalAs(UnmanagedType.I1)]
public bool PasswordExpired;
[MarshalAs(UnmanagedType.I1)]
public bool PrivateDataSensitive;
}
[StructLayout(LayoutKind.Sequential, Pack=4)]
internal struct USER_GENERAL_INFORMATION
{
public UNICODE_STRING UserName;
public UNICODE_STRING FullName;
public UInt32 PrimaryGroupId;
public UNICODE_STRING AdminComment;
public UNICODE_STRING UserComment;
}
[StructLayout(LayoutKind.Sequential, Pack=4)]
internal struct USER_LOGON_INFORMATION
{
public UNICODE_STRING UserName;
public UNICODE_STRING FullName;
public UInt32 UserId;
public UInt32 PrimaryGroupId;
public UNICODE_STRING HomeDirectory;
public UNICODE_STRING HomeDirectoryDrive;
public UNICODE_STRING ScriptPath;
public UNICODE_STRING ProfilePath;
public UNICODE_STRING WorkStations;
public LARGE_INTEGER LastLogon;
public LARGE_INTEGER LastLogoff;
public LARGE_INTEGER PasswordLastSet;
public LARGE_INTEGER PasswordCanChange;
public LARGE_INTEGER PasswordMustChange;
public LOGON_HOURS LogonHours;
public UInt16 BadPasswordCount;
public UInt16 LogonCount;
public UInt32 UserAccountControl;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_ACCOUNT_NAME_INFORMATION
{
public UNICODE_STRING UserName;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_FULL_NAME_INFORMATION
{
public UNICODE_STRING FullName;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_NAME_INFORMATION
{
public UNICODE_STRING UserName;
public UNICODE_STRING FullName;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_ADMIN_COMMENT_INFORMATION
{
UNICODE_STRING AdminComment;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_EXPIRES_INFORMATION
{
//LARGE_INTEGER AccountExpires;
public Int64 AccountExpires;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_SET_PASSWORD_INFORMATION
{
public UNICODE_STRING Password;
public bool PasswordExpired;
}
[StructLayout(LayoutKind.Sequential)]
internal struct USER_LOGON_HOURS_INFORMATION
{
public LOGON_HOURS LogonHours;
}
[StructLayout(LayoutKind.Sequential)]
internal struct POLICY_PRIMARY_DOMAIN_INFO
{
public UNICODE_STRING Name;
public IntPtr Sid;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ALIAS_GENERAL_INFORMATION
{
public UNICODE_STRING Name;
public UInt32 MemberCount;
public UNICODE_STRING AdminComment;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ALIAS_NAME_INFORMATION
{
public UNICODE_STRING Name;
}
[StructLayout(LayoutKind.Sequential)]
internal struct ALIAS_ADM_COMMENT_INFORMATION
{
public UNICODE_STRING AdminComment;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SAMPR_GROUP_GENERAL_INFORMATION
{
public UNICODE_STRING Name;
public UInt32 Attributes;
public UInt32 MemberCount;
public UNICODE_STRING AdminComment;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SAMPR_GROUP_NAME_INFORMATION
{
public UNICODE_STRING Name;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SAM_RID_ENUMERATION
{
public UInt32 RelativeId;
public UNICODE_STRING Name;
}
#endregion Structures
/// <summary>
/// Provides methods for invoking functions in the Windows
/// Security Accounts Manager (SAM) API.
/// </summary>
internal static class SamApi
{
#region Constants
// Account enumeration filters, may be combined by bitwise OR
internal const UInt32 SAM_USER_ENUMERATION_FILTER_LOCAL = 0x00000001;
internal const UInt32 SAM_USER_ENUMERATION_FILTER_INTERNET = 0x00000002;
internal const UInt32 SAM_SERVER_LOOKUP_DOMAIN = 0x0020;
//
// Bits to be used in UserAllInformation's WhichFields field (to indicate
// which items were queried or set).
//
internal const UInt32 USER_ALL_USERNAME = 0x00000001;
internal const UInt32 USER_ALL_FULLNAME = 0x00000002;
internal const UInt32 USER_ALL_USERID = 0x00000004;
internal const UInt32 USER_ALL_PRIMARYGROUPID = 0x00000008;
internal const UInt32 USER_ALL_ADMINCOMMENT = 0x00000010;
internal const UInt32 USER_ALL_USERCOMMENT = 0x00000020;
internal const UInt32 USER_ALL_HOMEDIRECTORY = 0x00000040;
internal const UInt32 USER_ALL_HOMEDIRECTORYDRIVE = 0x00000080;
internal const UInt32 USER_ALL_SCRIPTPATH = 0x00000100;
internal const UInt32 USER_ALL_PROFILEPATH = 0x00000200;
internal const UInt32 USER_ALL_WORKSTATIONS = 0x00000400;
internal const UInt32 USER_ALL_LASTLOGON = 0x00000800;
internal const UInt32 USER_ALL_LASTLOGOFF = 0x00001000;
internal const UInt32 USER_ALL_LOGONHOURS = 0x00002000;
internal const UInt32 USER_ALL_BADPASSWORDCOUNT = 0x00004000;
internal const UInt32 USER_ALL_LOGONCOUNT = 0x00008000;
internal const UInt32 USER_ALL_PASSWORDCANCHANGE = 0x00010000;
internal const UInt32 USER_ALL_PASSWORDMUSTCHANGE = 0x00020000;
internal const UInt32 USER_ALL_PASSWORDLASTSET = 0x00040000;
internal const UInt32 USER_ALL_ACCOUNTEXPIRES = 0x00080000;
internal const UInt32 USER_ALL_USERACCOUNTCONTROL = 0x00100000;
internal const UInt32 USER_ALL_PARAMETERS = 0x00200000; // ntsubauth
internal const UInt32 USER_ALL_COUNTRYCODE = 0x00400000;
internal const UInt32 USER_ALL_CODEPAGE = 0x00800000;
internal const UInt32 USER_ALL_NTPASSWORDPRESENT = 0x01000000; // field AND boolean
internal const UInt32 USER_ALL_LMPASSWORDPRESENT = 0x02000000; // field AND boolean
internal const UInt32 USER_ALL_PRIVATEDATA = 0x04000000; // field AND boolean
internal const UInt32 USER_ALL_PASSWORDEXPIRED = 0x08000000;
internal const UInt32 USER_ALL_SECURITYDESCRIPTOR = 0x10000000;
internal const UInt32 USER_ALL_OWFPASSWORD = 0x20000000; // boolean
internal const UInt32 USER_ALL_UNDEFINED_MASK = 0xC0000000;
//
// Bit masks for the UserAccountControl member of the USER_ALL_INFORMATION structure
//
internal const UInt32 USER_ACCOUNT_DISABLED = 0x00000001;
internal const UInt32 USER_HOME_DIRECTORY_REQUIRED = 0x00000002;
internal const UInt32 USER_PASSWORD_NOT_REQUIRED = 0x00000004;
internal const UInt32 USER_TEMP_DUPLICATE_ACCOUNT = 0x00000008;
internal const UInt32 USER_NORMAL_ACCOUNT = 0x00000010;
internal const UInt32 USER_MNS_LOGON_ACCOUNT = 0x00000020;
internal const UInt32 USER_INTERDOMAIN_TRUST_ACCOUNT = 0x00000040;
internal const UInt32 USER_WORKSTATION_TRUST_ACCOUNT = 0x00000080;
internal const UInt32 USER_SERVER_TRUST_ACCOUNT = 0x00000100;
internal const UInt32 USER_DONT_EXPIRE_PASSWORD = 0x00000200;
internal const UInt32 USER_ACCOUNT_AUTO_LOCKED = 0x00000400;
internal const UInt32 USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000800;
internal const UInt32 USER_SMARTCARD_REQUIRED = 0x00001000;
internal const UInt32 USER_TRUSTED_FOR_DELEGATION = 0x00002000;
internal const UInt32 USER_NOT_DELEGATED = 0x00004000;
internal const UInt32 USER_USE_DES_KEY_ONLY = 0x00008000;
internal const UInt32 USER_DONT_REQUIRE_PREAUTH = 0x00010000;
internal const UInt32 USER_PASSWORD_EXPIRED = 0x00020000;
internal const UInt32 USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x00040000;
internal const UInt32 USER_NO_AUTH_DATA_REQUIRED = 0x00080000;
internal const UInt32 USER_PARTIAL_SECRETS_ACCOUNT = 0x00100000;
internal const UInt32 USER_USE_AES_KEYS = 0x00200000;
//
// Access rights for user object
//
internal const UInt16 USER_CHANGE_PASSWORD = 0x0040;
#endregion Constants
#region Sam Functions
[DllImport("samlib.dll")]
public static extern UInt32 SamConnect(ref UNICODE_STRING serverName,
out IntPtr serverHandle,
UInt32 desiredAccess,
ref OBJECT_ATTRIBUTES objectAttributes);
[DllImport("samlib.dll")]
internal static extern UInt32 SamRidToSid(IntPtr objectHandle, UInt32 rid, out IntPtr sid);
[DllImport("samlib.dll")]
internal static extern UInt32 SamCloseHandle(IntPtr serverHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamFreeMemory(IntPtr buffer);
#region Domain Functions
[DllImport("samlib.dll")]
internal static extern UInt32 SamOpenDomain(IntPtr serverHandle,
UInt32 desiredAccess,
IntPtr domainId,
out IntPtr domainHandle);
#endregion Domain Functions
#region Alias Functions
[DllImport("samlib.dll")]
internal static extern UInt32 SamEnumerateAliasesInDomain(IntPtr domainHandle,
ref UInt32 enumerationContext,
out IntPtr buffer,
UInt32 preferredMaximumLength,
out UInt32 countReturned);
[DllImport("samlib.dll")]
internal static extern UInt32 SamCreateAliasInDomain(IntPtr domainHandle,
IntPtr accountName, // PUNICODE_STRING
UInt32 desiredAccess,
out IntPtr aliasHandle,
out UInt32 relativeId); // PULONG
[DllImport("samlib.dll")]
internal static extern UInt32 SamOpenAlias(IntPtr domainHandle,
UInt32 desiredAccess,
UInt32 aliasId,
out IntPtr aliasHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamQueryInformationAlias(IntPtr aliasHandle,
ALIAS_INFORMATION_CLASS aliasInformationClass,
out IntPtr buffer);
[DllImport("samlib.dll")]
internal static extern UInt32 SamSetInformationAlias(IntPtr aliasHandle,
ALIAS_INFORMATION_CLASS aliasInformationClass,
IntPtr buffer);
[DllImport("samlib.dll")]
internal static extern UInt32 SamDeleteAlias(IntPtr aliasHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamAddMemberToAlias(IntPtr aliasHandle,
byte[] memberId); // PSID
[DllImport("samlib.dll")]
internal static extern UInt32 SamAddMultipleMembersToAlias(IntPtr aliasHandle,
IntPtr memberIds, // PSID
UInt32 memberCount);
[DllImport("samlib.dll")]
internal static extern UInt32 SamRemoveMemberFromAlias(IntPtr aliasHandle,
byte[] memberId); // PSID
[DllImport("samlib.dll")]
internal static extern UInt32 SamRemoveMultipleMembersFromAlias(IntPtr aliasHandle,
IntPtr memberIds, // PSID
UInt32 memberCount);
[DllImport("samlib.dll")]
internal static extern UInt32 SamGetMembersInAlias(IntPtr aliasHandle,
out IntPtr memberIds, // PSID **
out UInt32 memberCount);
#endregion Alias Functions
#region Group Functions
[DllImport("samlib.dll")]
internal static extern UInt32 SamEnumerateGroupsInDomain(IntPtr domainHandle,
ref UInt32 enumerationContext,
out IntPtr buffer,
UInt32 preferredMaximumLength,
out UInt32 countReturned);
[DllImport("samlib.dll")]
internal static extern UInt32 SamCreateGroupInDomain(IntPtr domainHandle,
ref UNICODE_STRING accountName,
UInt32 desiredAccess,
out IntPtr groupHandle,
out UInt32 relativeId);
[DllImport("samlib.dll")]
internal static extern UInt32 SamOpenGroup(IntPtr domainHandle,
UInt32 desiredAccess,
UInt32 groupId,
out IntPtr groupHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamQueryInformationGroup(IntPtr groupHandle,
GROUP_INFORMATION_CLASS groupInformationClass,
out IntPtr buffer);
[DllImport("samlib.dll")]
internal static extern UInt32 SamSetInformationGroup(IntPtr groupHandle,
GROUP_INFORMATION_CLASS groupInformationClass,
IntPtr buffer);
#endregion Group Functions
#region User Functions
[DllImport("samlib.dll")]
internal static extern UInt32 SamOpenUser(IntPtr domainHandle,
UInt32 desiredAccess,
UInt32 userID,
out IntPtr userHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamDeleteUser(IntPtr aliasHandle);
[DllImport("samlib.dll")]
internal static extern UInt32 SamEnumerateUsersInDomain(IntPtr domainHandle,
ref UInt32 enumerationContext,
UInt32 userAccountControl,
out IntPtr buffer,
UInt32 preferredMaximumLength,
out UInt32 countReturned);
[DllImport("samlib.dll")]
internal static extern UInt32 SamEnumerateUsersInDomain2(IntPtr domainHandle,
ref UInt32 enumerationContext,
UInt32 userAccountControl,
UInt32 filter,
out IntPtr buffer,
UInt32 preferredMaximumLength,
out UInt32 countReturned);
[DllImport("samlib.dll")]
internal static extern UInt32 SamCreateUserInDomain(IntPtr domainHandle,
ref UNICODE_STRING accountName,
UInt32 desiredAccess,
out IntPtr userHandle,
out UInt32 relativeId);
[DllImport("samlib.dll")]
internal static extern UInt32 SamCreateUser2InDomain(IntPtr domainHandle,
ref UNICODE_STRING accountName,
Int32 accountType,
UInt32 desiredAccess,
out IntPtr userHandle,
out UInt32 grantedAccess,
out UInt32 relativeId);
[DllImport("samlib.dll")]
internal static extern UInt32 SamQueryInformationUser(IntPtr userHandle,
USER_INFORMATION_CLASS userInformationClass,
out IntPtr buffer);
[DllImport("samlib.dll")]
internal static extern UInt32 SamSetInformationUser(IntPtr userHandle,
USER_INFORMATION_CLASS userInformationClass,
IntPtr buffer);
[DllImport("samlib.dll")]
internal static extern UInt32 SamQuerySecurityObject(IntPtr objectHandle,
UInt32 securityInformation,
out IntPtr securityDescriptor);
[DllImport("samlib.dll")]
internal static extern UInt32 SamSetSecurityObject(IntPtr objectHandle,
UInt32 SecurityInformation,
IntPtr SecurityDescriptor);
#endregion User Functions
#endregion Sam Functions
}
}

View file

@ -0,0 +1,58 @@
using System.Globalization;
using System.Management.Automation.SecurityAccountsManager.Native;
namespace System.Management.Automation.SecurityAccountsManager
{
/// <summary>
/// Contains utility functions for formatting localizable strings
/// </summary>
internal class StringUtil
{
internal static string Format(string str)
{
return string.Format(CultureInfo.CurrentCulture, str);
}
internal static string Format(string fmt, string p0)
{
return string.Format(CultureInfo.CurrentCulture, fmt, p0);
}
internal static string Format(string fmt, string p0, string p1)
{
return string.Format(CultureInfo.CurrentCulture, fmt, p0, p1);
}
internal static string Format(string fmt, uint p0)
{
return string.Format(CultureInfo.CurrentCulture, fmt, p0);
}
internal static string Format(string fmt, int p0)
{
return string.Format(CultureInfo.CurrentCulture, fmt, p0);
}
internal static string FormatMessage(uint messageId, string[] args)
{
var message = new System.Text.StringBuilder(256);
UInt32 flags = Win32.FORMAT_MESSAGE_FROM_SYSTEM;
if (args == null)
flags |= Win32.FORMAT_MESSAGE_IGNORE_INSERTS;
else
flags |= Win32.FORMAT_MESSAGE_ARGUMENT_ARRAY;
var length = Win32.FormatMessage(flags, IntPtr.Zero, messageId, 0, message, 256, args);
if (length > 0)
return message.ToString();
return null;
}
internal static string GetSystemMessage(uint messageId)
{
return FormatMessage(messageId, null);
}
}
}

View file

@ -0,0 +1,234 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AccessDenied" xml:space="preserve">
<value>Access denied.</value>
</data>
<data name="AccountNotFound" xml:space="preserve">
<value>Account {0} was not found.</value>
</data>
<data name="ActionAddGroupMember" xml:space="preserve">
<value>Add member {0}</value>
</data>
<data name="ActionDisableUser" xml:space="preserve">
<value>Disable local user</value>
</data>
<data name="ActionEnableUser" xml:space="preserve">
<value>Enable local user</value>
</data>
<data name="ActionNewGroup" xml:space="preserve">
<value>Create new local group</value>
</data>
<data name="ActionNewUser" xml:space="preserve">
<value>Create new local user</value>
</data>
<data name="ActionRemoveGroup" xml:space="preserve">
<value>Remove local group</value>
</data>
<data name="ActionRemoveGroupMember" xml:space="preserve">
<value>Remove member {0}</value>
</data>
<data name="ActionRemoveUser" xml:space="preserve">
<value>Remove local user</value>
</data>
<data name="ActionRenameGroup" xml:space="preserve">
<value>Rename local group to {0}</value>
</data>
<data name="ActionRenameUser" xml:space="preserve">
<value>Rename local user to {0}</value>
</data>
<data name="ActionSetGroup" xml:space="preserve">
<value>Modify local group</value>
</data>
<data name="ActionSetUser" xml:space="preserve">
<value>Modify local user</value>
</data>
<data name="GroupExists" xml:space="preserve">
<value>Group {0} already exists.</value>
</data>
<data name="GroupHasMembers" xml:space="preserve">
<value>The group {0} still has members.</value>
</data>
<data name="GroupNotFound" xml:space="preserve">
<value>Group {0} was not found.</value>
</data>
<data name="InvalidForGroup" xml:space="preserve">
<value>The operation is not allowed for group {0}.</value>
</data>
<data name="InvalidForUser" xml:space="preserve">
<value>The operation is not allowed for user {0}.</value>
</data>
<data name="InvalidName" xml:space="preserve">
<value>The name {0} is invalid.</value>
</data>
<data name="InvalidParameterPair" xml:space="preserve">
<value>Parameter {0} and parameter {1} may not be used together.</value>
</data>
<data name="InvalidPassword" xml:space="preserve">
<value>Invalid password.</value>
</data>
<data name="LastAdmin" xml:space="preserve">
<value>Cannot remove the last Administrator</value>
</data>
<data name="MemberExists" xml:space="preserve">
<value>{0} is already a member of group {1}.</value>
</data>
<data name="MemberNotFound" xml:space="preserve">
<value>Member {0} was not found in group {1}.</value>
</data>
<data name="MembersPrimaryGroup" xml:space="preserve">
<value>User {0} may not be removed from its primary group.</value>
</data>
<data name="NameInUse" xml:space="preserve">
<value>The name {0} is already in use.</value>
</data>
<data name="ObjectClassGroup" xml:space="preserve">
<value>Group</value>
</data>
<data name="ObjectClassOther" xml:space="preserve">
<value>Other</value>
</data>
<data name="ObjectClassUser" xml:space="preserve">
<value>User</value>
</data>
<data name="PasswordRestriction" xml:space="preserve">
<value>The password cannot be set because a password restriction is in place.</value>
</data>
<data name="PrincipalNotFound" xml:space="preserve">
<value>Principal {0} was not found.</value>
</data>
<data name="RidToSidFailed" xml:space="preserve">
<value>RID {0} was not found.</value>
</data>
<data name="UnspecifiedError" xml:space="preserve">
<value>An unspecified error occurred.</value>
</data>
<data name="UnspecifiedErrorNtStatus" xml:space="preserve">
<value>An unspecified error occurred: status = {0}</value>
</data>
<data name="UnspecifiedErrorWin32Error" xml:space="preserve">
<value>An unspecified error occurred: error code = {0}</value>
</data>
<data name="UserExists" xml:space="preserve">
<value>User {0} already exists.</value>
</data>
<data name="UserNotFound" xml:space="preserve">
<value>User {0} was not found.</value>
</data>
</root>

View file

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Microsoft.PowerShell.Commands.LocalUser</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.LocalUser</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Enabled</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Description</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>Microsoft.PowerShell.Commands.LocalGroup</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.LocalGroup</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Description</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>Microsoft.PowerShell.Commands.LocalPrincipal</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Commands.LocalPrincipal</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>ObjectClass</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>PrincipalSource</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>