【发布时间】:2017-10-07 04:57:07
【问题描述】:
我正在尝试实现一个在网页上显示一些 ActiveDirectory 信息的功能,但是当我尝试显示某些信息(用户的管理器)时,由于某种原因它开始向我抛出以下错误,但它还没有完成那个过去。谁能解释这里发生了什么或提出修复建议?
在 PowerShell 的 using() 块期间处置后,我没有向 StringBuilder 写入任何内容,所以我不知道为什么当 manager_name 字符串调用 GetManager 函数时突然抛出异常,我知道该函数返回基于 VisualStudio 的调试工具的正确值,当它滚动到第 752 行时显示正确的值
PrintADInfo_displayresults.InnerHtml = html_results;
就在处理所有对象并返回函数外部之前。奇怪的是,当将 manager_name 设置为空字符串或只是“test”时,代码会运行良好,但使用 GetUsersManager 函数会导致异常触发。
您将在下面找到相关方法和错误文本。
错误文本
System.ObjectDisposedException:无法写入已关闭的 TextWriter。 在 System.IO.__Error.WriterClosed() 在 System.IO.StreamWriter.Flush(布尔flushStream,布尔 flushEncoder) 在 System.IO.StreamWriter.Flush() 在 System.Management.Automation.Host.TranscriptionOption.Dispose() 在 System.Management.Automation.Host.PSHostUserInterface.StopAllTranscribing() 在 System.Management.Automation.Runspaces.LocalRunspace.DoCloseHelper() 在 System.Management.Automation.Runspaces.LocalRunspace.CloseHelper(布尔 同步呼叫)在 System.Management.Automation.Runspaces.RunspaceBase.CoreClose(布尔 同步呼叫)在 System.Management.Automation.Runspaces.LocalRunspace.Close() 在 System.Management.Automation.Runspaces.LocalRunspace.Dispose(布尔 处置)在 System.Management.Automation.PowerShell.Dispose(布尔 处置)在 System.Management.Automation.PowerShell.Dispose() 在 _Default.PrintADInfo(String username) in h:\Visual Studio 2015\WebSites\WebSite2\Default.aspx.cs:line 753
private void PrintADInfo(string username)
{
//Print AD information for given username
AD_PrintADInfoDiv.Attributes["style"] = "display:block"; //Move to the account display
try
{
using (PowerShell ps = PowerShell.Create())
{
var sb = new StringBuilder();
sb.Append("Grabbing AD info for " + username.ToUpper() + " ...");
//Run command Get-ADUser to get user information from AD
//Command Information -> https://technet.microsoft.com/en-us/library/hh852208(v=wps.630).aspx
// Use -Properties to get specific proprties we want, then use Select to ignore some additional ones
ps.AddScript("Get-ADUser -Properties SamAccountName, CN, EmailAddress, Title, Department, Manager, OfficePhone, Mobile, PasswordLastSet, EmployeeID, co, physicalDeliveryOfficeName " + username + " | select SamAccountName, CN, Title, Department, EmailAddress, Manager, OfficePhone, Mobile, PasswordLastSet, EmployeeID, co, physicalDeliveryOfficeName | ConvertTo-Html");
Collection<PSObject> psOutput = ps.Invoke();
//Add user informtion to StringBuilder for output
foreach (PSObject p in psOutput)
{
sb.Append(p.ToString());
}
//Evil regex hacking
//Quotes are doubled to account for C# literals
//https://stackoverflow.com/questions/9289357/javascript-regular-expression-for-dn
string pattern = @"(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*|""(?:[^\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*"")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*|""(?:[^\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*""))*(?:,(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*|""(?:[^\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*"")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*|""(?:[^\\""]|\\[,=\+<>#;\\""]|\\[\dA-Fa-f]{2})*""))*)*";
Regex rgx = new Regex(pattern);
//Replace the user's manager field that's normally in CN format to NTID
string manager_name = GetUsersManager(username);
//string manager_name = ""; // <-- Making the manager blank runs fine
string html_results = rgx.Replace(sb.ToString(), manager_name);
PrintADInfo_displayresults.InnerHtml = html_results;
return; // <--- Error gets thrown here
}
}
catch (Exception e)
{
PrintADInfo_displayresults.InnerHtml = "Exception caught:" + e;
return;
}
}
private string GetUsersManager(string username)
{
//Returns the NTID of the user's manager, instead of the CN
string manager_name = "";
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript("(Get-ADUser (Get-ADUser " + username + " -Properties manager).manager).samaccountName");
Collection<PSObject> psOutput = ps.Invoke();
foreach (PSObject p in psOutput)
{
manager_name = manager_name + p.ToString();
}
}
return manager_name;
}
【问题讨论】:
-
如果您从
string manager_name = GetUsersManager(username);开始,在using (Powershell...)块之外,通过提供示例用户名,它是否有效?例如。将username设置为有效的用户名,看看是否可以从那里调用它?我认为您的问题可能是您实际上在另一个块中有一个 using Powershell 块。 -
好像已经搞定了,谢谢!将 GetUsersManager() 调用移动到 try() 内部,但仍然在 using() 块之前似乎已经解决了问题。
标签: c# .net powershell