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