Automation

 View Only

Recompose all virtual desktops for a user (multiple pools)

  • 1.  Recompose all virtual desktops for a user (multiple pools)

    Posted Jun 20, 2012 08:37 PM

    Here is the scenario

    We have 14 view pools (using 6 different base images) that get recomposed every month (for patching).

    After searching the forums and sites, we now have a script that will do the following:

    1)     Set a time to recompose the pools (we stagger the recompose start time for each pool so we do not over stress our storage)

    2)     Delete all snapshots on the base images

    3)     Create a new snapshot using the current date in the name

            One of our snapshots is used for 9 different pools, we need to change the vlan that the base image is on for each different pool)

    4)     Update each pool to use the new snapshot for new machine creation

    5)     Schedule every machine in each pool to be recomposed at the scheduled time

    This bit works and everyone is happy

    Now for the change (because when things work well, we need to expand to see what more we can do J )

    In order to verify that all of the machines will get recomposed and run without issue, we start with a “testing” snapshot for each of the base images and Recompose 1 machine from each pool (that has been assigned to the same user). So far this has been a manual process.

    What I would like to do here is

    Create the test snapshot (without deleting any of the existing snapshots)

    Recompose 1 machine from each pool using the new snapshot from each base image.

    I can get the machine names from all of the pools with

    ForEach ($vm in (Get-DesktopVM)) {If ($vm.user_displayname -match "$name") {Write-Host $vm.Name}}

    I can get all of the pool detail to include parentvmpath and parentsnapshotpath

    My issue is now putting it all together in one place (I believe I am overthinking the process) and have now hit a programming mental block.

    Just for anyone who wants to see what the working recompose script looks like (yes I know there are a few places in the end for the script that could be changed to a loop, but again… mental program block)

    Not the complete code (redundant info removed) and the names have been changed to protect the innocent

    ------------------------------------------------------------------

    #add-pssnapin VMware.VimAutomation.Core

    & 'C:\Program Files\vmware\VMware View\server\extras\powershell\add-snapin.ps1'

    #

    ####################################################

    #Pop up a Calendar to get the Date for the Recompose to Happen. The time works from 00:00 on the chosen date

    Write-Host "Please Select the Date for the Recompose and Press Enter"

    #

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

    $objForm = New-Object Windows.Forms.Form

    $objForm.Text = "Select a Date"

    $objForm.Size = New-Object Drawing.Size @(190,190)

    $objForm.StartPosition = "CenterScreen"

    $objForm.KeyPreview = $True

    #

    $objForm.Add_KeyDown({

        if ($_.KeyCode -eq "Enter")

            {

                $dtmDate=$objCalendar.SelectionStart

                $objForm.Close()

            }

        })

    #

    $objForm.Add_KeyDown({

        if ($_.KeyCode -eq "Escape")

            {

                $objForm.Close()

            }

        })

    #

    $objCalendar = New-Object System.Windows.Forms.MonthCalendar

    $objCalendar.ShowTodayCircle = $False

    $objCalendar.MaxSelectionCount = 1

    $objForm.Controls.Add($objCalendar)

    $objForm.Topmost = $True

    $objForm.Add_Shown({$objForm.Activate()})

    [void] $objForm.ShowDialog()

    #

    ####################################################

    # Set the time for the Pool Recomposes and display this for final confirmation from the user

    # The start times are staggered so we dont over run the system

    $RECpool1 = $dtmDate.addminutes(-270)                            #Start at 7:30 PM

    $RECpool2 = $dtmDate.addminutes(-270)                            #Start at 7:30 PM

    $RECpool3 = $dtmDate.addminutes(-240)                            #Start at 8:00 PM

    $RECpool4 = $dtmDate.addminutes(-225)                            #Start at 8:25 PM

    $RECpool5 = $dtmDate.addminutes(-120)                            #Start at 10:00 PM

    #

    #

    # Display the proposed recompose schedule with an  option to cancel

    if ($dtmDate)

        {

            Write-Host "Pool 1 Scheduled for: $RECpool1"

            Write-Host "Pool 2 Scheduled for: $RECpool2"

            Write-Host "Pool 3 Scheduled for: $RECpool3"

                                    Write-Host "Pool 3 Scheduled for: $RECpool4"

                                    Write-Host "Pool 3 Scheduled for: $RECpool5"

                    Write-Host " "

        }

    #

    #Give the option to cancel the Recompose

    Read-Host "If this is OK, Hit the Enter Key, If this is not OK, hit ctrl-c now"

    #

    ####################################################

    #Get Todays date to use when creating the Snapshots

    $Date = get-date -uformat "%m-%d-%Y"

    #

    ####################################################

    # Connect to the VCenter Server

    $struser = Read-Host "Enter Username"

    Connect-VIServer -Server <vcenter servername> -Protocol https -user $struser

    #

    ####################################################

    #Delete all snapshots from all of the base images in the View Directory ViewComposerImages

    #

    foreach ($vm in get-folder "ViewComposerImages" | get-vm | sort-object) {

    $aduser

                 $snaps = get-snapshot -vm $vm

                 $vmname = $vm.name

                     foreach ($snap in $snaps){

                     $snapName = $snap.name

                         if ($snapname -ne $null){

                             #"  "

                             $strOut = "Found snapshot: $snapname on: $vmname"

                             $strOut | Out-Default

                             $snap | select-object Name

                         

                           # Delete All Snapshots in this directory structure

                           remove-snapshot -snapshot $snap -confirm:$false

                         }

                         #else {"No snapshots found on $vmname"}

                         #"  "

                     }

             }

    #

    ####################################################

    ##Create a new snapshot for all of the base images in the ViewComposerImages directory using todays date in the name

    #

    foreach ($vm in get-folder "ViewComposerImages" | get-vm ) {

                    get-vm -name $vm | new-snapshot -name "$Date"

                    }

    #

    #           

    ####################################################

    ####################################################

    ### Pool1 Base Image (Windows 7)

    #Change the VLans and Create Snapshots of the General_Base image to be used for the pools that use the General Image as a Base

    #First, Make sure we are using the Base Snapshot

    #Then Change the VLan and take a snapshot

    #Then revert the snapshot back so we can change the VLan and take another snapshot

    #

    Set-VM -VM Gen1_Base -Snapshot $Date -confirm:$false

    #

    Get-VM -name Gen1_Base | Get-NetworkAdapter | Set-NetworkAdapter -Confirm:$false -NetworkName "VLAN10"

    Get-vm -name Gen1_Base | new-snapshot -name "$Date pool1"

    Set-VM -VM Gen1_Base -Snapshot $Date -confirm:$false

    #

    Get-VM -name Gen1_Base | Get-NetworkAdapter | Set-NetworkAdapter -Confirm:$false -NetworkName "VLAN20"

    Get-vm -name Gen1_Base | new-snapshot -name "$Date pool2"

    Set-VM -VM Gen1_Base -Snapshot $Date -confirm:$false

    #

    Get-VM -name Gen1_Base | Get-NetworkAdapter | Set-NetworkAdapter -Confirm:$false -NetworkName "VLAN30"

    Get-vm -name Gen1_Base | new-snapshot -name "$Date pool3"

    Set-VM -VM Gen1_Base -Snapshot $Date -confirm:$false

    #

    #Reset the Snapshot to the original VLan

    Get-VM -name Gen1_Base | Get-NetworkAdapter | Set-NetworkAdapter -Confirm:$false -NetworkName "VLAN60"

    #

    ####################################################

    #Set the Pool base snapshot for new machines

    ###########################################

    #These pools do not use the Gen1_Base Image

    Update-AutomaticLinkedClonePool -pool_id pool4 -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/pool4" -parentsnapshotpath /$date

    Update-AutomaticLinkedClonePool -pool_id pool5 -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/pool5" -parentsnapshotpath /$datetsnapshotpath /$date

    #

    #These pools use the Gen1_Base Image

    Update-AutomaticLinkedClonePool -pool_id pool1 -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool1"

    Update-AutomaticLinkedClonePool -pool_id pool2 -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool2"

    Update-AutomaticLinkedClonePool -pool_id pool3 -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool3"

    #

    ####################################################

    #Recompose Pools

    #

    Get-DesktopVM -pool_id pool4 | Send-LinkedCloneRecompose -schedule "$RECpool4" -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/pool4" -parentsnapshotpath /$Date -forceLogoff $true -stopOnError $false

    Get-DesktopVM -pool_id pool5 | Send-LinkedCloneRecompose -schedule "$RECpool5" -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/pool5" -parentsnapshotpath /$Date -forceLogoff $true -stopOnError $false

    #

    #These use the Gen1_Base image

    Get-DesktopVM -pool_id pool1 | Send-LinkedCloneRecompose -schedule "$RECpool1" -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool1" -forceLogoff $true -stopOnError $false

    Get-DesktopVM -pool_id pool2 | Send-LinkedCloneRecompose -schedule "$RECpool2" -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool2" -forceLogoff $true -stopOnError $false

    Get-DesktopVM -pool_id pool3 | Send-LinkedCloneRecompose -schedule "$RECpool3" -parentvmpath "/vm/Discovered virtual machine/ViewComposerImages/Gen1_Base" -parentsnapshotpath /$date/"$Date pool3" -forceLogoff $true -stopOnError $false

    #

    Write-Host "Finished"

    ----------------------------------------------

    If anyone has any ideas to puch me into the right direction please chime in..

    Thank you for looking