public static string OfflineDomainJoinProvision(string ComputerSamAccountName, string OrganisationalUnit, ref ADMachineAccount MachineAccount, out string DiagnosticInformation) { var domain = Context.GetDomainFromDistinguishedName(OrganisationalUnit); var writableDomainController = domain.GetAvailableDomainController(RequireWritable: true); return writableDomainController.OfflineDomainJoinProvision(ComputerSamAccountName, OrganisationalUnit, ref MachineAccount, out DiagnosticInformation); }
public string OfflineDomainJoinProvision(string ComputerSamAccountName, string OrganisationalUnit, ref ADMachineAccount MachineAccount, out string DiagnosticInformation) { if (MachineAccount != null && MachineAccount.IsCriticalSystemObject) throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", MachineAccount.DistinguishedName)); if (!this.IsWritable) throw new InvalidOperationException(string.Format("The domain controller [{0}] is not writable. This action (Offline Domain Join Provision) requires a writable domain controller.", this.Name)); StringBuilder diagnosticInfo = new StringBuilder(); string DJoinResult = null; if (!string.IsNullOrWhiteSpace(ComputerSamAccountName)) ComputerSamAccountName = ComputerSamAccountName.TrimEnd('$'); if (!string.IsNullOrWhiteSpace(ComputerSamAccountName) && ComputerSamAccountName.Contains('\\')) ComputerSamAccountName = ComputerSamAccountName.Substring(ComputerSamAccountName.IndexOf('\\') + 1); if (string.IsNullOrWhiteSpace(ComputerSamAccountName) || ComputerSamAccountName.Length > 24) throw new System.ArgumentException("Invalid Computer Name; > 0 and <= 24", "ComputerName"); // Ensure Specified OU Exists if (!string.IsNullOrEmpty(OrganisationalUnit)) { try { using (var deOU = this.RetrieveDirectoryEntry(OrganisationalUnit, new string[] { "distinguishedName" })) { if (deOU == null) throw new Exception(string.Format("OU's Directory Entry couldn't be found at [{0}]", OrganisationalUnit)); } } catch (Exception ex) { throw new ArgumentException(string.Format("An error occurred while trying to locate the specified OU: {0}", OrganisationalUnit), "OrganisationalUnit", ex); } } if (MachineAccount != null) MachineAccount.DeleteAccount(this); string tempFileName = System.IO.Path.GetTempFileName(); string argumentOU = (!string.IsNullOrWhiteSpace(OrganisationalUnit)) ? string.Format(" /MACHINEOU \"{0}\"", OrganisationalUnit) : string.Empty; string arguments = string.Format("/PROVISION /DOMAIN \"{0}\" /DCNAME \"{1}\" /MACHINE \"{2}\"{3} /REUSE /SAVEFILE \"{4}\"", this.Domain.Name, this.Name, ComputerSamAccountName, argumentOU, tempFileName ); ProcessStartInfo commandStarter = new ProcessStartInfo("DJOIN.EXE", arguments) { CreateNoWindow = true, ErrorDialog = false, LoadUserProfile = false, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }; diagnosticInfo.AppendFormat("{0} {1}", "DJOIN.EXE", arguments); diagnosticInfo.AppendLine(); string stdOutput; string stdError; using (Process commandProc = Process.Start(commandStarter)) { commandProc.WaitForExit(20000); stdOutput = commandProc.StandardOutput.ReadToEnd(); stdError = commandProc.StandardError.ReadToEnd(); } if (!string.IsNullOrWhiteSpace(stdOutput)) diagnosticInfo.AppendLine(stdOutput); if (!string.IsNullOrWhiteSpace(stdError)) diagnosticInfo.AppendLine(stdError); if (System.IO.File.Exists(tempFileName)) { DJoinResult = System.Convert.ToBase64String(System.IO.File.ReadAllBytes(tempFileName)); System.IO.File.Delete(tempFileName); } if (string.IsNullOrWhiteSpace(DJoinResult)) throw new System.InvalidOperationException(string.Format("Domain Join Unsuccessful{0}Error: {1}{0}Output: {2}", System.Environment.NewLine, stdError, stdOutput)); DiagnosticInformation = diagnosticInfo.ToString(); // Reload Machine Account MachineAccount = this.RetrieveADMachineAccount(string.Format(@"{0}\{1}", this.Domain.NetBiosName, ComputerSamAccountName), (MachineAccount == null ? null : MachineAccount.LoadedProperties.Keys.ToArray())); return DJoinResult; }