I have several .net-based web apps running powershell code with various snapins. Currently because powershell was apparently thought of as a command-line tool, to run under a MS web app, an application pool must be configured with domain credentials of a 'service account' so that the underlying providers run under credentials. With the VMWare VI Toolkit installed and the 'service account' configured on the pool that has rights in vCenter, it will not work on a production web server (it does work on the dev server because the web browser is running on the same machine as the web server and credentials are passed through) even though credentials are being specified in the 'connect-viserver' line with -user userid -password password and the account is a local admin on the web server.
This configuration (service account that has rights in the target powershell object and is a local admin on the web server) works fine except with the VI Toolkit powershell providers.
Another oddity is that if the pool is configured with MY domain account, it will work, and if the credentials of the 'service account' are specified in the 'connect-viserver' line, the code returns only what that account has rights to see. If I specify MY credentials in the 'connect-viserver' line it returns what I have rights to see. I can run the commands fine manually from the command-prompt when logged into the web server as the service account.
There are no errors generated in the eventlog, web logs, or anywhere else on the server. The 'providers' and 'engine' all startup fine in the powershell eventlog, then stop. The code appears to not run the connect-viserver line correctly, becasue the error trapped by the web code errors on the line 'get-vm' which states: "Get-VM You are not currently connected to any servers. Please connect first using Connect-VIServer or one of its aliases"
Here is the web code:
Public Shared Sub GetVMs(ByVal Controller As String, ByRef resultObject As System.Collections.ObjectModel.Collection(Of System.Management.Automation.PSObject), ByRef errtxt As String, ByVal IDToUse As String, ByVal PasswordToUse As String)
Dim myRunSpace As Runspace
Dim rsConfig As RunspaceConfiguration = RunspaceConfiguration.Create()
Dim snapInException As New PSSnapInException
Dim info As PSSnapInInfo
info = rsConfig.AddPSSnapIn("VMware.VimAutomation.Core", snapInException)
myRunSpace = RunspaceFactory.CreateRunspace(rsConfig)
myRunSpace.Open()
Dim enumD As New StringBuilder
enumD.AppendLine("$visvr = Connect-VIServer -Server " & Controller & " -User " & IDToUse & " -Password " & PasswordToUse)
enumD.AppendLine("get-vm")
Dim pipe As Pipeline = myRunSpace.CreatePipeline()
pipe.Commands.AddScript(enumD.ToString)
Try
resultObject = pipe.Invoke()
Catch ex As Exception
errtxt = ex.InnerException.Message.ToString & "<BR>" & ex.TargetSite.ToString & "<BR>" & ex.Source.ToString
End Try
myRunSpace.Close()
End Sub
The way you are passing the parameter and using the AddLine is might be creating the problem. AddLine function is adding the endline character at the end of the line after the password and the next cmdlet Get-VM is not being considered as a cmdlets and throwing the error.
The AddScript function is used to add the next cmdlet while in your case you are trying to separate the cmdlet by using AddLine which is incorrect. AddScript method should be used to add the next cmdlet after the previous cmdlet by calling the Command object.
We made the modification in your code for C# and ran it successfully. I would request to you that please modify the below in VB.Net and test it at your end.
System.Management.Automation.Runspaces.Runspace myRunSpace;
System.Management.Automation.Runspaces.PSSnapInException snapInException = new System.Management.Automation.Runspaces.PSSnapInException();
System.Management.Automation.Runspaces.RunspaceConfiguration rsConfig = System.Management.Automation.Runspaces.RunspaceConfiguration.Create();
System.Management.Automation.PSSnapInInfo info = rsConfig.AddPSSnapIn("VMware.VimAutomation.Core", out snapInException);
myRunSpace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open();
System.Management.Automation.Runspaces.Pipeline Pipe = myRunSpace.CreatePipeline();
System.Management.Automation.Runspaces.Command getCommand = new System.Management.Automation.Runspaces.Command("Connect-VIServer");
getCommand.Parameters.Add("server", "xxx.xxx.xxx.xxx");
getCommand.Parameters.Add("user", "user");
getCommand.Parameters.Add("password", "password");
Pipe.Commands.Add(getCommand);
Pipe.Commands.AddScript("Get-vm");
System.Collections.ObjectModel.Collection<System.Management.Automation.PSObject> commandResults;
try
{
commandResults = Pipe.Invoke();
}
I hope it helps you. Please share the testing results with us.
Thanks
Niket
Thanks for your response. I tried your suggestion with exactly the same results.
To replicate this problem make sure you are pushing your code to a web server that is not your development server box. Development boxes have the web server AND web page running from the same box and therefore pass-thru credentials (it works for me that way too). It is when there is no credential pass-thru that the problem occurs.