Well, This is a second edition,enhanced or debugged version of my previous “Deploy Template” script.
I tried to make it a little more user-friendly and added capability of selecting the location (Resource Pool/vApp) which user/admin can place their newly created VM(s) as well as capability of powering on VM(s) after their creation.
Also this script can be run from normal “Microsoft PowerShell” window just if you have installed “VMware vSphere PowerCLI” on your system and it will take care of adding needed snappin. 😉
Your comment and feedback would help me to make it faster, better and more straight forward and I’d be really happy to receive them. 😉 Again you can download the saved code bellow or check and copy/paste it to “.ps1” file.
Update #1:
Current version (v0.2) will work correctly only if environment contains more than one item in each section (templates, customization profile, …); I’m working on it to fix this problem and will update this post as soon as I finished the correction and tests. [May 7, 2012 – 4:57 PM]
Update #2:
I’ve updated my script to fix “some problem” it got as mentioned by “nWill” and post it here. [May 10, 2012 – 4:05 PM]
[wpdm_file id=6]
##################################################### function Header { CLS Write-Host "Name:`tDeploy Template Script (v0.2)" } ##################################################### <h1>Adding PSSnapin</h1> $pssnap = Get-PSSnapin | Sort-Object Name $APS = "No" $PSIndex = 1 1..$pssnap.Count | foreach { if ($pssnap[$PSIndex].Name -like "vmware.vimautomation.core") { $APS = "Yes" } $PSIndex++ } if ($APS -eq "No") { Add-PSSnapin VMware.VimAutomation.Core } <h1>Enabling multiple connection</h1> $PCC = get-PowerCLIConfiguration if ($test.DefaultVIServerMode -eq "single") { Set-PowerCLIConfiguration -DefaultVIServerMode Multiple } <h1>vCenter Server Connection</h1> Header Write-Host "" $Target = Read-Host ("Which vCenter Do you want connect to") if ($global:DefaultVIServer.Name -eq $Target) { $CRMB = "Yes" } else { $VICSI = Get-VICredentialStoreItem | Sort-Object Host $AI = "No" foreach ($item in $VICSI) { if ($Target -eq $item.Host) { $AI = "Yes" } } if ($AI -eq "No") { $cred = Get-Credential $NCR = Connect-VIServer -Server $Target -Credential $cred } else { $NCR = Connect-VIServer -Server $Target } if ($NCR.IsConnected -eq $true) { $CRMB = "Yes" } else { $CRMB = "No" } } function MainBody { # Template Selection Header Write-Host "" $Templates = Get-Template | Select Name | Sort-Object Name $i = 1 $Templates | %{Write-Host $i":" $_.Name; $i++} $SIndex = Read-Host "Enter a number ( 1 -" $Templates.Count ")" $STemplate = $Templates[$SIndex - 1].Name <pre><code># Customization Profile Selection Header Write-Host &quot;&quot; $OSCPs = Get-OSCustomizationSpec | Select Name | Sort-Object $j = 1 $OSCPs | %{Write-Host $j&quot;:&quot; $_.Name; $j++} Write-Host $j&quot;: None&quot; $OSIndex = Read-Host &quot;Enter a number ( 1 -&quot; $OSCPs.Count+1 &quot;)&quot; $SOSCP = $OSCPs[$OSIndex - 1].Name if ($OSIndex -eq $j) { $SOSCP = &quot;None&quot; } # Host Selection Header Write-Host &quot;&quot; $VMHosts = Get-VMHost | Select Name | Sort-Object $x = 1 $VMHosts | %{Write-Host $x&quot;:&quot; $_.Name; $x++} $VMHIndex = Read-Host &quot;Enter a number ( 1 -&quot; $VMHosts.Count &quot;)&quot; $SVMHost = $VMHosts[$VMHIndex - 1].Name # Datastore Selection Header Write-Host &quot;&quot; $Datastores = Get-VMHost $SVMHost | Get-Datastore | Select Name,FreeSpaceGB,CapacityGB | Sort-Object CapacityGB $y = 1 $Datastores | %{Write-Host $y&quot;:&quot; $_.Name&quot;`t`tCapacity (GB):&quot; $_.CapacityGB&quot;`t`tFree Space (GB):&quot; $_.FreeSpaceGB; $y++} $DSIndex = Read-Host &quot;Enter a number ( 1 -&quot; $Datastores.count &quot;)&quot; $SDatastore = $Datastores[$DSIndex - 1].Name # Location Selection Header Write-Host &quot;&quot; $LSA = Read-Host &quot;[R] Resource Pool`n[V] vApp`n[Other Keys] No Config (simple)`nPlease select location for placing new VM(s)&quot; $SLocation = &quot;None&quot; Switch ($LSA) { &quot;r&quot; { Write-Host &quot;&quot; $ARPs = Get-ResourcePool | Sort-Object Name $z = 1 $ARPs | %{Write-Host $z&quot;:&quot; $_.Name; $z++} $RPIndex = Read-Host &quot;Enter a number ( 1 -&quot; $ARPs.count &quot;)&quot; $SRP = $ARPs[$RPIndex - 1].Name $SLocation = $ARPs[$RPIndex - 1] } &quot;v&quot; { Write-Host &quot;&quot; $AVAs = Get-VApp | Sort-Object Name $k = 1 $AVAs | %{Write-Host $k&quot;:&quot; $_.Name;$k++} $VAIndex = Read-Host &quot;Enter a number ( 1 -&quot; $AVAs.cout &quot;)&quot; $SVA = $AVAs[$VAIndex - 1].Name $SLocation = $AVAs[$VAIndex - 1] } default { $SLocation = &quot;Root&quot; } } # Name Selection Header Write-Host &quot;&quot; $SName = Read-Host &quot;Please enter VMs Naming Patern&quot; # Getting VM count $NVMTD = Read-Host &quot;How many VMs do you want to deploy&quot; # Getting confirmation and deploying Header Write-Host &quot;`nNew VM(s) would be created by bellow configuration </code></pre> Source Template: $STemplate Target Host: $SVMHost Target Datastore: $SDatastore OS Customization Profile: $SOSCP VM naming pattern: $SName Number of VM(s): $NVMTD Would place on: $SLocation" <pre><code># Action Menu $NVMDConf = Read-Host &quot;`n[C] Create VM(s)`n[R] Create and run VM(s)`n[Other Keys] Exit`nPlease select action from list&quot; switch ($NVMDConf) { &quot;c&quot; { Switch ($SOSCP) { &quot;None&quot; { $NVMs = 1..$NVMTD | foreach { New-VM -VMHost $SVMHost -Name $SName$_ -Template $STemplate -Datastore $SDatastore } } default { $NVMs = 1..$NVMTD | foreach { New-VM -VMHost $SVMHost -Name $SName$_ -Template $STemplate -Datastore $SDatastore -OSCustomizationSpec $SOSCP } } } Switch ($SLocation) { &quot;None&quot; { break } default { $NoOut = Get-VM | Where {$_.Name -like &quot;$SName*&quot;} | Move-VM -Destination $SLocation } } Write-Host &quot;`n----- Created VMs -----&quot; -NoNewline Get-VM | Where {$_.Name -like &quot;$SName*&quot;} | Select Name,PowerState,NumCPU,MemoryMB | Format-Table -AutoSize Write-Host &quot;You need to manually start your VMs.`n&quot; -BackgroundColor Yellow -ForegroundColor Blue } &quot;r&quot; { Switch ($SOSCP) { &quot;None&quot; { $NVMs = 1..$NVMTD | foreach { New-VM -VMHost $SVMHost -Name $SName$_ -Template $STemplate -Datastore $SDatastore | Start-VM } } default { $NVMs = 1..$NVMTD | foreach { New-VM -VMHost $SVMHost -Name $SName$_ -Template $STemplate -Datastore $SDatastore -OSCustomizationSpec $SOSCP | Start-VM } } } Switch ($SLocation) { &quot;None&quot; { break } default { $NoOut = Get-VM | Where {$_.Name -like &quot;$SName*&quot;} | Move-VM -Destination $SLocation } } Write-Host &quot;`n----- Created VMs -----&quot; Get-VM | Where {$_.Name -like &quot;$SName*&quot;} | Select Name,PowerState,NumCPU,MemoryMB | Format-Table -AutoSize } default { Write-Host (&quot;All process aborted by user!&quot;) -BackgroundColor Yellow -ForegroundColor DarkRed break } } </code></pre> } if ($CRMB -eq "Yes") { MainBody{} Write-Host "Thanks for using <code>&quot;Deploy Template Script (v0.2)</code>"<code>nSohrab Kasraeian Fard (@Kasraeian)</code>n" } else { Write-Host "Error on connecting to vCenter Server" -BackgroundColor Yellow -ForegroundColor DarkRed }
This script is great and exactly what i’m looking for. However, Right after i choose to create VMs i get the following error:
“New-VM : Cannot validate argument on parameter ‘Template’. The argument is null. Supply a non-null argument and try the command again.”
This is weird because when asked for a template i am able to choose the template i created without giving me an error or something.
Any idea what i’m doing wrong?
Hi,
First of all, thanks for your kind comment and your time and I hope we can fix this problem so you can use this script better and faster.
May I ask what did you input when it asked for template ( screen shot ), and if its possible, would you please send me the screen shot of your configuration ( screen shot ).
I only could reproduce this problem by giving the name of template instead of its item number ( screen shot ), if its possible could you just enter the relevant number when it prompted for selecting the template and let me know the result.
Also for checking the warning or error you can add # before line number 3 and 4 so the all command would run after each other on same view instead of refreshing and adding header and in this case you can see the related error.
Hi,
Thank you for your quick reply.
When asked for the template i just entered the number (1) and not the name of the template. [url=http://postimage.org/][img]http://s17.postimage.org/cxlpnzlkf/DT0_2_Template.jpg[/img][/url]
[url=http://postimage.org/]upload pictures[/url]
When reviewing the final configuration the source template is not there however.
[url=http://postimage.org/][img=http://s17.postimage.org/66e4nh71r/DT0_2_Conf.jpg][/url]
[url=http://postimage.org/]upload images[/url]
I also tried adding # before line 3 and 4, when running the script i received the following error when selecting the template:
[url=http://postimage.org/][img=http://s14.postimage.org/4eucjxs41/DT0_2_Error.jpg][/url]
[url=http://postimage.org/]picture hosting[/url]
Is there a chance there is a problem with my template?
Thanks for reply and screen shots, I’ve changed my configuration based on your configuration and now I get same problem.
As far as I checked it’s just because of number of templates you got and you can be sure there’s no problem with your template, the problem is related to logic in item selection I’ve used in this script.
Current script will work only if you have more than one item in each section (template, customization profile, …) and now I’m working on it to fix it and will update this post as soon as I finished the correction.
Thanks a lot for your consideration and help
Ah i see, so that was the problem.
Thank you for helping me and taking the time to make a new script.
I will be looking forward to it.