我正在尝试实现一个在网页上显示一些 ActiveDirectory 信息的功能,但是当我尝试显示某些信息(用户的经理)时,由于某种原因,它开始向我抛出以下错误(当它没有完成时)过去的事。任何人都可以解释这里发生了什么或建议修复吗?
在 PowerShell 的 using() block 中处理后,我没有向 StringBuilder 写入任何内容,所以我不知道为什么当 manager_name 字符串调用 GetManager 函数时突然抛出异常,我知道该函数会返回正确的值基于 VisualStudio 的调试工具,当它滚动到第 752 行时显示正确的值
PrintADInfo_displayresults.InnerHtml = html_results;
这是在处理所有对象并返回函数外部之前。奇怪的是,当将 manager_name 设置为空字符串或只是“test”时,代码将运行良好,但使用 GetUsersManager 函数将导致引发异常。
您将在下面找到相关方法和错误文本。
错误文本
System.ObjectDisposedException: Cannot write to a closed TextWriter. at System.IO.__Error.WriterClosed() at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) at System.IO.StreamWriter.Flush() at System.Management.Automation.Host.TranscriptionOption.Dispose() at System.Management.Automation.Host.PSHostUserInterface.StopAllTranscribing() at System.Management.Automation.Runspaces.LocalRunspace.DoCloseHelper() at System.Management.Automation.Runspaces.LocalRunspace.CloseHelper(Boolean syncCall) at System.Management.Automation.Runspaces.RunspaceBase.CoreClose(Boolean syncCall) at System.Management.Automation.Runspaces.LocalRunspace.Close() at System.Management.Automation.Runspaces.LocalRunspace.Dispose(Boolean disposing) at System.Management.Automation.PowerShell.Dispose(Boolean disposing) at System.Management.Automation.PowerShell.Dispose() at _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 ps = PowerShell.Create()) {}
之外> 阻止。你在 using 里面有一个 using,我认为你的对象被过早地处理了。
关于c# - 使用某些字符串时关闭 TextWriter 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46610211/