Create a New Virtual Machine with PowerShell: Part 3

Create a New Virtual Machine with PowerShell: Part 3

  • Comments 5
  • Likes

Summary: Windows PowerShell MVP and honorary Scripting Guy, Sean Kearney, completes his series about using Windows PowerShell to create a virtual machine.

Microsoft Scripting Guy, Ed Wilson, is here. If you are a seasoned Hey, Scripting Guy! Blog reader, you know that the most frequent guest blogger is Sean Kearney. If you are new to the blog, I welcome you, and I encourage you to catch up with Sean’s previous blogs.

Sean is a Windows PowerShell MVP and an Honorary Scripting Guy. Sean’s session at TechEd NA and TechEd Europe this year is Integrating with Microsoft System Center 2012 and Windows PowerShell. In his free time, Sean has written several blog posts about Hyper-V and some other cool stuff, and for the next few weeks, Sean will be the designated guest blogger on Fridays.

To read the previous posts in this series, please see:

Create a New Virtual Machine with Windows PowerShell: Part 1

Create a New Virtual Machine with Windows PowerShell: Part 2

Take it away Sean…

My good friend, Brad, had been playing with making a new virtual machine in Windows Server 2012 with Hyper-V. He wanted to create a machine with the following parameters:

Name of “Brad VM SCSM”

2 gigabytes of RAM

60 gigabyte hard drive

2 CPU cores assigned

Connected to my virtual network called “Hyper-V-Prod1”

To do so, he ran the following commands in Windows PowerShell:

NEW-VM –Name “Brad VM SCSM” –MemoryStartupBytes 2048 –NewVHDPath E:\VHD\BradVMSCSM-C.VHDX –NewVHDSizeBytes 60000000000

ADD-VMNetworkAdapter –VMName “Brad VM SCSM” –Switchname “Hyper-V-Prod1”

SET-VMProcessor –VMName “Brad VM SCSM”

Now Brad’s question became how to make this repeatable. “I’ve figured out online that if I save this as a .PS1 file with Notepad or the Windows PowerShell ISE, this is technically a Windows PowerShell script. I would like to do two things to make this truly useful:

  • Avoid editing the text file to change virtual machine names and parameters
  • Be able to create the virtual machines on any Windows Server 2012 with Hyper-V

First, I wanted to show Brad how to change the names to variables for the same script. “Wherever you see a value in the script, you can swap it with a variable starting with a dollar sign ($). Here’s your original script changed with appropriately named variables in Windows PowerShell.”

$VMName=”Brad VM SCSM”

$Memory=2048

$NewVHD=”E:\VHD\BradVMSCSM-C.vhdx”

$VHDSize=60000000000

$Switch=”Hyper-V-Prod1”

$Cpu=2

NEW-VM –Name $Vmname –MemoryStartupBytes $Memory –NewVHDPath $NewVHD –NewVHDSizeBytes $VHDSize

ADD-VMNetworkAdapter –VMName $VMName –Switchname $Switch

SET-VMProcessor –VMName $VMName –count $Cpu

Brad’s eyes lit up. “Oh, that’s actually pretty easy. So is there any way we can write this script to accept these as values?”

I looked over. “Brad, I’d like you to meet parameters. We can simply add Param before the variables that we want to change, and separate the list with commas like this:”

Param(

$VMName,

$Memory,

$NewVHD,

$VHDSize,

$Switch,

$Cpu=2

)

“So with these names as parameters, we can launch our NEW-BRADVM.PS1 Script like this:”

./NEW-BRADVM.PS1 –VMName ‘test’ –Memory 2048MB -$NewVHD ‘C:\VHD\MyVHD.VHDX’ –VHDSize 10000000000 $Switch ‘Hyper-V-Prod1’ –Cpu 4

“Fine. Now how about my bigger request? I’d like to run this from one computer to make these kinds of changes to multiple virtual machines running Hyper-V.”

“Ah. Such a simple answer. You can supply in the parameter called ComputerName to most cmdlets. In the case of the Hyper-V cmdlets, this parameter specifies the name of the computer running Hyper-V. So your completed script with the ability to create a virtual machine on any remote computer running Hyper-V would look like this:”

Param(

$Computername,

$VMName,

$Memory,

$NewVHD,

$VHDSize,

$Switch,

$Cpu=2

)

NEW-VM –Name $Vmname –MemoryStartupBytes $Memory –NewVHDPath $NewVHD –NewVHDSizeBytes $VHDSize –computername $computername

ADD-VMNetworkAdapter –VMName $VMName –Switchname $Switch –computername $computername

SET-VMProcessor –VMName $VMName –count $Cpu –computername $computername

“Here’s the cool part, Brad. If I had a list of this information in a .csv file, I can do all this in one line:”

IMPORT-CSV | FOREACH { ./NEW-BRADVM.PS1 –VMName $_.Vmname –Memory $_.Ram -$NewVHD $_.VHDFile –VHDSize $_.Vhdsize $Switch $_.Switch –Cpu $_.CpuCount }

“All of that in one line? Why didn’t you tell me about Windows PowerShell before?!?!”

So, it appears that we have yet another person saved by the Power of Shell.

~Sean

Thanks, Sean. This is awesome stuff. Join me tomorrow for more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Are there some typos in the two lines above?

    ./NEW-BRADVM.PS1 –VMName ‘test’ –Memory 2048MB -$NewVHD ‘C:\VHD\MyVHD.VHDX’ –VHDSize 10000000000 $Switch ‘Hyper-V-Prod1’ –Cpu 4

    and

    IMPORT-CSV | FOREACH { ./NEW-BRADVM.PS1 –VMName $_.Vmname –Memory $_.Ram -$NewVHD $_.VHDFile –VHDSize $_.Vhdsize $Switch $_.Switch –Cpu $_.CpuCount }

    The Dollar Signs in front of the parameter names should be dashes (-$NewVHD and $Switch)

  • @mike

    You're dead on.... Looks like I had too much coffee that day!

    It should read

    IMPORT-CSV | FOREACH { ./NEW-BRADVM.PS1 –VMName $_.Vmname –Memory $_.Ram -NewVHD $_.VHDFile –VHDSize $_.Vhdsize -Switch $_.Switch –Cpu $_.CpuCount }

    Thanks for pointing out!  No more coffee for ME today! :)

    Sean

  • $Memory=2048 does not work for me, had to use $Memory = 2147483648

  • Great series of articles.  Could anyone post the csv file format and the powershell to import and run

  • I usually use the KB/MB/GB/TB values hardcoded into PowerShell, ie.:

    NEW-VM –Name “Brad VM SCSM” –MemoryStartupBytes $(2GB)