Overblog Tous les blogs Top blogs Technologie & Science Tous les blogs Technologie & Science
Editer l'article Suivre ce blog Administration + Créer mon blog
MENU

Deploy Windows Server 2008 or higher in vCenter script

Publié le par damcuvelier

Set a CSV file with informations:
Domain    vCenterInstance    Cluster    VMTemplate    CustomSpec    Location    DataStore    DiskStorageFormat    NetworkName    Memory    CPU    DiskCapacity    SubnetLength    GW    IP_DNS    Hostname    IP    JoinDomainYN


Deploy Windows Server 2008 or higher in vCenter script:

#### USER DEFINED VARIABLES ############################################################################################
$VMs = import-csv "C:\VM.csv"

### FUNCTION DEFINITIONS ################################################################################################
Function Check-CustomizationStarted([string] $VM)
{
    Write-Host "Verifying that Customization for VM $VM has started"
    $i=60 #time-out of 5 min
while($i -gt 0)
{
$vmEvents = Get-VIEvent -Entity $VM
$startedEvent = $vmEvents | Where { $_.GetType().Name -eq "CustomizationStartedEvent" }
if ($startedEvent)
{
            Write-Host  "Customization for VM $VM has started"
return $true
}
else
{
Start-Sleep -Seconds 5
            $i--
}
}
    Write-Warning "Customization for VM $VM has failed"
    return $false
}

Function Check-CustomizatonFinished([string] $VM)
{
    Write-Host  "Verifying that Customization for VM $VM has finished"
    $i = 60 #time-out of 5 min
while($true)
{
$vmEvents = Get-VIEvent -Entity $VM
$SucceededEvent = $vmEvents | Where { $_.GetType().Name -eq "CustomizationSucceeded" }
        $FailureEvent = $vmEvents | Where { $_.GetType().Name -eq "CustomizationFailed" }
if ($FailureEvent -or ($i -eq 0))
{
Write-Warning  "Customization of VM $VM failed"
            return $False
}
if ($SucceededEvent)
{
            Write-Host  "Customization of VM $VM Completed Successfully"
            Start-Sleep -Seconds 30
            Write-Host  "Waiting for VM $VM to complete post-customization reboot"
            Wait-Tools -VM $VM -TimeoutSeconds 300
            Start-Sleep -Seconds 30
            return $true
}
        Start-Sleep -Seconds 5
        $i--
}
}

Function Restart-VM([string] $VM)
{
    Restart-VMGuest -VM $VM -Confirm:$false | Out-Null
    Write-Host "Reboot VM $VM"
    Start-Sleep -Seconds 60
    Wait-Tools -VM $VM -TimeoutSeconds 300 | Out-Null
    Start-Sleep -Seconds 10
}

function Add-Script([string] $script,$parameters=@(),[bool] $reboot=$false){
    $i=1
    foreach ($parameter in $parameters)
    {
        if ($parameter.GetType().Name -eq "String") {$script=$script.replace("%"+[string] $i,'"'+$parameter+'"')}
        else                                        {$script=$script.replace("%"+[string] $i,[string] $parameter)}
        $i++
    }
    $script:scripts += ,@($script,$reboot)
}

Function Test-IP([string] $IP)
{
  if (-not ($IP) -or (([bool]($IP -as [IPADDRESS])))) { return $true} else {return $false}
}

ForEach ($VM in $VMs){
$Domain = $($VM.Domain)     #AD Domain to join
$vCenterInstance = $($VM.vCenterInstance)     #vCenter to deploy VM
$Cluster = $($VM.Cluster)     #vCenter cluster to deploy VM
$VMTemplate = $($VM.VMTemplate)     #vCenter template to deploy VM
$CustomSpec = $($VM.CustomSpec)     #vCenter customization to use for VM
$Location = $($VM.Location)     #Folderlocation in vCenter for VM
$DataStore = $($VM.DataStore)     #Datastore in vCenter to use for VM
$DiskStorageFormat = $($VM.DiskStorageFormat)     #Diskformtat to use (Thin / Thick) for VM
$NetworkName = $($VM.NetworkName)     #Portgroup to use for VM
$Memory = $($VM.Memory)     #Memory of VM In GB
$CPU = $($VM.CPU)     #number of vCPUs of VM
$DiskCapacity = $($VM.DiskCapacity)     #Disksize of VM in GB
$SubnetLength = $($VM.SubnetLength)     #Subnetlength IP address to use (24 means /24 or 255.255.255.0) for VM
$GW = $($VM.GW)     #Gateway to use for VM
$IP_DNS = $($VM.IP_DNS)     #IP address DNS server to use
$Hostname = $($VM.Hostname)     #Hostname of VM
$IP = $($VM.IP)     #IP address of VM
$JoinDomainYN = $($VM.JoinDomainYN)     #Join domain or not?

#### USER INTERACTIONS ##############################################################################################
cls
Write-host "Deploy Windows server" -foregroundcolor red
if (!$Hostname){$Hostname = Read-Host -Prompt "Hostname"}
If ($Hostname.Length -gt 15) {write-Host -ForegroundColor Red "$Hostname is an invalid hostname"; break}
if (!$IP){$IP = Read-Host -Prompt "IP Address (press ENTER for DHCP)"}
If (-not (Test-IP $IP)) {write-Host -ForegroundColor Red "$IP is an invalid address"; break}
if (!$JoinDomainYN){$JoinDomainYN = Read-Host "Join Domain $Domain (Y/N)"}

### READ CREDENTIALS ########################################################################################################
Get-Content credentials.txt | Foreach-Object{
   $var = $_.Split('=')
   Set-Variable -Name $var[0].trim('" ') -Value $var[1].trim('" ')
}
$VMLocalUser = "$Hostname\$LocalUser"
$VMLocalPWord = ConvertTo-SecureString -String $LocalPassword -AsPlainText -Force
$VMLocalCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $VMLocalUser, $VMLocalPWord

### CONNECT TO VCENTER ##############################################################################################
Get-Module -ListAvailable VMware* | Import-Module | Out-Null
Connect-VIServer -Server $vCenterInstance -User $vCenterUser -Password $vCenterPass -WarningAction SilentlyContinue
$SourceVMTemplate = Get-Template -Name $VMTemplate
$SourceCustomSpec = Get-OSCustomizationSpec -Name $CustomSpec

### DEFINE POWERSHELL SCRIPTS TO RUN IN VM AFTER DEPLOYMENT ############################################################################################################
if ($IP) {
Add-Script "New-NetIPAddress -InterfaceIndex 2 -IPAddress %1 -PrefixLength %2 -DefaultGateway %3" @($IP, $SubnetLength, $GW)
Add-Script "Set-DnsClientServerAddress -InterfaceIndex 2 -ServerAddresses %1" @($IP_DNS) }
if ($JoinDomainYN.ToUpper() -eq "Y") {
Add-Script '$DomainUser = %1;
            $DomainPWord = ConvertTo-SecureString -String %2 -AsPlainText -Force;
            $DomainCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $DomainUser, $DomainPWord;
             Add-Computer -DomainName %3 -Credential $DomainCredential' @("$Domain\$DomainAdmin",$DomainAdminPassword, $Domain) $true }
Add-Script 'Import-Module NetSecurity; Set-NetFirewallRule -DisplayGroup "File and Printer Sharing" -enabled True'
Add-Script 'Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -name fDenyTSConnections -Value 0;
            Enable-NetFirewallRule -DisplayGroup "Remote Desktop";
            Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -name UserAuthentication -Value 0'

### DEPLOY VM ###############################################################################################################################################################
Write-Host "Deploying Virtual Machine with Name: [$Hostname] using Template: [$SourceVMTemplate] and Customization Specification: [$SourceCustomSpec] on cluster: [$cluster]"
New-VM -Name $Hostname -Template $SourceVMTemplate -ResourcePool $cluster -OSCustomizationSpec $SourceCustomSpec -Location $Location `
  -Datastore $Datastore -DiskStorageFormat $DiskStorageFormat | Out-Null
Get-VM $Hostname | Get-NetworkAdapter | Set-NetworkAdapter -Portgroup $NetworkName -confirm:$false | Out-Null
Set-VM -VM $Hostname -NumCpu $CPU -MemoryGB $Memory -Confirm:$false | Out-Null
Get-VM $Hostname | Get-HardDisk | Where-Object {$_.Name -eq "Hard Disk 1"} | Set-HardDisk -CapacityGB $DiskCapacity -Confirm:$false | Out-Null

Write-Host "Virtual Machine $Hostname Deployed. Powering On"
Start-VM -VM $Hostname | Out-Null

if (-not (Check-CustomizationStarted $Hostname)) { break }; if (-not (Check-CustomizatonFinished $Hostname)) { break }

foreach ($script in $scripts)
{
    Invoke-VMScript -ScriptText $script[0] -VM $Hostname -GuestCredential $VMLocalCredential | Out-Null
    if ($script[1]) {Restart-VM $Hostname}
}

### End of Script ##############################
Write-Host "Deployment of VM $Hostname finished"
}

Commenter cet article