Я создаю приложение, которое взаимодействует с Active Directory, используя System.Management.Automation (не используя службы каталогов, поскольку в настоящее время не знаком с этой библиотекой и изучаю ее). Чтобы обновить членство в группе для группы в активном каталоге, я создаю объект JSON в своем представлении и вызываю функцию для передачи объекта и URI от внешнего интерфейса к внутреннему через функцию в моем контроллере.
Основная идея состоит в том, чтобы разрешить массовое удаление членов группы AD, передав объект JSON в качестве параметра сценарию оболочки, который будет выполняться в экземпляре PowerShell, созданном в функции. Я использую вызов .ajax для вызова функции контроллера и передачи сгенерированного объекта JSON в качестве аргумента вместе с текущим URI. Функция shell.commands.AddParameter() принимает аргумент только в строковом формате. Итак, я преобразовал его с помощью ToString() и преобразовал в JSON в сценарии PowerShell. Я передаю URL-адрес из кода позади, поскольку URL-адрес может быть изменен. Я не получаю никаких ошибок. Однако я также не вижу никаких обновлений в членстве в AD. Объект Json создается из таблицы HTML.
Мой сценарий оболочки
param($objMemberUpdate, $uri)
$body = $objMemberUpdate | ConvertTo-JSON
Invoke-WebRequest -Uri $uri -Method Post -Body $objMemberUpdate
Моя функция контроллера для вызова экземпляра PowerShell и выполнения файла сценария оболочки из указанного места.
private string UpdateMemberList(JsonResult objMemberUpdate)
{
var uri = HttpContext.Request.Url.AbsoluteUri;
var shell = PowerShell.Create();
shell.Commands.AddCommand(AppDomain.CurrentDomain.BaseDirectory + "Shell\\Set-ADGroupMembership.ps1").AddParameter(objMemberUpdate.ToString(), uri);
var results = shell.Invoke();
shell.Dispose();
return results.ToString();
}
Вызов Ajax, который я вызываю при нажатии кнопки на моей HTML-странице.
//Make Array Object to pass in the API For Membership Update
$("#btnUpdate").click(function () {
var RemoveMembers = [];
var RemoveAfter = [];
var MemberUpdate = {};
var GroupGUID = "";
$("table [id*=ddlReqdAdjustment]").each(function () {
if ($(this).val() != "Keep") {
GroupGUID = $(this).parent().parent().children().eq(4)[0].innerText;
var date = $(this).parent().parent().children().eq(8)[0].firstElementChild.value;
var ObjectGUID = $(this).parent().parent().children().eq(3)[0].innerText + "@@" + $('#ddlDirectory').val();
if ($(this).val() == "Remove") {
var format = ObjectGUID;
RemoveMembers.push(format);
} else {
var format = date + "|" + ObjectGUID;
RemoveAfter.push(format);
}
}
});
MemberUpdate = {
"Directory": $('#ddlDirectory').val(),
"Group": GroupGUID,
"Remove": RemoveMembers,
"RemoveAfter": RemoveAfter,
"ResultFormat": "json",
"OnBehalfOf": "11112201"
};
console.info(MemberUpdate);
$.ajax({
type: "POST",
url: "/Group/UpdateMemberList",
data: { objMemberUpdate: MemberUpdate },
success: function (response) {
alert(response.message);
}
});
Предполагается, что выбранный член в таблице будет удален из группы, чей GroupGUID (атрибут ObjectGUID в AD) упоминается в AD. Однако время компиляции или ошибка времени выполнения не возникают, и даже какие-либо изменения не отражаются, и я думаю, что это должно быть связано с проблемой с моим объектом JSON?





Первая проблема здесь:
private string UpdateMemberList(JsonResult objMemberUpdate)
Класс JsonResult предназначен для использования в ответе (возвращенном из действия контроллера), а не в качестве параметра.
Вместо этого создайте свой собственный класс с нужными вам свойствами и используйте его. Что-то вроде этого:
public class MemberUpdate {
public string Directory { get; set; }
public Guid Group { get; set; }
public List<string> Remove { get; set; }
public List<string> RemoveAfter { get; set; }
public string ResultFormat { get; set; }
public string OnBehalfOf { get; set; }
}
И тогда ваше определение действия будет таким:
public string UpdateMemberList(MemberUpdate objMemberUpdate)
ASP.NET автоматически десериализует JSON, отправленный из браузера, в экземпляр вашего класса.
Тем не менее, я хочу обратиться к тому, что вы сказали:
using System.Management.Automation (Not using Directory Services because currently new to that library and learning it)
Независимо от того, как вы это реализуете, вам придется чему-то научиться. Вы можете также учиться лучше :)
Вызов PowerShell из C# ужасен. Я делал это несколько раз, и это всегда вызывает у меня головную боль. Это означает больше предварительных условий (вам нужен установленный модуль AD), больше вещей, которые нужно сломать, и просто более медленная производительность (поскольку вы общаетесь с отдельным процессом powershell.exe).
В Интернете есть множество примеров того, как добавлять и удалять участников из групп на C#, например здесь — будет работать как код в самом вопросе (с использованием System.DirectoryServices), так и код в принятом ответе (с использованием System.DirectoryServices.AccountManagement). Но использование System.DirectoryServices напрямую, хотя и немного сложнее, всегда работает быстрее, чем System.DirectoryServices.AccountManagement. (я говорил почему в статья, которую я написал).
Да, это правда. Если сделать ваше действие приватным, оно просто ничего не сделает - я этого не уловил (но это случалось со мной раньше).
Исключение, которое вы получаете сейчас, является причиной, по которой я рекомендую вам не вызывать PowerShell из С# :)
Итак, я понимаю, что причина этого в том, что мой объект JSON дает нулевые значения, но вызов ajax уже передает значения аргументу. imgur.com/LDdbjTW вот что я получаю.
О, я думаю, это из-за этого в вашем JavaScript: data: { objMemberUpdate: MemberUpdate }. Измените это на просто data: MemberUpdate
Да, конечно, Габриэль, спасибо за ответ, а также еще одна проблема, которую я обнаружил, заключалась в том, что я использовал частную для функции, поэтому она не вызывалась, и когда я сделал ее общедоступной, я получил следующую ошибку синтаксического анализа: System.Management.Automation. ParseException HResult=0x80131501 Сообщение=Системная ошибка. Source=<Невозможно оценить источник исключения> StackTrace: <Невозможно оценить трассировку стека исключений>