使用某些字符串时关闭TextWriter异常

时间:2017-10-06 16:31:57

标签: c# .net powershell

我试图实现一个在网页上显示一些ActiveDirectory信息的功能,但是当我因某种原因尝试显示某些信息(用户的管理员)时,它开始向我抛出以下错误在过去没有做过的时候。任何人都可以解释这里发生的事情或建议修复吗?

我在PowerShell的using()块处理后没有写任何东西到StringBuilder,所以我不知道为什么当manager_name字符串调用GetManager函数时,这突然抛出异常,我know基于VisualStudio的调试工具返回正确的值,当它进入第752行时显示正确的值

  

PrintADInfo_displayresults.InnerHtml = html_results;

就在处理所有对象之前,并返回到函数外部。奇怪的是,当将manager_name设置为空字符串或只是" test"时,代码将运行良好,但使用GetUsersManager函数将导致触发异常。

您将在下面找到有问题的方法和错误文本。

错误文字

  

System.ObjectDisposedException:无法写入已关闭的TextWriter。   在System.IO .__ Error.WriterClosed()at   System.IO.StreamWriter.Flush(Boolean flushStream,Boolean   flushEncoder在System.IO.StreamWriter.Flush()处于   System.Management.Automation.Host.TranscriptionOption.Dispose()at   System.Management.Automation.Host.PSHostUserInterface.StopAllTranscribing()   在   System.Management.Automation.Runspaces.LocalRunspace.DoCloseHelper()   在   System.Management.Automation.Runspaces.LocalRunspace.CloseHelper(布尔   syncCall)at   System.Management.Automation.Runspaces.RunspaceBase.CoreClose(布尔   syncCall)at   System.Management.Automation.Runspaces.LocalRunspace.Close()at   System.Management.Automation.Runspaces.LocalRunspace.Dispose(布尔   处理System.Management.Automation.PowerShell.Dispose(布尔值。)   处理)在System.Management.Automation.PowerShell.Dispose()处于   _Default.PrintADInfo(字符串用户名)在h:\ Visual Studio 2015 \ WebSites \ WebSite2 \ Default.aspx.cs:第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;
}

1 个答案:

答案 0 :(得分:2)

我认为您需要将string manager_name = GetUsersManager(username);的呼叫转移到using (PowerShell ps = PowerShell.Create()) {}阻止之外。你在使用中有一个使用,我认为你的对象是过早处置的。

相关问题