title: ASP.NET to host Active Directory RSAT powershell scripts--DC hangs up
body: <p>I'm working on making a ASP.NET (C#) app that is basically a gateway for running Powershell scripts for routine admin tasks.  Some of these scripts use the ActiveDirectory RSAT module and I'm finding that some of these cmdlets will not run correctly when invoked via the gateway and the trace seems to imply that the connection to the domain controller is successful, but is then being shut down by the DC.</p>
  
  <p>The following code is an ASP.NET web form that has one text input to specify a username.  Basically, it does the following:</p>
  
  <ul>
  <li>Assumes the identity of the web user (confirmed to be inherited by powershell)</li>
  <li>Creates a powershell runspace and a pipeline within that runspace</li>
  <li>Invokes the Get-ADUser cmdlet and passes the username as the Identity parameter</li>
  <li><p>Confirms success by reading the user's name into an output element on the form.</p>
  
  <pre><code>protected void LookupButton_Click( object sender, EventArgs e ) {
    WindowsImpersonationContext impersonationContext = ((WindowsIdentity)User.Identity).Impersonate();
    Runspace runspace;
    Pipeline pipe;
    try {
      runspace = new_runspace();
      runspace.Open();
      pipe = runspace.CreatePipeline();
      Command cmd = new Command("Get-ADUser");
      cmd.Parameters.Add(new CommandParameter("Identity", text_username.Text));
      pipe.Commands.Add(cmd);
  
      PSObject ps_out = pipe.Invoke().First();
      output.Text = ps_out.Properties["Name"].Value.ToString();
    }
    catch( Exception ex ) {
      error.Text = ex.ToString();
    }
    finally {
      impersonationContext.Undo();
    }
  }
  
  private Runspace new_runspace( ) {
    InitialSessionState init_state = InitialSessionState.CreateDefault();
    init_state.ThreadOptions = PSThreadOptions.UseCurrentThread;
    init_state.ImportPSModule(new[] { "ActiveDirectory" });
    return RunspaceFactory.CreateRunspace(init_state);
  }
  </code></pre></li>
  </ul>
  
  <p>The interesting part is the specific wording in the error message exposed in the catch block (emphasis mine):</p>
  
  <blockquote>
    <p>System.Management.Automation.CmdletInvocationException: Unable to
    contact the server. This may be because this server does not exist, it
    is currently down, or it does not have the Active Directory Web
    Services running. --->
    Microsoft.ActiveDirectory.Management.ADServerDownException: Unable to
    contact the server. This may be because this server does not exist, it
    is currently down, or it does not have the Active Directory Web
    Services running. ---> System.ServiceModel.CommunicationException: The
    socket connection was aborted. This could be caused by an error
    processing your message or a receive timeout being exceeded by the
    remote host, or an underlying network resource issue. Local socket
    timeout was '00:01:59.6870000'. ---> System.IO.IOException: The read
    operation failed, see inner exception. --->
    System.ServiceModel.CommunicationException: The socket connection was
    aborted. This could be caused by an error processing your message or a
    receive timeout being exceeded by the remote host, or an underlying
    network resource issue. Local socket timeout was '00:01:59.6870000'.
    ---> <strong>System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host</strong></p>
  </blockquote>
  
  <p>The upper-level exceptions suggest there was a timeout, but there was no timeout indicated by the lower exceptions (and it took only a few seconds to return from the command).  In cases where the server is not reachable, the lowest-level exception message says as much, but this specific wording is making me think there is some kind of authentication (or other security) problem at work here.</p>
  
  <p>UPDATE Feb 19, 2013:
  When using the impersonation method described <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158" rel="nofollow">here</a>, the script runs as expected.  This is making me think that the issue may be that the WindowsIdentity object provided by Windows authentication is perhaps unsuitable for a script that essentially makes RPC calls against AD.  Unfortunately, it's not really desirable for me to abandon windows auth because I would have to handle the users' passwords in my application code (and that's not a responsibility that I want).</p>
  
  <p>I haven't been able to find any documentation about what exactly windows auth is doing or what kind of impersonation is allowed to result from its use.  Is it possible to do this while using windows auth or am I going to have to require the user to give me their password?</p>