关于c#调用PowerShell来控制SCVMM,网上有很多例子,也比较简单,但创建虚拟机的过程,是一个很漫长的时间,所以一般来说,创建的时候都希望可以实时的显示当前虚拟机的创建进度。当时这个问题困扰了我了一段时间,但找到方法以后,发现其实很简单。

环境:

  Win server 2008 R2 + Hyper-v + SCVMM2008 R2

目的:

  C#调PowerShell在SCVMM中创建虚拟机时,实时显示创建进度

在SCVMM2008R2中手动创建一个vm(虚拟机)时,作业界面中会显示很详细的创建进度,包括有哪些子任务,每个任务的完成度、状态等信息。SCVMM的界面操作是基于Powershell的,所以肯定有ps脚本可以实现上述目的。

microsoft提供的创建虚拟机的ps脚本中,提到如下内容(为显示PS脚本中部分内容被回车)

$NewVMTasks = [System.Array]::CreateInstance("Microsoft.SystemCenter.VirtualMachineManager.Task"$NumVMs)$NewVMs = [System.Array]::CreateInstance("Microsoft.SystemCenter.VirtualMachineManager.VM"$NumVMs)$i = 0# Loop that creates each VM asynchronously.while($NumVMs -gt 0){# Generate a unique VM name.$VMRnd = $Random.next()$NewVMName = $VMName+$VMRnd# Get the ratings for each host and sort the hosts by ratings.$Ratings = @(Get-VMHostRating -Template $Template -VMHost $VMHosts -DiskSpaceGB $DiskSizeGB  -VMName $NewVMName | where { $_.Rating -gt 0| Sort-Object -property Rating -descending)if ($Ratings.Count -gt 0    {$VMHost = $Ratings[0].VMHost$VMPath = $Ratings[0].VMHost.VMPaths[0]# Create a new VM from the template and add an additional VHD# to the VM.$NewVMJobGroup = [System.Guid]::NewGuid()$VMAdditionalVhd | Add-VirtualHardDisk -Bus 0 -Lun 1 -IDE -JobGroup $NewVMJobGroup$NewVMs[$i= New-VM -Template $Template -Name $NewVMName -Description $NewVMName  -VMHost $VMHost -Path $VMPath -RunAsynchronously -StartVM -JobGroup $NewVMJobGroup$NewVMTasks[$i= $NewVMs[$i].MostRecentTask$i = $i + 1   }$NumVMs = $NumVMs - 1   Start-Sleep -seconds 5}

脚本中的Task,其实就是我们所需要的,可以实时显示创建进度的类(Microsoft.SystemCenter.VirtualMachineManager.Task)。

也就是说在通过c#调用powershell创建虚拟时,如果可以得到此类的实例,即可解决问题。

在SCVMM提供的ps脚本中,创建虚机的cmdlet为“new-vm .....”后面带了很多参数,比如-name(虚机名字),-path(存储路径),-jobGroup(作业ID,作业ID一般通过 [System.Guid]::NewGuid()获得,唯一标示),-jobVariable(记录当前作业实例)等等,其中的-jobVariable即是我们所需要的。

关于-jobVariable这个参数的详细信息,及实例可以参考微软帮助文档

http://technet.microsoft.com/en-us/library/bb963731.aspx

例如下面的解释很详细了,即调用new-vm命令后,会将当前作业存在-jobvariable 后面指定的变量中。

##################################################################### Run a VMM cmdlet that creates a job - in this example script, the # cmdlet is New-V2V, so the job is the creation of a new VM from an # existing VMware VM.####################################################################$VM = New-V2V -VMXPath $LegacyVM -VMHost $VMHost -Name $VMName  -Path $VMPath -Memory $Memory -Runasynchronously -Jobvariable "Job"##################################################################### Track the status of the running job.####################################################################$JobNameString = $Job.CmdletName+" "+$Job.ResultName# Loop while the job is running, writing progress using current step # and progress values from the job.while ($job.status -eq "Running"Write-Progress -Activity "$JobNameString" -Status $Job.CurrentStep  -PercentComplete $Job.ProgressValue; Start-Sleep -seconds 5}

-jobvariable 一般跟-Runasynchronously参数一起使用,因为你获得了job变量当然希望ps异步执行了,

在c#中如何使用-jobvariable参数?请参考下面代码中红色部分

private void CreateVM(Host host           , Template template           , HardwareProfile hardwareProfile           , Runspace runspace){  Command newVM = new Command("new-vm");    newVM.Parameters.Add("vmhost", host);    newVM.Parameters.Add("Template", template);    newVM.Parameters.Add("hardwareprofile", hardwareProfile);    newVM.Parameters.Add("name", newVMName);    newVM.Parameters.Add("Description"            , string.Format("vm created by {0} on {1}"                      , Environment.UserName, DateTime.Now));  newVM.Parameters.Add("path", host.VMPaths[0]);  newVM.Parameters.Add("owner"this.owner);   newVM.Parameters.Add("startvm"true);  newVM.Parameters.Add("jobgroup"this.jobGroupID);  newVM.Parameters.Add("jobvariable""newvmtask");  newVM.Parameters.Add("runAsynchronously"true);    using (Pipeline pipeline = GetCommandPipe(runspace))  {    pipeline.Commands.Add(newVM);       Collection<PSObject> result = pipeline.Invoke();       pipeline.Stop();Task task = runspace.SessionStateProxy.GetVariable("newvmtask"as Task;task.Updated += new EventHandler<ObjectChangedEventArgs>(task_Updated);   }}private void task_Updated(object sender, ObjectChangedEventArgs e)  if (OnTaskProcess != null)    {        Task taskTemp = e.Object as Task;this.OnTaskProcess(taskTemp);     }}

上述代码中,很多东西不全,只是介绍如何取到-jobvariable参数指定的Task实例,在Command中添加-jobvariable

//Task对象放于名为newvmtask的变量中,此处随便定义。newVM.Parameters.Add("jobvariable""newvmtask");newVM.Parameters.Add("runAsynchronously"true);//指定cmdlet异步执行

在异步执行完后,在Runspace的Session中可以取到之前指定的Task实例,(此处为newvmtask)

Task task = runspace.SessionStateProxy.GetVariable("newvmtask") as Task;
此处的newvmtask是依据在command中-jobvariable参数指定的实例名。

取到Task对象实例后,即可通过其update事件,来实时显示Task的处理进度。

task.Updated += new EventHandler<ObjectChangedEventArgs>(task_Updated);

在task_Updated中可以作自己想做的事情。

Microsoft.SystemCenter.VirtualMachineManager.Task

Task类中存在一个属性Steps,类型为List<Step>,可以通过此属性,浏览一个作业的子过程的运行状况。

Step为Microsoft.SystemCenter.VirtualMachineManager.Step类

顺便提一下,SCVMM2008R2中powershell的Snapin为"Microsoft.SystemCenter.VirtualMachineManager"。

C#调PowerShell在SCVMM中创建虚拟机时,实时显示创建进度的更多相关文章

  1. OpenStack Horizon创建虚拟机时增加虚拟机OS用户

    背景 通过OpenStack的Horizon使用镜像创建虚拟机(以Ubuntu为例),如果不知道镜像的用户名和密码,在创建好虚拟机之后,无法登录虚拟机的OS.因此,我们需要一种方法,创建虚拟机时增加用 ...

  2. Unity3d中使用摄像机制作实时显示小地图

    Unity3d中使用摄像机制作实时显示小地图,以之前的tank为例.开始制作之前场景中物体如图. 开始制作,步骤1:新建一个camera及一个plane.对齐位置,将camera改名为camera_U ...

  3. Android中如何下载文件并显示下载进度

    原文地址:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1125/2057.html 这里主要讨论三种方式:AsyncTask.Serv ...

  4. Android 创建虚拟机时“提示no system images installed for this target”

    经上网查证,发现原因在于CPU/ABI选项无法选择,并显示“No system images installed for this target”,也就是没有适合的系统镜像,通过与安装好了的ADT-b ...

  5. 创建虚拟机时,提示No valid host was found解决办法

    1.http://blog.csdn.net/yxwmzouzou/article/details/43892261 2.http://www.cnblogs.com/kevingrace/p/601 ...

  6. vagrant 创建虚拟机时遇到问题

    问题1 :  ceph-node3: Warning: Authentication failure. Retrying.. 问题分析: ssh 认证失败,在向虚拟机拷贝内容时权限不足. 解决办法: ...

  7. Azure 基础:使用 powershell 创建虚拟网络

    什么是虚拟网络 虚拟网络是您的网络在 Azure 云上的表示形式.您可以完全控制虚拟网络的 IP 地址.DNS 的设置.安全策略和路由表.您还可以更进一步,把虚拟网络划分为多个子网.然后用它们连接您的 ...

  8. VS中 无法创建虚拟目录 本地IIS IIS Express 外部主机

    从前就有个疑问了,为什么我拉取别人写好的代码后就可以在IIS里面生成一个网站呢? 这里所谓的生成网站,是指包含了所有源代码文件的网站:相对地,发布网站,就是指包含被编译的源文件所得到的DLL文件的网站 ...

  9. Azure 中的虚拟网络和虚拟机

    创建 Azure 虚拟机 (VM) 时,必须创建虚拟网络 (VNet) 或使用现有的 VNet. 此外,还需要确定如何在 VNet 上访问 VM. 在创建资源之前必须做好规划,确保了解网络资源的限制. ...

随机推荐

  1. appium常见问题06_如何解决uiaotomator定位工具报错

    在使用uiaotomator工具定位元素过程中,经常会弹出报错,截图失败,导致无法定位元素,当遇到该问题时,解决办法如下: 方法一:拔掉手机usb连接,重新连接手机 方法二:adb杀掉手机服务,重起服 ...

  2. 1381. 删除 (Standard IO)

    题目描述: Alice上化学课时又分心了,他首先画了一个3行N列的表格,然后把数字1到N填入表格的第一行,保证每个数只出现一次,另外两行他也填入数字1到N,但不限制每个数字的出现次数.Alice现在想 ...

  3. golang的数据类型之布尔类型

    1)布尔类型也叫 bool类型,bool类型数据只允许取值true或false2)bool类型占1个字节.3)bool类型适于逻辑运算,一般用于程序流程控制4)不可以0或非0的整数替代false和tr ...

  4. Linux系统安全

    简单优化: 1.删除不必要的软件包(如postfix等) yum remove -y postfix 安装管理:1.口令 1.1至少8个字符,大小写.特殊字符和数字组合,定期更改 1.2口令长度可以编 ...

  5. LOGO有哪几种常规设计思路?

    Logo设计的思路多种多样,但是我个人从Logo设计的历史上,大致可以归纳出五种常规思路,思路的名称是自己编的,仅供大家参考.而列举的这些思路背后,都是有着各自的时代背景的. 先从历史最悠久的一种设计 ...

  6. C# 编程—字符串(方法应用)、数学Math函数、DateTime、异常捕获、其他

    其他:        #--任意位数字,有几位显示几位        0--至少以为数字,不足则补0        例如:#.00--必须保留两位小数 字符串(string): Length  长度 ...

  7. 作业(二)—python实现wc命令

    Gitee地址:https://gitee.com/c1e4r/word-count(为什么老师不让我们用github) 0x00 前言 好久没发博客了,感觉自己的学习是有点偷懒了.这篇博客也是应专业 ...

  8. while/until/for 循环举例2

  9. 2019HDU多校第三场 Distribution of books 二分 + DP

    题意:给你一个序列,你可以选择序列的一个前缀,把前缀分成k个连续的部分,要求这k个部分的区间和的最大值尽量的小,问这个最小的最大值是多少? 思路:首先看到最大值的最小值,容易想到二分.对于每个二分值m ...

  10. Django Rest框架 APIView源码调用

    上一篇说了请求访问的流程,这一篇说一下请求对应的源码调用 as_view 定义view dispatch dispatch initialize_request get_parsers         ...