«

»

mai 19

Script d’automatisation de déploiement de VMs

Bonjour à tous,

Dans le cadre d’un de mes projets de POC, j’ai été amené à developper un script capable de :

– Déployer l’ensemble des VMs

– Déployer les VMs d’une business Units

– Déployer une VMs

– Gérer les snapshot et le retour sur le dernier snapshot

– De supprimer les VMs

– De gérer l’alimentation des VMs

Voici le script :

###########################################################
# POC.ps1                                            #
# Nicolas EHRMAN - EMC Consultant - 12/11/2013 - v1.0     #
# Purpose of the script :                                 #
# Deploy a large environment automatically with the       #
# creation of a Customization and deployment of VMs       #
###########################################################

###########################################
# Connection to VCenter Server Management #
###########################################

# Connection to vCenter Server
Function ConnectVI($VCenter)
    {
        $cred=get-credential
        $vc=connect-viserver -server $VCenter -credential $cred
    }

# Disconnection from vCenter
Function DisconnectVI($VCenter)
    {
        Disconnect-viserver -server $VCenter -confirm:$false
    }

#######################
# Snapshot Management #
#######################

# Take a snapshot
Function Snapshot($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Creation of the Snapshot - Function
Function TakeSnapshot($vmname, $DEMOCode)
{
        New-Snapshot -VM $vmname -Name "Snapshot_Before_Bench"
}

# Revert to last snapshot
Function RevertSnapshot($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Revert to the last Snapshot - Function
Function RevertToLastSnapshot($vmname)
{
get-snapshot -VM $vmname -Name "Snapshot_Before_Bench" | set-vm -VM $vmname -confirm:$False
}

#######################
# Cleaning Management #
#######################

# Delete all VMs or VMs in a DEMO
Function DeleteVMs($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Delete permanently VMs in Scope
Function Delete($vmname,$vcenter)
{
        Write-Host "Attention, vous etes sur le point de supprimer definitivement des VMs." -ForegroundColor Red
        Write-Host "Etes vous sur de vouloir continuer" -ForegroundColor Red
        $Answer=Read-Host "Oui / Non"
        If ($Answer -eq "Oui")
        {
            remove-VM -VM $vmname -deletepermanently -confirm:$False
        }
        Else{
            Write-Host "Le script s'est termine." -foregroundColor Yellow
            DisconnectVI $VCenter
            exit
        }
}

#########################
# PowerState Management #
#########################

# Power Off
Function PowerOff($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Power On
Function PowerOn($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Power Off All VMs or VMs in a DEMO
Function PowerOff-VM($vmname)
{
  if((Get-VM $vmname).powerstate -eq "PoweredOff"){
    Write-Host "$vmname est deja eteinte"}
       else{
         Shutdown-VMGuest -VM (Get-VM $vmname) -Confirm:$false | Out-Null
         Write-Host "Arret de la VM $vmname"
       do {
         $status = (get-VM $vmname).PowerState
         }until($status -eq "PoweredOff")
       }
}

# Power On All VMs or VMs in a DEMO
Function PowerOn-VM($Scope)
{
    if((Get-VM $vmname).powerstate -eq "PoweredOn"){
    Write-Host "$vmname est deja demarree"}
    else{
        Start-VM -VM (Get-VM $vmname) -Confirm:$false | Out-Null
Write-Host "Demarrage de la VM $vmname"
do {
$status = (get-VM $vmname).PowerState
}until($status -eq "PoweredOn")
}
}

#####################
# Deployement Tasks #
#####################

# Deploy all VMs or only one by one DEMO
Function Deploy($Scope)
{
    ConnectVI $VCenter
    if($Scope -eq "ALL")
        {
        ParseCSVALL $Scope
        }
    ElseIf($Scope -like "DEMO*")
        {
        ParseCSVDEMOCode $Scope
        }
    ElseIf($Scope -like "Test*")
        {
        ParseCSVVM $Scope
        }
}

# Create Guest Customization
Function GuestCusto($Customization,$vc)
{
New-OSCustomizationSpec -OSType Linux -Server $vc -Name $Customization -Type NonPersistent -DnsServer $Dns -DnsSuffix $Suffix -NamingScheme VM -Domain $Domain
}

# Set IP address into Customization
Function SetIp($Customization, $IPaddress, $Netmask, $gw)
{
    Get-OSCustomizationNicMapping -OSCustomizationSpec $Customization | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $IPaddress -SubnetMask $Netmask -DefaultGateway $gw
}

# Clone VM
Function CloneVM($vmname, $VMHost, $Datastore, $template, $Customization)
{
    # No more than 10 Cloning operations at a time
    do{sleep 10}while(
    (get-task -status running |? name -eq "CloneVM_Task").count -eq 10)
    # Create the new VM from template
    $tasktab[(New-Vm -Name $vmname -VMhost $VMhost -Datastore $datastore -Template $template -OSCustomizationSpec $Customization -DiskStorageFormat $FormatDisk -RunAsync).id] = $vmname
}

######################
# Work with CSV File #
######################

# Import CSV File
Function ImportCSV()
    {
        $DEMOPOCCSV = Import-Csv C:\POC_DEMO\Deploy_POC_DEMO.csv -delimiter ";"
        return $DEMOPOCCSV
    }

# Parse CSV for DEMO Code
Function ParseCSVDEMOCode($Scope)
{
    $DEMOPOCCSV = ImportCSV
    foreach ($row in ($DEMOPOCCSV | where-object {$_.DEMOCode -eq $Scope})) {
            $vmname = $row.VmName
            $Customization = $row.Customization
            $VMhost = $row.VMhost
            $datastore = $row.Datastore
            $template = $row.Template
            $IPaddress = $row.IP
            $Netmask = $row.Netmask
            $Gw = $row.Gateway
            $DEMOCode = $row.DEMOCode
            $Dns = $row.dns
            $Suffix = $row.DNSSuffix
            $Domain = $row.Domain
            $DEMOCode = $row.DEMOCode
            $FormatDisk = $row.FormatDisk
                if($Action -eq "Deploy"){
                    GuestCusto $Customization $vc
                    SetIP $Customization $IPaddress $Netmask $gw
                    CloneVM $vmname $VMHost $Datastore $template $Customization $FormatDisk
                }
                Elseif($Action -eq "TakeSnapshot"){
                    PowerOff-VM $vmname
                    TakeSnapshot $vmname $DEMOCode
                    PowerOn-VM $vmname
                    }
                Elseif($Action -eq "Delete"){
                    Delete $vmname
                    }
                Elseif($Action -eq "PowerOff"){
                    PowerOff-VM $vmname
                    }
                Elseif($Action -eq "PowerOn"){
                    PowerOn-VM $vmname
                    }
                Elseif($Action -eq "RevertSnapshot"){
                    RevertToLastSnapshot $vmname
                    }
            }
If($DEMOCode.lenght -eq "")
    {
    write-host "Probleme avec le scope:"$Scope
    }
}

# Parse CSV for VM
Function ParseCSVVM($Scope)
{
    $DEMOPOCCSV = ImportCSV
    foreach ($row in ($DEMOPOCCSV | where-object {$_.VMname -eq $Scope})) {
            $vmname = $row.VmName
            $Customization = $row.Customization
            $VMhost = $row.VMhost
            $datastore = $row.Datastore
            $template = $row.Template
            $IPaddress = $row.IP
            $Netmask = $row.Netmask
            $Gw = $row.Gateway
            $DEMOCode = $row.DEMOCode
            $Dns = $row.dns
            $Suffix = $row.DNSSuffix
            $Domain = $row.Domain
            $DEMOCode = $row.DEMOCode
            $FormatDisk = $row.FormatDisk
                if($Action -eq "Deploy"){
                    GuestCusto $Customization $vc
                    SetIP $Customization $IPaddress $Netmask $gw
                    CloneVM $vmname $VMHost $Datastore $template $Customization $FormatDisk
                }
                Elseif($Action -eq "TakeSnapshot"){
                    PowerOff-VM $vmname
                    TakeSnapshot $vmname $DEMOCode
                    PowerOn-VM $vmname
                    }
                Elseif($Action -eq "Delete"){
                    Delete $vmname
                    }
                Elseif($Action -eq "PowerOff"){
                    PowerOff-VM $vmname
                    }
                Elseif($Action -eq "PowerOn"){
                    PowerOn-VM $vmname
                    }
                Elseif($Action -eq "RevertSnapshot"){
                    RevertToLastSnapshot $vmname
                    }
            }
If($vmname.lenght -eq "")
    {
    write-host "Probleme avec le scope:"$Scope
    }
}

# Parse CSV for All
Function ParseCSVALL($Scope,$Action)
{
    $DEMOPOCCSV = ImportCSV
    foreach ($row in $DEMOPOCCSV2) {
            $vmname = $row.VmName
            $Customization = $row.Customization
            $VMhost = $row.VMhost
            $datastore = $row.Datastore
            $template = $row.Template
            $IPaddress = $row.IP
            $Netmask = $row.Netmask
            $Gw = $row.Gateway
            $DEMOCode = $row.DEMOCode
            $Dns = $row.dns
            $Suffix = $row.DNSSuffix
            $Domain = $row.Domain
            $DEMOCode = $row.DEMOCode
            $FormatDisk = $row.FormatDisk
                if($Action -eq "Deploy"){
                    GuestCusto $Customization $vc
                    SetIP $Customization $IPaddress $Netmask $gw
                    CloneVM $vmname $VMHost $Datastore $template $Customization $FormatDisk
                }
                Elseif($Action -eq "TakeSnapshot"){
                    PowerOff-VM $vmname
                    TakeSnapshot $vmname $DEMOCode
                    PowerOn-VM $vmname
                    }
                Elseif($Action -eq "Delete"){
                    PowerOff-VM $vmname
                    Delete $vmname
                    }
                Elseif($Action -eq "PowerOff"){
                    PowerOff-VM $vmname
                    }
                Elseif($Action -eq "PowerOn"){
                    PowerOn-VM $vmname
                    }
                    Elseif($Action -eq "RevertSnapshot"){
                    PowerOff-VM $vmname
                    RevertToLastSnapshot $vmname
                    }
            }
}
###############
# Main Script #
###############

$SnapingLoaded = get-pssnapin | Where-Object{$_.name -like "*VMware*"}
If(!$SnapingLoaded){
Add-PSSnapin VMware.VimAutomation.Core
}

# HashTables

$Tasktab= @{}

if(!$args.length -eq 4)
{
    Write-host("Usage: Scriptname.ps1 deploy|takesnapshot|revertsnapshot|PowerOff|PowerOn|Delete ALL|DEMOx|VM vCenterIP@ CSVPathFile")
    }else{
    $Scope=$args[1]
    $VCenter=$args[2]
    $CSVPath=$args[3]
    $Action=$args[0]
    switch ($args[0])
    {
        Deploy{Deploy $Scope}
        TakeSnapshot{Snapshot $Scope}
        RevertSnapshot{RevertSnapshot $Scope}
        PowerOff{Poweroff $Scope}
        PowerOn{PowerOn $Scope}
        Delete{DeleteVMs $Scope}
        Default{Write-Host("L'action doit etre deploy, takesnapshot, revertsnapshot, PowerOff, PowerOn ou Delete")}
    } 

    # Start each VM who is completed
        $runningTasks = $taskTab.Count
        while($runningTasks -gt 0){
        Get-Task | % {
            if($taskTab.ContainsKey($_.Id) -and $_.State -eq "Success"){
            Get-VM $taskTab[$_.Id] | Start-VM
            $taskTab.Remove($_.Id)
            $runningTasks--
        }
        elseif($taskTab.ContainsKey($_.Id) -and $_.State -eq "Error"){
            $taskTab.Remove($_.Id)
            $runningTasks--
        }
  }
  Start-Sleep -Seconds 15
  }
}

Bien sûr, comme vous pouvez le constater, ce script s’appuie sur un fichier CSV mais on pourra imaginer quelque chose de plus poussé avec une connexion à une base de données par exemple. Ou pourquoi une fonction qui pourrait créer un nombre de VMs automatiquement en les appellant VM01 to VMXX.

Bref, je vais continuer à travailler dessus quand j’aurai du temps.

A bientôt.

Nicolas

Share

Lien Permanent pour cet article : http://www.my-v-world.fr/archives/152

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser les balises HTML suivantes : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>