简体   繁体   中英

calling remote powershell script with different credential in C#

I am trying to call a powershell script file in the remote server which basically get a parameter and create a shared drive using that parameter. The credentials are all correct but whenever I run this, it returns this error:

When the runspace is set to use the current thread the apartment state in the invocation settings must match that of the current thread

It is something to do with the credential as once I removed the credential, it runs fine on my local machine. Can anyone shed light on this? Thanks,

The following is my C# script:

PSCredential credential = new PSCredential(_exchangeUsername, password);

// Set exchange connection details
WSManConnectionInfo connectionInfo = new WSManConnectionInfo((new Uri(_exchangeConnectionUri)), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);

connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Default;
string cmdArg = @"\\servername\\c$\\scripts\\HomeDrive.ps1 "+userID;

using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
    try
    {
        runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;
        runspace.ApartmentState = System.Threading.ApartmentState.STA;
        runspace.Open();

        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(cmdArg);
        pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
        Collection<PSObject> results = pipeline.Invoke();
        var error = pipeline.Error.ReadToEnd();
        // Check for powershell command errors
        if (error.Count > 0)
        {
            throw new Exception(errorMessage.ToString());
        }

        // Check for powershell command results
        if (results.Count <= 0)
        {
            throw new Exception(String.Format("Error. No results after command invoked.", userID));
        }
        runspace.Close();
    }
    catch (Exception ex)
    {
        runspace.Close();
        throw new ApplicationException(String.Format("Error ", userID), ex);
    }
}

I think you are using the wrong constructor overload WSManConnectionInfo. you can check the Credential property on the object after you create it, but before you pass it to create the runspace.

Here is a snippet from my own code where this is working fine, where I am using the most verbose of the constructors (I think)

#region create WSmanconnection
//Create the PowerShell Remoting WinRM WSMan connection object so we can connect to the remote machine, only using credentials if Not Implicitly negotiated.
var ci = new WSManConnectionInfo(
    useSSL, trueFQDN , port, appName, shellUri,
    (authenticationMechanism == AuthenticationMechanism.NegotiateWithImplicitCredential) ? null : credential)
    {
        AuthenticationMechanism = authenticationMechanism,
        OpenTimeout = openTimeoutMinutes * 60 * 1000,
        OperationTimeout = operationTimeoutMinutes * 60 * 1000,
        IdleTimeout = idleTimeOut * 60 * 1000
    };
#endregion

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM