c#remote powershell Hyperv cmdlet start-vm -Vm

时间:2012-12-17 20:21:16

标签: c# powershell hyper-v

我正在尝试传递该powershell命令的VM对象:

Start-Vm -Vm <VirtualMachine>

我想用c#代码来做这件事。 所以我创建了一个远程运行空间,依此类推:

class RemotePowershell
{
    private const string SHELL_URI = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
    private WSManConnectionInfo connectionInfo = null;

    public RemotePowershell(string hostname, string username, string livepassword)
    {

        SecureString password = new SecureString();
        foreach (char c in livepassword.ToCharArray()) { password.AppendChar(c); }
        password.MakeReadOnly();

        PSCredential creds = new PSCredential(string.Format("{0}\\{1}", hostname, username), password);

        var targetWsMan = new Uri(string.Format("http://{0}:5985/wsman", hostname));
        connectionInfo = new WSManConnectionInfo(targetWsMan, SHELL_URI, creds);
        connectionInfo.OperationTimeout = 4 * 60 * 1000; // 4 minutes.
        connectionInfo.OpenTimeout = 1 * 60 * 1000; // 1 minute.
        connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate;       
    }


    public void RunScript(string scriptText, Collection<CommandParameter> parametters)
    {
        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            runspace.Open();

            using (PowerShell ps = PowerShell.Create())
            {
                ps.Runspace = runspace;
                ps.AddCommand(scriptText);
                ps.AddParameters(parametters);


                Collection<PSObject> results = ps.Invoke();    
            }
            runspace.Close();
        }

我使用这样的扩展方法运行它:

public static class PowershellExtentionMethods
{
    private static RemotePowershell powerShellSession = new RemotePowershell("HOSTNAME", "USERNAME", "PASSWORD");


    public static void PowershellExec(this string commands, Collection<CommandParameter> parameters)
    {
        powerShellSession.RunScript(commands, parameters);
    }
}

var cmd = "Start-VM";
Collection<CommandParameter> cpc = new Collection<CommandParameter>();
cpc.Add(new CommandParameter("Vm",this.vm));
cmd.PowershellExec(cpc);

没有任何附加vm不启动,代码运行无例外。

所以我想知道我是否使用正确的技术将对象传递给cmdlet ......

如果有人作为一个想法,他是受欢迎的;)

1 个答案:

答案 0 :(得分:0)

一些想法..您的示例看起来不错,但您使用的是哪种类型的虚拟化?我猜是基于你使用Hyper-V的例子。

要检查的事项:

  • 服务器操作系统,如果是2008或2008 R2,来自System Center或第三方库的命令在哪里?在任何一种情况下,我都没有看到使用Start-VM命令加载模块的调用。在调用之前,请确保cmdlet或函数可用。如果它是Server 2012,自动加载应该处理加载命令,但是你需要确保盒子上有Hyper-V模块并加载到会话中。
  • 您传递给Start-VM的“this.VM”类型是什么?根据您用于管理VM的模块,对象的类型将很重要。
  • 什么是VM存储?是本地还是SMB共享?如果它在SMB共享上,是否有正确的凭据授权?