Using VMware PowerCLI (#004) – Deploy Template (v0.2)

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 = &quot;No&quot;
$PSIndex = 1
1..$pssnap.Count | foreach {
    if ($pssnap[$PSIndex].Name -like &quot;vmware.vimautomation.core&quot;) {
        $APS = &quot;Yes&quot;
    }
    $PSIndex++
}
if ($APS -eq &quot;No&quot;) { Add-PSSnapin VMware.VimAutomation.Core }

<h1>Enabling multiple connection</h1>

$PCC = get-PowerCLIConfiguration
if ($test.DefaultVIServerMode -eq &quot;single&quot;) {
    Set-PowerCLIConfiguration -DefaultVIServerMode Multiple
}

<h1>vCenter Server Connection</h1>

Header
Write-Host &quot;&quot;
$Target = Read-Host (&quot;Which vCenter Do you want connect to&quot;)
if ($global:DefaultVIServer.Name -eq $Target) {
    $CRMB = &quot;Yes&quot;
} else {
    $VICSI = Get-VICredentialStoreItem | Sort-Object Host
    $AI = &quot;No&quot;
    foreach ($item in $VICSI) {
        if ($Target -eq $item.Host) {
            $AI = &quot;Yes&quot;
        }
    }
    if ($AI -eq &quot;No&quot;) {
        $cred = Get-Credential
        $NCR = Connect-VIServer -Server $Target -Credential $cred
    } else {
        $NCR = Connect-VIServer -Server $Target
    }
    if ($NCR.IsConnected -eq $true) {
        $CRMB = &quot;Yes&quot;
    } else {
        $CRMB = &quot;No&quot;
    }
}

function MainBody {
    # Template Selection
    Header
    Write-Host &quot;&quot;
    $Templates = Get-Template | Select Name | Sort-Object Name
    $i = 1
    $Templates | %{Write-Host $i&quot;:&quot; $_.Name; $i++}
    $SIndex = Read-Host &quot;Enter a number ( 1 -&quot; $Templates.Count &quot;)&quot;
    $STemplate = $Templates[$SIndex - 1].Name

<pre><code># Customization Profile Selection
Header
Write-Host &amp;quot;&amp;quot;
$OSCPs = Get-OSCustomizationSpec | Select Name | Sort-Object
$j = 1
$OSCPs | %{Write-Host $j&amp;quot;:&amp;quot; $_.Name; $j++}
Write-Host $j&amp;quot;: None&amp;quot;
$OSIndex = Read-Host &amp;quot;Enter a number ( 1 -&amp;quot; $OSCPs.Count+1 &amp;quot;)&amp;quot;
$SOSCP = $OSCPs[$OSIndex - 1].Name
if ($OSIndex -eq $j) {
    $SOSCP = &amp;quot;None&amp;quot;
}

# Host Selection
Header
Write-Host &amp;quot;&amp;quot;
$VMHosts = Get-VMHost | Select Name | Sort-Object
$x = 1
$VMHosts | %{Write-Host $x&amp;quot;:&amp;quot; $_.Name; $x++}
$VMHIndex = Read-Host &amp;quot;Enter a number ( 1 -&amp;quot; $VMHosts.Count &amp;quot;)&amp;quot;
$SVMHost = $VMHosts[$VMHIndex - 1].Name

# Datastore Selection
Header
Write-Host &amp;quot;&amp;quot;
$Datastores = Get-VMHost $SVMHost | Get-Datastore | Select Name,FreeSpaceGB,CapacityGB | Sort-Object CapacityGB
$y = 1
$Datastores | %{Write-Host $y&amp;quot;:&amp;quot; $_.Name&amp;quot;`t`tCapacity (GB):&amp;quot; $_.CapacityGB&amp;quot;`t`tFree Space (GB):&amp;quot; $_.FreeSpaceGB; $y++}
$DSIndex = Read-Host &amp;quot;Enter a number ( 1 -&amp;quot; $Datastores.count &amp;quot;)&amp;quot;
$SDatastore = $Datastores[$DSIndex - 1].Name

# Location Selection
Header
Write-Host &amp;quot;&amp;quot;
$LSA = Read-Host &amp;quot;[R] Resource Pool`n[V] vApp`n[Other Keys] No Config (simple)`nPlease select location for placing new VM(s)&amp;quot;
$SLocation = &amp;quot;None&amp;quot;
Switch ($LSA) {
    &amp;quot;r&amp;quot; {
        Write-Host &amp;quot;&amp;quot;
        $ARPs = Get-ResourcePool | Sort-Object Name
        $z = 1
        $ARPs | %{Write-Host $z&amp;quot;:&amp;quot; $_.Name; $z++}
        $RPIndex = Read-Host &amp;quot;Enter a number ( 1 -&amp;quot; $ARPs.count &amp;quot;)&amp;quot;
        $SRP = $ARPs[$RPIndex - 1].Name
        $SLocation = $ARPs[$RPIndex - 1]
    }
    &amp;quot;v&amp;quot; {
        Write-Host &amp;quot;&amp;quot;
        $AVAs = Get-VApp | Sort-Object Name
        $k = 1
        $AVAs | %{Write-Host $k&amp;quot;:&amp;quot; $_.Name;$k++}
        $VAIndex = Read-Host &amp;quot;Enter a number ( 1 -&amp;quot; $AVAs.cout &amp;quot;)&amp;quot;
        $SVA = $AVAs[$VAIndex - 1].Name
        $SLocation = $AVAs[$VAIndex - 1]
    }
    default { $SLocation = &amp;quot;Root&amp;quot; }
}

# Name Selection
Header
Write-Host &amp;quot;&amp;quot;
$SName = Read-Host &amp;quot;Please enter VMs Naming Patern&amp;quot;

# Getting VM count
$NVMTD = Read-Host &amp;quot;How many VMs do you want to deploy&amp;quot;

# Getting confirmation and deploying
Header
Write-Host &amp;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&quot;

<pre><code># Action Menu
$NVMDConf = Read-Host &amp;quot;`n[C] Create VM(s)`n[R] Create and run VM(s)`n[Other Keys] Exit`nPlease select action from list&amp;quot;
switch ($NVMDConf) {
    &amp;quot;c&amp;quot; {
        Switch ($SOSCP) {
            &amp;quot;None&amp;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) {
            &amp;quot;None&amp;quot; { break }
            default { $NoOut = Get-VM | Where {$_.Name -like &amp;quot;$SName*&amp;quot;} | Move-VM -Destination $SLocation }
        }
        Write-Host &amp;quot;`n----- Created VMs -----&amp;quot; -NoNewline
        Get-VM | Where {$_.Name -like &amp;quot;$SName*&amp;quot;} | Select Name,PowerState,NumCPU,MemoryMB | Format-Table -AutoSize
        Write-Host &amp;quot;You need to manually start your VMs.`n&amp;quot; -BackgroundColor Yellow -ForegroundColor Blue
    }
    &amp;quot;r&amp;quot; {
        Switch ($SOSCP) {
            &amp;quot;None&amp;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) {
            &amp;quot;None&amp;quot; { break }
            default { $NoOut = Get-VM | Where {$_.Name -like &amp;quot;$SName*&amp;quot;} | Move-VM -Destination $SLocation }
        }
        Write-Host &amp;quot;`n----- Created VMs -----&amp;quot;
        Get-VM | Where {$_.Name -like &amp;quot;$SName*&amp;quot;} | Select Name,PowerState,NumCPU,MemoryMB | Format-Table -AutoSize
    }
    default {
        Write-Host (&amp;quot;All process aborted by user!&amp;quot;) -BackgroundColor Yellow -ForegroundColor DarkRed
        break
    }
}
</code></pre>

}

if ($CRMB -eq &quot;Yes&quot;) {
    MainBody{}
    Write-Host &quot;Thanks for using <code>&amp;quot;Deploy Template Script (v0.2)</code>&quot;<code>nSohrab Kasraeian Fard (@Kasraeian)</code>n&quot;
} else {
    Write-Host &quot;Error on connecting to vCenter Server&quot; -BackgroundColor Yellow -ForegroundColor DarkRed
}

6 Comments

Add a Comment
  1. 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?

    1. 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.

  2. 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?

    1. 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

  3. 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.

It's your kindness to leave a reply/feedback