DSInternals/Src/DSInternals.PowerShell/Commands/Replication/GetADReplAccountCommand.cs
Gabriele Gristina a99b06de13 v0.9
2021-09-04 00:17:58 +02:00

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
}
}