mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2025-05-05 09:18:41 +00:00
271 lines
9.6 KiB
C#
271 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Management.Automation;
|
|
using System.Security.Principal;
|
|
using DSInternals.Common.Data;
|
|
using DSInternals.PowerShell.Properties;
|
|
using DSInternals.Replication;
|
|
using DSInternals.Replication.Model;
|
|
|
|
namespace DSInternals.PowerShell.Commands
|
|
{
|
|
[Cmdlet(VerbsCommon.Get, "ADReplAccount")]
|
|
[OutputType(typeof(DSAccount))]
|
|
public class GetADReplAccountCommand : ADReplPrincipalCommandBase
|
|
{
|
|
#region Constants
|
|
protected const string ParameterSetAll = "All";
|
|
protected DSAccount.AccountType accountTypes = DSAccount.AccountType.Default;
|
|
protected DSAccount.CredType credTypes = DSAccount.CredType.All;
|
|
protected ulong counter = 0;
|
|
#endregion Constants
|
|
|
|
#region Parameters
|
|
[Parameter(Mandatory = true, ParameterSetName = ParameterSetAll)]
|
|
[Alias("AllAccounts", "ReturnAllAccounts")]
|
|
public SwitchParameter All
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Parameter(Mandatory = false, ParameterSetName = ParameterSetAll)]
|
|
[ValidateNotNullOrEmpty]
|
|
[Alias("NC", "DomainNC", "DomainNamingContext")]
|
|
public string NamingContext
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Parameter(Mandatory = false)]
|
|
public SwitchParameter Extra
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Parameter(Mandatory = false)]
|
|
public string[] AccountTypes
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Parameter(Mandatory = false)]
|
|
public string[] CredTypes
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[Parameter(Mandatory = false)]
|
|
public ulong Count
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
#endregion Parameters
|
|
|
|
#region Cmdlet Overrides
|
|
protected override void ProcessRecord()
|
|
{
|
|
if (AccountTypes != null && AccountTypes.Length > 0)
|
|
{
|
|
accountTypes = DSAccount.GetAccountType(AccountTypes);
|
|
}
|
|
|
|
if (CredTypes != null && CredTypes.Length > 0)
|
|
{
|
|
credTypes = DSAccount.GetCredType(CredTypes);
|
|
}
|
|
|
|
if (Count > 0)
|
|
{
|
|
counter = Count;
|
|
}
|
|
|
|
if (this.ParameterSetName == ParameterSetAll)
|
|
{
|
|
this.ReturnAllAccounts();
|
|
}
|
|
else
|
|
{
|
|
this.ReturnSingleAccount();
|
|
}
|
|
}
|
|
#endregion Cmdlet Overrides
|
|
|
|
#region Helper Methods
|
|
|
|
protected void ReturnAllAccounts()
|
|
{
|
|
List<BitlockerRecoveryInfo> bitlockerRecoveryInfoList = null;
|
|
// Write the initial progress
|
|
// TODO: Extract strings as resources
|
|
var progress = new ProgressRecord(1, "Replication", "Replicating Active Directory objects.");
|
|
ulong accountCount = 0;
|
|
|
|
progress.PercentComplete = 0;
|
|
this.WriteProgress(progress);
|
|
|
|
// Update the progress after each replication cycle
|
|
ReplicationProgressHandler progressReporter = (ReplicationCookie cookie, int processedObjectCount, int totalObjectCount) =>
|
|
{
|
|
int percentComplete = (int)(((double)processedObjectCount / (double)totalObjectCount) * 100);
|
|
// AD's object count estimate is sometimes lower than the actual count, so we cap the value to 100%.
|
|
progress.PercentComplete = Math.Min(percentComplete, 100);
|
|
this.WriteProgress(progress);
|
|
};
|
|
|
|
// Automatically infer domain name if no value is provided
|
|
string domainNamingContext = this.NamingContext ?? this.ReplicationClient.DomainNamingContext;
|
|
|
|
if (accountTypes.HasFlag(DSAccount.AccountType.Default) || accountTypes.HasFlag(DSAccount.AccountType.All) || accountTypes.HasFlag(DSAccount.AccountType.Computer))
|
|
{
|
|
if (credTypes.HasFlag(DSAccount.CredType.All) || credTypes.HasFlag(DSAccount.CredType.Bitlocker))
|
|
{
|
|
// dump msFVE-RecoveryInformation
|
|
bitlockerRecoveryInfoList = new List<BitlockerRecoveryInfo>();
|
|
|
|
foreach (var bl in this.ReplicationClient.GetBitlockerRecoveryData(domainNamingContext, null))
|
|
{
|
|
if (bl == null)
|
|
continue;
|
|
|
|
bitlockerRecoveryInfoList.Add(bl);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Replicate all accounts
|
|
foreach (var account in this.ReplicationClient.GetAccounts(domainNamingContext, progressReporter, Extra.IsPresent, accountTypes, credTypes))
|
|
{
|
|
if (account == null)
|
|
continue;
|
|
|
|
if (bitlockerRecoveryInfoList != null)
|
|
{
|
|
List<BitlockerRecoveryInfo> bl_curUser = bitlockerRecoveryInfoList.FindAll(
|
|
delegate(BitlockerRecoveryInfo br)
|
|
{
|
|
return br.OwnerDN.Equals(account.DistinguishedName);
|
|
}
|
|
);
|
|
|
|
int i = (bl_curUser != null) ? bl_curUser.Count : 0;
|
|
|
|
if (i > 0)
|
|
{
|
|
BitlockerRecoveryInfo[] bitlockerRecoveryData = new BitlockerRecoveryInfo[i];
|
|
|
|
bl_curUser.ForEach(
|
|
delegate(BitlockerRecoveryInfo br)
|
|
{
|
|
bitlockerRecoveryData[--i] = br;
|
|
}
|
|
);
|
|
|
|
account.BitlockerInfo = bitlockerRecoveryData;
|
|
}
|
|
}
|
|
|
|
this.WriteObject(account);
|
|
|
|
if (counter > 0 && ++accountCount >= counter)
|
|
break;
|
|
}
|
|
|
|
// Write progress completed
|
|
progress.RecordType = ProgressRecordType.Completed;
|
|
this.WriteProgress(progress);
|
|
}
|
|
|
|
protected void ReturnSingleAccount()
|
|
{
|
|
DSAccount account = null;
|
|
|
|
switch (this.ParameterSetName)
|
|
{
|
|
case ParameterSetByDN:
|
|
account = this.ReplicationClient.GetAccount(this.DistinguishedName, Extra.IsPresent, credTypes);
|
|
break;
|
|
|
|
case ParameterSetByName:
|
|
var accountName = new NTAccount(this.Domain, this.SamAccountName);
|
|
account = this.ReplicationClient.GetAccount(accountName, Extra.IsPresent, credTypes);
|
|
break;
|
|
|
|
case ParameterSetByGuid:
|
|
account = this.ReplicationClient.GetAccount(this.ObjectGuid, Extra.IsPresent, credTypes);
|
|
break;
|
|
|
|
case ParameterSetBySid:
|
|
account = this.ReplicationClient.GetAccount(this.ObjectSid, Extra.IsPresent, credTypes);
|
|
break;
|
|
|
|
case ParameterSetByUPN:
|
|
var upn = new NTAccount(this.UserPrincipalName);
|
|
account = this.ReplicationClient.GetAccount(upn, Extra.IsPresent, credTypes);
|
|
break;
|
|
|
|
default:
|
|
// This should never happen:
|
|
throw new PSInvalidOperationException(Resources.InvalidParameterSetMessage);
|
|
}
|
|
|
|
if (account != null)
|
|
{
|
|
if (account.SamAccountType.HasFlag(SamAccountType.Computer))
|
|
{
|
|
if (credTypes.HasFlag(DSAccount.CredType.All) || credTypes.HasFlag(DSAccount.CredType.Bitlocker))
|
|
{
|
|
// Automatically infer domain name if no value is provided
|
|
string domainNamingContext = this.NamingContext ?? this.ReplicationClient.DomainNamingContext;
|
|
|
|
// dump msFVE-RecoveryInformation
|
|
List<BitlockerRecoveryInfo> bitlockerRecoveryInfoList = new List<BitlockerRecoveryInfo>();
|
|
|
|
foreach (var bl in this.ReplicationClient.GetBitlockerRecoveryData(domainNamingContext, null))
|
|
{
|
|
if (bl == null)
|
|
continue;
|
|
|
|
bitlockerRecoveryInfoList.Add(bl);
|
|
}
|
|
|
|
if (bitlockerRecoveryInfoList != null)
|
|
{
|
|
List<BitlockerRecoveryInfo> bl_curUser = bitlockerRecoveryInfoList.FindAll(
|
|
delegate (BitlockerRecoveryInfo br)
|
|
{
|
|
return br.OwnerDN.Equals(account.DistinguishedName);
|
|
}
|
|
);
|
|
|
|
int i = (bl_curUser != null) ? bl_curUser.Count : 0;
|
|
|
|
if (i > 0)
|
|
{
|
|
BitlockerRecoveryInfo[] bitlockerRecoveryData = new BitlockerRecoveryInfo[i];
|
|
|
|
bl_curUser.ForEach(
|
|
delegate (BitlockerRecoveryInfo br)
|
|
{
|
|
bitlockerRecoveryData[--i] = br;
|
|
}
|
|
);
|
|
|
|
account.BitlockerInfo = bitlockerRecoveryData;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.WriteObject(account);
|
|
}
|
|
#endregion Helper Methods
|
|
}
|
|
}
|