I am trying to automate the vm deployement and reconfigure after deployment using OSCustomizationSpec after completion of the tasks install specific applications mentioned in the input file.
I tried to automate with the below script partially but can't achieve on few tasks. Is it possible to automate below tasks post completion of guest Customization? I have plain idea but can't write the script correctly.
Input excel file:
$defaultwindowssettings
$defaultwindowssettings :
these setting should be automated and applied to all the windows machines. using (invoke-vmscript)
power options set to never
firewall allow inbound and outbound
remote connections allow
UAC disable
create new user 'testuser' and set password 'testpassword', set only- password never expires and uncheck remaining.
add administrator and testuser to administrators groups
$defaultlinuxsettings:
these setting should be automated and applied to all the linux machines. using (invoke-vmscript)
Disable selinux,
disable networkmanager, firewall, firewalld, libvirtd, iptables
add new user 'linuxuser' user
add linuxuser to sudoers
$dnsconfig= @'
Install-WindowsFeature DNS -includeManagementTools
Add-DnsServerPrimaryZone -Name $vmsautodeploy.DNSPrimaryZone -Zonefile $vmsautodeploy.DNSPrimaryZone.dns
Add-DnsServerPrimaryZone -NetworkId $vmsautodeploy.IP -ZoneFile $vmsautodeploy.DNSPrimaryZone
Add-DnsServerResourceRecordA -Name $vmsautodeploy.vmname -IPv4Address $vmsautodeploy.IP -ZoneName $vmsautodeploy.DNSPrimaryZone -CreatePtr
'@
$ntpconfig=@'
'@
$defaultwindowssettings=@'
'@
$defaultlinuxsettings=@'
'@
$answerfile= 'C:\Users\vk185112\Desktop\answerfile.xlsx'
foreach($vmsautodeploy in Import-Excel $answerfile ){
$vmhost= (Get-Cluster $vmsautodeploy.Cluster |Get-VMHost |Get-Random|select).name
$dst= (Get-VMHost $vmhost |Get-Datastore 'LIBDatastore').Name
#| Sort-Object -Property FreespaceGB -Descending:$true | Select-Object -First 1
$vmnetwork= (Get-VirtualPortGroup -VMHost $vmhost |?{$_.VLanID -eq $vmsautodeploy.vLANID}).Name
$deploytask=@()
if($vmsautodeploy.GuestOSType -eq 'windows'){
$Chars = [Char[]]"abcdefghijklmnopqrstuvwxyz"
$RandomNameWindows = ($Chars | Get-Random -Count 😎 -join ""
$tempwindowsSpec = New-OSCustomizationSpec -OSType Windows -Name $RandomNameWindows -FullName $vmsautodeploy.UserName -AdminPassword $vmsautodeploy.Password -AutoLogonCount 1 -Workgroup 'NCR' -OrgName 'NCR' -NamingScheme vm -ChangeSid -Type NonPersistent -GuiRunOnce
$networkspecProperties = @{OSCustomizationNicMapping= Get-OSCustomizationNicMapping -OSCustomizationSpec $RandomNameWindows }
$networkspecProperties.IpMode = "UseStaticIP"
$networkspecProperties.IpAddress = $vmsautodeploy.IP
$networkspecProperties.SubNetMask = $vmsautodeploy.Subnet
$networkspecProperties.DefaultGateway = $vmsautodeploy.Gateway
$networkspecProperties.dns = "8.8.8.8"
Set-OSCustomizationNicMapping @networkspecProperties | Out-Null
$deploytask+=New-VM -Name $vmsautodeploy.VMName -Template $vmsautodeploy.Template -Host $vmhost -Datastore $dst -DiskStorageFormat Thin -OSCustomizationSpec $RandomNameWindows -Confirm:$false
Remove-OSCustomizationSpec -OSCustomizationSpec $tempwindowsSpec -Confirm:$false
Invoke-VMScript -VM $vmsautodeploy.VMName -GuestUser $vmsautodeploy.UserName -GuestPassword $vmsautodeploy.Password -ScriptText $vmsautodeploy.ServerRoles -ScriptType Powershell
#Reconfigure VM
Set-VM -VM $vmsautodeploy.VMName -MemoryGB $vmsautodeploy.Memory -NumCpu $vmsautodeploy.vCpu
Get-NetworkAdapter -VM $vmsautodeploy.VMName|Set-NetworkAdapter -NetworkName $vmnetwork -Connected:$true
Start-VM -VM $vmsautodeploy.VMName
}
else {
$Chars = [Char[]]"abcdefghijklmnopqrstuvwxyz"
$RandomNameWindowsLinux = ($Chars | Get-Random -Count 9) -join ""
$templinuxSpec = New-OSCustomizationSpec -OSType Linux -Name $RandomNameWindowsLinux -Domain 'NCR' -Type NonPersistent -ErrorAction SilentlyContinue
$networkspecProperties = @{OSCustomizationNicMapping= Get-OSCustomizationNicMapping -OSCustomizationSpec $RandomNameWindowsLinux }
$networkspecProperties.IpMode = "UseStaticIP"
$networkspecProperties.IpAddress = $vmsautodeploy.IP
$networkspecProperties.SubNetMask = $vmsautodeploy.Subnet
$networkspecProperties.DefaultGateway = $vmsautodeploy.Gateway
#$networkspecProperties.dns = "127.0.0.1"
Set-OSCustomizationNicMapping @networkspecProperties | Out-Null
$deploytask+=New-VM -Name $vmsautodeploy.VMName -Template $vmsautodeploy.Template -Host $vmhost -Datastore $dst -DiskStorageFormat Thin -OSCustomizationSpec $RandomNameWindowsLinux -Confirm:$false
Remove-OSCustomizationSpec -OSCustomizationSpec $templinuxSpec -Confirm:$false
#Reconfigure VM
Set-VM -VM $vmsautodeploy.VMName -MemoryGB $vmsautodeploy.Memory -NumCpu $vmsautodeploy.vCpu
Get-NetworkAdapter -VM $vmsautodeploy.VMName|Set-NetworkAdapter -NetworkName $vmnetwork -Connected:$true
Start-VM -VM $vmsautodeploy.VMName
Invoke-VMScript -VM $vmsautodeploy.VMName -GuestUser $vmsautodeploy.UserName -GuestPassword $vmsautodeploy.Password -ScriptText $vmsautodeploy.ServerRoles -ScriptType Powershell
}
while($deploytask.ExtensionData.Info.State -eq "running"){
Write-Progress -Activity '"$vmsautodeploy.VMName" Deployment' -Status "Progress"
sleep 1
$deploytask.ExtensionData.UpdateViewData('Info.State')
}
}
1. VMs are deploying and guestCustomization is successfully applied.
Need correction on point 2 in the script
2.Post applying guest customization I can able to Reconfigure VM using set-vm (line 35,36,37,53,54 & 55 ) and start the vm but is it possible to achieve this task using (ReconfigVM_Task) some thing as below:
$VMSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$VMSpec.NumCPUs=$vmsautodeploy.vCpu
$VMSpec.MemoryMB=$vmsautodeploy.Memory*1024
$vmsautodeploy.VMName.ExtensionData.ReconfigVM_Task($VMSpec)
3. After powering on the vm it should wait till the guestCustomization is applied (wait-task) before next task going to execute.
4.once the guest customization is applied then it should apply default setting inside the guestos ($defaultwindowssettings or $defaultlinuxsettings) using (Invoke-VMScript) and the Server role if their is any role available in the input file.
5. Once the role and vm default setting applied then it should write output VM Provision completed.
You could try something like this.
It waits for an event that indicates that the OSCustomisation completed or failed.
You will eventually need to add logic to handle that the OSCustomisation failed.
Set-VM -VM $vmsautodeploy.VMName -MemoryGB $vmsautodeploy.Memory -NumCpu $vmsautodeploy.vCpu
Get-NetworkAdapter -VM $vmsautodeploy.VMName|Set-NetworkAdapter -NetworkName $vmnetwork -Connected:$true
Start-VM -VM $vmsautodeploy.VMName
$now = Get-Date
$eventTypes = Get-VIEvent -Entity $vm -Start $now | % {$_.GetType().Name}
while ($eventTypes -notcontains 'CustomizationSucceeded' -and
$eventTypes -notcontains 'CustomizationFailed’) {
Start-Sleep -Seconds 5
$eventTypes = Get-VIEvent -Entity $vm -Start $now | % {$_.GetType().Name}
}
Invoke-VMScript -VM $vmsautodeploy.VMName -GuestUser $vmsautodeploy.UserName -GuestPassword $vmsautodeploy.Password -ScriptText $vmsaut
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That's a whole bunch of questions for 1 thread.
Wouldn't it be easier, and avoid a massive thread, by splitting this out in multiple threads?
Starting with point 2, you want to replace the Set-VM and Set-NetworkAdapter by 1 call to ReconfigVM.
Is that correct?
And what would be the reason behind that?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yeah sure. Sorry posting all questions at once I will split it into multiple thread.
for point 2:
yes looking both set of cmds in one call. If possible only!! No specific reason just to reduce multiple cmds for a single vm.
The number of lines will definitely not be less when using the ReconfigVM method.
This only changes the NumCPU and MemoryGB, and is already 4 lines.
$spec.NumCPUs = $vmsautodeploy.vCPU
$spec.MemoryMB = $vmsautodeploy.Memory * 1KB
$vm.ExtensionData.ReconfigVM($spec)
Adding the Set-NetworkAdapter in there is possible but will an additional number of lines.
And the Start-VM will also requires some lines.
Are you sure you want to do this?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ok I will continue with the same lines rather then going with reconfigVM
How to write wait till guest customization completes in below lines.
- #Reconfigure VM
- Set-VM -VM $vmsautodeploy.VMName -MemoryGB $vmsautodeploy.Memory -NumCpu $vmsautodeploy.vCpu
- Get-NetworkAdapter -VM $vmsautodeploy.VMName|Set-NetworkAdapter -NetworkName $vmnetwork -Connected:$true
- Start-VM -VM $vmsautodeploy.VMName
- Invoke-VMScript -VM $vmsautodeploy.VMName -GuestUser $vmsautodeploy.UserName -GuestPassword $vmsautodeploy.Password -ScriptText $vmsautodep
You could try something like this.
It waits for an event that indicates that the OSCustomisation completed or failed.
You will eventually need to add logic to handle that the OSCustomisation failed.
Set-VM -VM $vmsautodeploy.VMName -MemoryGB $vmsautodeploy.Memory -NumCpu $vmsautodeploy.vCpu
Get-NetworkAdapter -VM $vmsautodeploy.VMName|Set-NetworkAdapter -NetworkName $vmnetwork -Connected:$true
Start-VM -VM $vmsautodeploy.VMName
$now = Get-Date
$eventTypes = Get-VIEvent -Entity $vm -Start $now | % {$_.GetType().Name}
while ($eventTypes -notcontains 'CustomizationSucceeded' -and
$eventTypes -notcontains 'CustomizationFailed’) {
Start-Sleep -Seconds 5
$eventTypes = Get-VIEvent -Entity $vm -Start $now | % {$_.GetType().Name}
}
Invoke-VMScript -VM $vmsautodeploy.VMName -GuestUser $vmsautodeploy.UserName -GuestPassword $vmsautodeploy.Password -ScriptText $vmsaut
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks This is working