DSCResources/POSHOrigin_vSphere_VM/Helpers/_CreateVM.ps1
function _CreateVM { [cmdletbinding(DefaultParameterSetName='cluster')] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$VMTemplate, [Parameter(Mandatory, ParameterSetName ='cluster')] [ValidateNotNullOrEmpty()] [string]$Cluster, [Parameter(Mandatory, ParameterSetName = 'resourcepool')] [ValidateNotNullOrEmpty()] [string]$ResourcePool, [Parameter(Mandatory, ParameterSetName = 'vmhost')] [ValidateNotNullOrEmpty()] [string]$VMHost, [Parameter(Mandatory, ParameterSetName = 'vapp')] [ValidateNotNullOrEmpty()] [string]$vApp, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$InitialDatastore, [Parameter(Mandatory)] [ValidateSet('Thick','Thin','EagerZeroedThick')] [string]$DiskFormat, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$NICSpec, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$CustomizationSpec, [string]$Folder = [string]::Empty <# [string]$IPAMFqdn, [pscredential]$IPAMCredentials #> ) try { $continue = $true $sdrs = $false # Resolve VM template $template = Get-Template -Name $VMTemplate -verbose:$false | Select-Object -First 1 if ($template -ne $null) { Write-Debug -Message "Template: $($template.Name)" } else { Write-Error -Message "Unable to resolve template $VMTemplate" $continue = $false } switch ($PSCmdlet.ParameterSetName) { 'cluster' { # Resolve cluster $viContainer = Get-Cluster -Name $Cluster -Verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($viContainer -ne $null) { Write-Debug -Message "Cluster: $($viContainer.Name)" } else { Write-Error -Message "Unable to resolve cluster [$Cluster]" $continue = $false } } 'vmhost' { # Resolve VM host $viContainer = Get-VMHost -Name $VMHost -Verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($null -ne $viContainer) { Write-Debug -Message "VMHost: $($viContainer.Name)" } else { Write-Error -Message "Unable to resolve VM host [$VMHost]" $continue = $false } } 'resourcepool' { # Resolve VM host $viContainer = Get-ResourcePool -Name $ResourcePool -Verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($null -ne $viContainer) { Write-Debug -Message "Resource Pool: $($viContainer.Name)" } else { Write-Error -Message "Unable to resolve resource pool [$ResourcePool]" $continue = $false } } 'vapp' { # Resolve vApp $viContainer = Get-VApp -Name $vApp -Verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($null -ne $viContainer) { Write-Debug -Message "vApp: $($viContainer.Name)" } else { Write-Error -Message "Unable to resolve vApp [$vApp]" $continue = $false } } } # Resolve datastore / datastore cluster $datastore = Get-Datastore -Name $InitialDatastore -verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($datastore -ne $null) { Write-Debug -Message "Datastore: $($datastore.Name)" } else { $datastore = Get-DatastoreCluster -Name $InitialDatastore -verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($datastore -ne $null) { $sdrs = $true Write-Debug -Message "Datastore cluster: $InitialDatastore" } else { Write-Error -Message "Unable to resolve datastore or datastore cluster [$InitialDatastore]" $continue = $false } } # Resolve folder to put VM into if ($Folder -ne [string]::Empty) { $vmFolder = _GetVMFolderByPath -Path $Folder -ErrorAction SilentlyContinue if (!$vmFolder) { Write-Error -Message "Unable to resolve folder [$Folder]" $continue = $false } } else { $vmFolder = $null } # Verify any IP addresses defined in configuration are not already in use # and resolve network portgroups $netConfigs = $NICSpec | ConvertFrom-Json foreach ($netConfig in $netConfigs) { # Verify the IP address(s) that we're about to set are not already in use if ($netConfig.IPAddress) { Write-Debug -Message "Pinging $($netConfig.IPAddress)" $pingable = Test-Connection -ComputerName $netConfig.IPAddress -Count 2 -Quiet if ($pingable) { Write-Error -Message "$($netConfig.IPAddress) appears to already be in use." $continue = $false } } if ($null -eq (Get-VDPortGroup -Name $netConfig.PortGroup -ErrorAction SilentlyContinue -Verbose:$false -Debug:$false)) { if ($null -eq (Get-VirtualPortGroup -Name $netConfig.PortGroup -ErrorAction SilentlyContinue -Verbose:$false -Debug:$false)) { Write-Error -Message "Unable to resolve portgroup $($netConfig.PortGroup)" $continue = $false } } } # Resolve OS customization spec $custSpec = Get-OSCustomizationSpec -Name $CustomizationSpec -Type Persistent -Verbose:$false -ErrorAction SilentlyContinue | Select-Object -First 1 if ($null -eq $custSpec) { Write-Error -Message "Unable to resolve OS customization spec $CustomizationSpec" $continue = $false } <# # If the configuration says to get an IP from IPAM # let's try to resolve that first before creating the VM $netConfigs = @(ConvertFrom-Json -InputObject $NICSpec) $custSpecInstr = @() foreach ($netConfig in $netConfigs) { if ($netConfig.IPAssignment -eq 'IPAMNextAvailable') { Write-Verbose -Message 'Attempting to reserve IP in IPAM..' $IPInfo = _RequestInfoBloxIP -Name $VM.Name -Network $netConfig.Network -GridServer $IPAMFqdn -Credential $IPAMCredentials $custSpecInstr += @{ OSCustomizationSpec = $null IpMode = 'UseStaticIp' IpAddress = $IPInfo.ipv4addr SubnetMask = $netInfo.subnetMask DefaultGateway = $netInfo.gateway Dns = $netConfig.DNSServers } } } #> $vm = $null # Do we have all the information we need to provision the VM? if ($continue) { Write-Verbose "Creating VM [$Name]" # Create VM asynchronously and get task object $t = $null $params = @{ Name = $Name Template = $template Datastore = $datastore #DiskStorageFormat = $diskFormat ResourcePool = $viContainer RunAsync = $true Verbose = $false Confirm = $false } if (-not $sdrs) { $params.DiskStorageFormat = $diskFormat } if ($null -ne $vmFolder) { $params.Location = $vmFolder } $t = New-VM @params #if ($sdrs) { # $t = New-VM -Name $Name -Template $template -Datastore $datastore -ResourcePool $clus -RunAsync -Verbose:$false -Confirm:$false #} else { # $t = New-VM -Name $Name -Template $template -Datastore $datastore -ResourcePool $clus -DiskStorageFormat $diskFormat -RunAsync -Verbose:$false -Confirm:$false #} # Wait for task to complete while ($t.State.ToString().ToLower() -eq 'running') { Write-Verbose -Message "VM creation $($t.PercentComplete)% complete" Start-Sleep -Seconds 10 $t = Get-Task -Id $t.Id -Verbose:$false -Debug:$false } $t = Get-Task -Id $t.Id -Verbose:$false -Debug:$false if ($t.State.ToString().ToLower() -eq 'success') { #$vm = Get-VM -Id $t.Result.Vm -Verbose:$false -Debug:$false $vm = Get-VM -Name $Name -Verbose:$false -Debug:$false } if ($null -eq $vm) { throw 'VM failed to create' } } else { Write-Error 'Could not resolve required VMware objects needed to create this VM' } } catch { Write-Error 'There was a problem creating the VM' Write-Error "$($_.InvocationInfo.ScriptName)($($_.InvocationInfo.ScriptLineNumber)): $($_.InvocationInfo.Line)" Write-Error $_ } return $vm } |