Điều này tương tự, nhưng không phải là sự lừa đảo, this question - tuy nhiên, nơi nó tìm kiếm thông tin về cách tham gia máy chủ theo cách thủ công vào miền (và đã được chuyển hướng đúng) Tôi đang tìm trợ giúp với một số mã lập trình tham gia một máy vào miền.Lập trình tham gia máy Windows vào miền AD
Kịch bản là chúng tôi có dịch vụ trình khởi chạy instantiates máy chủ Amazon EC2 Server2008R1, tùy chọn chuyển Tên Máy qua luồng Người dùng-Dữ liệu. Một quá trình được đưa vào ảnh của chúng ta để kiểm tra User-Data cho một tên khi khởi động - Nếu không có thì VM vẫn ở bên ngoài miền Cloud của chúng ta, nhưng nếu tên đó có mặt thì máy sẽ được đổi tên như được chỉ định và tự động kết nối lĩnh vực.
Đây là vấn đề - nếu tôi chạy quy trình này theo cách thủ công bất kỳ lúc nào sau khi bắt đầu bắt đầu, nó hoạt động chính xác như mô tả; tên máy được thay đổi và máy ảo được nối với miền (chúng tôi buộc khởi động lại để thực hiện điều này).
Tuy nhiên, khi chạy dưới dạng tác vụ theo lịch biểu (được kích hoạt khi khởi động), quá trình đổi tên máy sẽ diễn ra như mong đợi, nhưng cuộc gọi tiếp theo là JoinDomainOrWorkgroup
(xem bên dưới) chọn tên máy ngẫu nhiên cũ cho máy ảo bằng EC2 thay vì tên mới nó vừa được gán.
Điều này dẫn đến mã trả về WMI là , chúng tôi nhận được mục nhập sai tên trong kho lưu trữ AD (tên ngẫu nhiên) và máy không được nối với miền. VM sau đó khởi động lại, và bước thứ hai thông qua quá trình khởi động (được kích hoạt bất thường vì có nội dung trong User-Data nhưng máy chưa nằm trong miền) thực hiện tất cả các bước tương tự và thành công.
Có vẻ như tên máy được đặt trong dấu đầu tiên nhưng không được 'hoàn thành' và JoinDomainOrWorkgroup
vẫn thấy tên gốc. Trên đèo thứ hai, tên máy đã được đặt đúng cách và do đó, JoinDomainOrWorkgroup
hoạt động như mong đợi. Khá lý do tại sao quá trình này hoạt động theo cách này trong khi khởi động, nhưng hoạt động hoàn hảo khi chạy thủ công trên một máy ảo đã bắt đầu, là tôi nghĩ rằng vấn đề của vấn đề.
Tôi đã thử chèn thời gian trễ giữa đổi tên và tham gia các bước trong trường hợp cuộc gọi đến JoinDomainOrWorkgroup
xảy ra trước khi đổi tên được hoàn thành sau hậu trường, nhưng điều này đã không giúp - và tôi thực sự không mong đợi , vì toàn bộ quá trình hoạt động hoàn hảo khi chạy thủ công. Vì vậy, nó có thể là một sự kết hợp của một sự khác biệt tinh tế trong trạng thái máy trong quá trình khởi động và một cái gì đó ngớ ngẩn trong mã.
Có thể sử dụng System.Environment.MachineName
trong phương pháp SetDomainMembership
là không thể lưu ý? Nhưng nó stil thất bại ngay cả khi tôi vượt qua tên mới trong như một chuỗi như tôi làm cho SetMachineName
. Vì vậy, tôi stumped.
Dưới đây là mã WMI rằng đổi tên máy:
/// <summary>
/// Set Machine Name
/// </summary>
public static bool SetMachineName(string newName)
{
_lh.Log(LogHandler.LogType.Debug, string.Format("Setting Machine Name to '{0}'...", newName));
// Invoke WMI to populate the machine name
using (ManagementObject wmiObject = new ManagementObject(new ManagementPath("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'")))
{
ManagementBaseObject inputArgs = wmiObject.GetMethodParameters("Rename");
inputArgs["Name"] = newName;
// Set the name
ManagementBaseObject outParams = wmiObject.InvokeMethod("Rename", inputArgs, null);
// Weird WMI shennanigans to get a return code (is there no better way to do this??)
uint ret = (uint)(outParams.Properties["ReturnValue"].Value);
if (ret == 0)
{
// It worked
return true;
}
else
{
// It didn't work
_lh.Log(LogHandler.LogType.Fatal, string.Format("Unable to change Machine Name from '{0}' to '{1}'", System.Environment.MachineName, newName));
return false;
}
}
}
Và đây là mã WMI rằng gia nhập nó vào miền:
/// <summary>
/// Set domain membership
/// </summary>
public static bool SetDomainMembership()
{
_lh.Log(LogHandler.LogType.Debug, string.Format("Setting domain membership of '{0}' to '{1}'...", System.Environment.MachineName, _targetDomain));
// Invoke WMI to join the domain
using (ManagementObject wmiObject = new ManagementObject(new ManagementPath("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'")))
{
try
{
// Obtain in-parameters for the method
ManagementBaseObject inParams = wmiObject.GetMethodParameters("JoinDomainOrWorkgroup");
inParams["Name"] = "*****";
inParams["Password"] = "*****";
inParams["UserName"] = "*****";
inParams["FJoinOptions"] = 3; // Magic number: 3 = join to domain and create computer account
// Execute the method and obtain the return values.
ManagementBaseObject outParams = wmiObject.InvokeMethod("JoinDomainOrWorkgroup", inParams, null);
_lh.Log(LogHandler.LogType.Debug, string.Format("JoinDomainOrWorkgroup return code: '{0}'", outParams["ReturnValue"]));
// Did it work? ** disabled so we restart later even if it fails
//uint ret = (uint)(outParams.Properties["ReturnValue"].Value);
//if (ret != 0)
//{
// // Nope
// _lh.Log(LogHandler.LogType.Fatal, string.Format("JoinDomainOrWorkgroup failed with return code: '{0}'", outParams["ReturnValue"]));
// return false;
//}
return true;
}
catch (ManagementException e)
{
// It didn't work
_lh.Log(LogHandler.LogType.Fatal, string.Format("Unable to join domain '{0}'", _targetDomain), e);
return false;
}
}
}
Xin lỗi nếu mã này có vẻ tâm-numbingly ngu ngốc - Tôi là mới đối với WMI, và điều này phần lớn được cribbed từ các ví dụ tôi đã tìm thấy trên interwebs; nếu có một cách thông minh hơn/neater để làm điều này thì bằng mọi cách chứng minh. Nếu bạn có thể chữa trị vấn đề cùng một lúc, điểm thưởng!
Thông tin khác: lệnh gọi 'SetMachineName' hoạt động, nhưng tên không thay đổi ngay lập tức -' ipconfig' vẫn hiển thị tên cũ và xem Thuộc tính hệ thống hiển thị tên cũ theo sau "(sẽ thay đổi tới XXXXXXX sau khi khởi động lại) ". Nếu 'SetDomainMembership' có một đường dẫn quản lý đến System.Environment.MachineName, thì đây vẫn là tên cũ và không chính xác (dẫn đến một mục AD bị hỏng và một tham gia không thành công). Thay vào đó, nếu tôi chuyển tên mới dưới dạng tham số, cuộc gọi WMI sẽ không thành công với ngoại lệ 'Không tìm thấy', có lẽ do chưa có một máy có tên mới được đặt chắc chắn. –