首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >导出多个vms

导出多个vms
EN

Stack Overflow用户
提问于 2015-01-07 07:37:33
回答 1查看 137关注 0票数 0

我使用这个C#代码在虚拟机管理器中完全备份我的vms:

代码语言:javascript
复制
using Microsoft.SystemCenter.VirtualMachineManager;
using Microsoft.SystemCenter.VirtualMachineManager.UIAddIns;
using Microsoft.SystemCenter.VirtualMachineManager.UIAddIns.ContextTypes;
using Microsoft.VirtualManager.Remoting;
using System;
using System.AddIn;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;

namespace Microsoft.VirtualManager.UI.AddIns.BackupAddIn
{
    [AddIn("Make Backup")]
    public class BackupAddIn : ActionAddInBase
    {
        protected const string PowershellPath = "%WINDIR%\\System32\\WindowsPowershell\\v1.0\\powershell.exe";
        protected const string DefaultDirectory = "you don't need to know this";
        protected const string WildcardVMName = "{{VMName}}";
        protected const string WildcardError = "{{Error}}";
        protected const string BackupDirectoryBase = "{{Base}}";
        protected const string BackupDirectoryName = "{{Name}}";
        protected const string BackupDirectoryDate = "{{Date}}";

        public enum JobState { Initialized, Success, Fail };

        protected const string BackupDirectoryTemplate = BackupDirectoryBase + "\\" + BackupDirectoryName + "\\" + BackupDirectoryDate + "\\";
        protected static readonly ReadOnlyCollection<string> AllowedBackupStates = new ReadOnlyCollection<string>(new string[] { "PowerOff", "Paused"/*, "Saved"*/});


        public override bool CheckIfEnabledFor(IList<ContextObject> contextObjects)
        {
            if (contextObjects != null && contextObjects.Count > 0)
            {
                foreach (var host in contextObjects.OfType<HostContext>())
                {
                    if (host.ComputerState != ComputerState.Responding)
                    {
                        return false;
                    }
                }
                return true;
            }

            return false;
        }

        public override void PerformAction(IList<ContextObject> contextObjects)
        {
            if (contextObjects != null)
            {
                // check if we have VMs selected
                var VMs = contextObjects.OfType<VMContext>();
                if (VMs != null && VMs.Count() > 0)
                {
                    // check if VMs are in a good state
                    var badVMs = VMs.Where(vm => AllowedBackupStates.Contains(vm.Status.ToString()) == false).ToArray();
                    if (badVMs != null && badVMs.Length > 0)
                    {
                        MessageBox.Show("Backup not possible!\r\nThe following VMs are still running:\r\n\r\n" + string.Join(", ", badVMs.Select(vm => vm.Name)));
                    }
                    else
                    {
                        // ask for backup directory
                        string backupDir = Microsoft.VisualBasic.Interaction.InputBox("Enter the export path for the selected virtual machine(s) on the host.", "Export path", DefaultDirectory);
                        if (string.IsNullOrEmpty(backupDir) == false)
                        {
                            if (backupDir.EndsWith("\\"))
                            {
                                backupDir = backupDir.Substring(0, backupDir.Length - 1);
                            }

                            // go
                            foreach (var vm in VMs)
                            {
                                exportVM(vm, backupDir);
                            }
                        }
                    }
                }
            }
        }

        public string getDate()
        {
            var date = DateTime.Now;
            return date.Year.ToString()
                + (date.Month < 10 ? "0" : "") + date.Month.ToString()
                + (date.Day < 10 ? "0" : "") + date.Day.ToString()
                + "-"
                + (date.Hour < 10 ? "0" : "") + date.Hour.ToString()
                + (date.Minute < 10 ? "0" : "") + date.Minute.ToString();
        }

        public void ManageJob(string name, JobState state, string message = null)
        {
            string command;
            if (state == JobState.Initialized)
            {
                command = string.Format("${0} = New-SCExternalJob -Name \"{0}\"", name);
            }
            else if (state == JobState.Success)
            {
                command = string.Format("Set-SCExternalJob -Job (Get-SCJob -Name \"{0}\")[0] -Complete -InfoMessage \"" + (string.IsNullOrEmpty(message) ? "Backup successfully completed." : message) + "\"", name);
            }
            else
            {
                command = string.Format("Set-SCExternalJob -Job (Get-SCJob -Name \"{0}\")[0] -Failed -InfoMessage \"" + (string.IsNullOrEmpty(message) ? "Backup FAILED." : message) + "\"", name);
            }

            PowerShellContext.ExecuteScript<Host>(
                command,
                (profiles, error) =>
                {
                    if (error != null)
                    {
                        MessageBox.Show("Cannot modify job state\r\nError: " + error.Problem);
                    }
                }
            );
        }

        public void exportVM(VMContext vm, string backupDir)
        {
            string date = getDate();
            string fullBackupDir = BackupDirectoryTemplate.Replace(BackupDirectoryBase, backupDir).Replace(BackupDirectoryName, vm.Name).Replace(BackupDirectoryDate, date);
            string jobname = "Backup_" + vm.Name.Replace("-", "_").Replace(" ", "_");
            string command = string.Format("Export-VM -Name '{0}' -Path '{1}'", vm.Name, fullBackupDir);

            execPSScript(jobname, command, vm, WildcardVMName + ": Backup successful.", WildcardVMName + ": Backup FAILED!\r\nError: " + WildcardError);
        }

        public String scvmmPsCommand(string command, VMContext vm)
        {
            return string.Format("Invoke-SCScriptCommand -Executable \"{0}\" -VMHost (Get-SCVMHost -ID \"{1}\") -CommandParameters \"{2}\" -RunAsynchronously -TimeoutSeconds 360000", PowershellPath, vm.VMHostId.ToString(), command);
        }

        public void execPSScript(string jobname, string command, VMContext vm, string successMessage, string errorMessage)
        {
            ManageJob(jobname, JobState.Initialized);
            PowerShellContext.ExecuteScript<Host>(
                scvmmPsCommand(command, vm),
                (vms, error) =>
                {
                    if (error != null)
                    {
                        ManageJob(jobname, JobState.Fail, errorMessage.Replace(WildcardVMName, vm.Name).Replace(WildcardError, error.Problem));
                    }
                    else
                    {
                        ManageJob(jobname, JobState.Success, successMessage.Replace(WildcardVMName, vm.Name));
                    }
                }
            );
        }
    }
}`

如果我选择多个vms并尝试备份它们,那么除了一个之外,所有这些都会立即失败。

我需要让主机在一个单独的powershell中执行每个被调用的命令。

你知道这是否可能吗?

Export-VM与多个vms一起工作吗?

好的-我试着使用cmd.exe启动每个powershell,作为一个新任务,如下所示:

代码语言:javascript
复制
string.Format(Invoke-SCScriptCommand -Executable \"%WINDIR%\\System32\\cmd.exe\" -VMHost (Get-SCVMHost -ID \"{1}\") -CommandParameters \"START powershell {2}\" -RunAsynchronously -TimeoutSeconds 360000", PowershellPath, vm.VMHostId.ToString(), command)

Now..it再也不备份了。还有.我没有收到任何错误信息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-07 12:04:34

要使代码工作,您需要告诉cmd.exe,您希望它执行一个命令。只需将/C放在命令之前,如下所示:

代码语言:javascript
复制
string.Format("Invoke-SCScriptCommand -Executable \"%WINDIR%\\System32\\cmd.exe\" -VMHost (Get-SCVMHost -ID \"{1}\") -CommandParameters \"/C START powershell {2}\" -RunAsynchronously -TimeoutSeconds 360000", PowershellPath, vm.VMHostId.ToString(), command)

你真好!)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27814540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档