Créer des VM en MASSE via script !!

Avant propos :

Ce script est « fait maison » et avec le cœur. Oui, il n’est pas parfait et oui, il y a surement des optimisations à faire, mais il fonctionne et surtout j’y ai passé du temps dessus…
Je suis ouvert à toute proposition d’amélioration, dans le respect bien-sur ! sinon allez vous faire … 🙂

Version :
V1 – Diffusion 10/04/2019

Prérequis :

  • PowerCLI sur le serveur ou PC allant lancer le script
  • Un compte ayant les droits de création de machine virtuelle
  • Un profil de machine virtuelle (vous savez, le « truc » que personne n’utilise dans le vCenter nommé « Gestionnaire de spécification de personnalisation » )
  • Un Template parfait (voir mon autre article « Comment créer une machine virtuelle)

Que va faire le script ?

  1. Se connecter au vCenter
  2. Chercher si les machines virtuelles existent déjà
  3. Créer X machines virtuelles via un template et un profil de VM sur un host aléatoire en fonction du nombre de Host disponible (mention spéciale aux personnes n’ayant pas le DRS de configuré :p )
  4. Vous informer de l’avancement des tâches de création
  5. Les démarrer après création afin que le profil de VM s’applique.

J’insiste sur le fait que le Profil de VM doit être créé et configuré. C’est simple à faire depuis le vCenter, et c’est un gain de temps considérable pour la configuration des machines virtuelles après création.

Pour rappel : le Profil de VM permet de configurer la machine virtuelle dès le premier démarrage de celle-ci. On peut configurer le hostname, la licence, la configuration réseau, joindre la VM au domaine etc ….. !

Le Script :

j’ai commenté suffisamment le script pour qu’il soit facile à lire et modifier. Dans cette exemple ci dessous, je l’applique à un environnement VDI (ce qui explique le nom des VM) mais cela fonctionne aussi dans un environnement standard…)

Les variables :

Les variables à modifier OBLIGATOIREMENT sont :


$vcenterXBI ##le nom d'hôte ou IP du VCENTER
$datastoreXBI ##Variable pour le Datastore de destination de l'ensemble des futurs VMs
$nbreHoteXBI ##Nombre d'hote ESX dans le cluster
$modeleXBI ##Le modèle de base (template obligatoire)
$poolVMXBI ##Nom du pool de ressource, pas obligatoire, vous pouvez supprimer si jamais
$personnalisationXBI ##Fichier de personnalisation créé depuis le vcenter (vous savez le fameux "Gestionnaire de spécification de personnalisation"
$nomVMXBI ##Nom des futurs VM, le {0} corresponds au numéro, exemple "maison{0}" va créer maison1, maison2 etc...

Le script complet :


Clear
Add-PSSnapIn VMware.VimAutomation.Core  #powercli
####### VARIABLES #######
$vcenterXBI = "nom du vcenter"                               ##le nom d'hôte ou IP du VCENTER
$userXBI = Read-Host -Prompt "Nom d'utilisateur"             ##Prompt pour l'utilisateur
$passwordXBI = Read-Host -Prompt "mot de passe"              ##Prompt pour le mot de passe
$datastoreXBI = "vsanDatastore"                              ##Variable pour le Datastore de destination de l'ensemble des futurs VMs
$nbreHoteXBI = "4"                                           ##Nombre d'hote ESX dans le cluster
$modeleXBI = "VDI-2k12-GOLD"                                  ##Le modèle de base (template)
$nombreVMXBI = Read-Host -Prompt "Nombre de VM à cloner ?"   ##Prompt pour le nombre de VM à créer
$poolVMXBI = "VDI-2K12"                                        ##Nom du pool de ressource, pas obligatoire, vous pouvez supprimer si jamais
$personnalisationXBI = 'Windows2k8-VDI'                      ##Fichier de personnalisation créé depuis le vcenter
$nomVMXBI = "VDI-TEST-{0}"                                   ##Nom des futurs VM, le {0} corresponds au numéro, exemple "maison{0}" va créer maison1, maison2 etc...  
###### FIN DES VARIABLES #######

Connect-VIServer -Server $vcenterXBI -User $userXBI -Password $passwordXBI
$spec = Get-OSCustomizationSpec -Name $personnalisationXBI

function creation {
    1..$nombreVMXBI | foreach{
        $vmNom = $nomVMXBI -f $_
        $vm = Get-VM -Name $vmNom
            if ($vm) {
                "{0} exists" -f $vmNom
                Write-Host "Machines existent déjà" -ForegroundColor Red
                exit
                Disconnect-VIServer -Confirm:$false
                     }
            else {
                $numHost = get-random -Maximum $nbreHoteXBI         ##genere un nombre         
                $esx = (Get-VMHost)[$numHost]                    ##selectionnne un hote en fonction du nombre au dessus
                $esx | New-VM -Name $vmNom -Template $modeleXBI -Datastore $datastoreXBI -OSCustomizationSpec $spec -ResourcePool $poolVMXBI -RunASync
                 }
}
}
Clear
function log {
              Do {
              Clear
              Get-Task | Where-Object { $_.name -eq "CloneVM_Task" -and $_.State -eq "Running"} | Format-Table
              sleep 10
              Clear
}
              until ((Get-Task | Where-Object { $_.name -eq "CloneVM_Task" -and $_.State -eq "Running"}) -eq $Null)}

function StartdesVM {
    1..$nombreVMXBI | foreach{
                          $vmNom = $nomVMXBI -f $_ 
                          Start-VM -VM $vmNom
                          sleep 3
                          }
}

creation #fonction de creation des VM
log #fonction de log interractif
StartdesVM #demarrage des VM

Write-Host "Machines virtuelles crées et démarrées, merci de patienter le temps que le profil de VM s'applique !" -ForegroundColor Yellow
Disconnect-VIServer -Confirm:$false

Résultat :

J’ai lancé la création de trois machines virtuelles :

Pendant la création des VM :

A la fin de l’exécution du script :

Sur mon pool de ressource dans le vCenter :


Chiffrer le Mot de Passe pour la connexion au VCenter via Powercli (Powershell)

Pourquoi ?

La question ne se pose même pas, un mot de passe en clair dans un script, c’est dégueulasse.
Attention : Je ne propose pas non plus la solution ultime en matière de sécurité mais cela restera plus « propre » qu’un mot de passe visible dans le script.

Pré requis :

Le Script :

#Variables
$vcenter = "LE FQDN DE VOTRE VCENTER"
$credfile = ".\credfile2.xml"
$user = Read-Host -Prompt "Nom d'utilisateur, exemple CONSO.ORG\Admin"
$Pass = Read-Host -Prompt "le mot de passe" -AsSecureString
#Génération du fichier
Add-PSSnapIn VMware.VimAutomation.Core
New-VICredentialStoreItem -host $vcenter -user $user -password $Pass -file $credfile

Le principe :

Le script en Powershell va générer un fichier de configuration en XML contenant le login en clair 🙁 mais le mot de passe chiffré.
Le fichier XML se trouvera à l’emplacement du script.

Lors de l’exécution du script, il faudra rentrer le login et mot de passe

Le Fichier XML peut être utilisé lors de votre script nécessitant une connexion au vcenter via la commande
Get-VICredentialStoreItem -file "chemin vers le fichier XML généré"

!!!! Attention, ce fichier XML ne doit être accessible que par vous, ou un compte ayant besoin de lire le fichier, ne négligez pas son stockage !!!!

Lister les Machines Virtuelles comportant des snapshots

Pourquoi ?

Mais Xavier ! Qu’elle est l’intérêt de faire un script qui liste les VM ayant des snapshots, sachant qu’il existe des outils comme RVTOOLS ou des solutions « packagés » comme VeeamONE ?!!!
Réponse :
– Ca coute rien (ou juste du temps)
– On peut planifier le script pour avoir un rapport Hebdo (contrairement à RVTOOL)
– Le PowerShell c’est bien

Pré requis :

Le Script :

#Variables
$vcenter = "LE FQDN DU VCENTER"
#le credfile correspond au fichier XML généré lors du précédent tuto (voir prérequis)
$credfile = ".\credfile.xml"
$creds = Get-VICredentialStoreItem -file $credfile
$smtp = "adresse du SMTP"
$to = "adresse du destinataire"
$from = "vcenter@votredomain.fr"
$subject = "Rapport Hebdo : Liste des serveurs avec snapshots"
$file = ".\snapshot.htm"
$date = Get-Date

#Chargement du module VMWARE
Add-PSSnapin VMware.VimAutomation.Core

#Connexion au vcenter
$creds = Get-VICredentialStoreItem -file $credfile
Connect-VIServer -Server $vcenter -User $creds.User -Password $creds.Password
#Lister les VM et les snapshots
Get-VM | Where-Object { $_.Name -notlike '*.repl*' -and $_.Name -notlike '*_replica*'} | get-snapshot | sort SizeMB | Format-Table vm,name,SizeMB,created | Out-File -FilePath $file
If ((Get-Content $file) -eq $Null) {
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nAucun Snapshot trouve" +  (Get-Content "$file") | Set-Content "$file")
}
else
{
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nCi dessous la liste :" +  (Get-Content "$file") | Set-Content "$file")
}
Add-Content -Path $file -Value "`r` Rapport fait le $date `r`Copyright : Xavier BIANCHI"
$body = Get-Content $file | Out-String
Send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -attachment $file -Body $body -Priority high

Explication du script :

1) Le script se connecte au Vcenter via le fichier credential précédemment généré.
$creds = Get-VICredentialStoreItem -file $credfile
Connect-VIServer -Server $vcenter -User $creds.User -Password $creds.Password
2) Il va lister les VM qui ne comporte pas le sufixe « _repl » « _replica » via cette chaîne :
Get-VM | Where-Object { $_.Name -notlike '*.repl*' -and $_.Name -notlike '*_replica*'}
3) Puis via un pipe, le script va lister les snapshots présent sur cette liste de VM
get-snapshot | sort SizeMB | Format-Table vm,name,SizeMB,created | 
4) Sortie vers un fichier htm :
Out-File -FilePath $file
5) Le fichier de sortie est ensuite analyser afin de voir si il est vide. Si il est vide (donc pas de snapshots), il va écrire dans ce même fichier qu’il n’y a pas de snapshot :
If ((Get-Content $file) -eq $Null) {
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nAucun Snapshot trouve" +  (Get-Content "$file") | Set-Content "$file")
}
6) Si le fichier de sortie n’est pas vide ALORS :
else
{
@("Rapport Hebdo des snapshot en cours (hors replica)" , "`r`nCi dessous la liste :" +  (Get-Content "$file") | Set-Content "$file")
}
7) L’envoi par Email :
Send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -attachment $file -Body $body -Priority high