delanguageRegister | Login
fingerprint

Login

call

Contact

help

Help

VMware: Create virtual machine

2 ratings
vmwaredeployvmvirtual machinecreatevSpherePowerCli

What it does

Erstellung von virtuellen Maschinen mit VMware vSphere. Unter Angabe des Hostnamen der neuen VM, den gewünschten RAM in GB, Anzahl der vCPU und Auswahl des entsprechenden Netzwerks, wird auf Grundlage des Scripts die VM erstellt. Diese Ressource benötigt das PowerCli Module.

Description

Creating a virtual machine with some specs.

Creation Details

  • Author: Sebastian Renners
  • Created: 25.08.2020 21:34:26
  • Last modification: 09.07.2022 12:43:01
Resource Image:

Input Parameters

Name: hostname

Description: Name of the virtual machine.

Name: vCPU

Description: Number of vCPUs

Name: memory

Description: Memory in GB

Name: additionDisk1Size

Description: If you need an additional disk to the new VM, type a number of diskspace (in GB). If not, leave it blank. The primary disc depends on the template.

Name: template

Description: Choose a template

Name: vLAN

Description: Choose a vLAN.

Resource Parameters

Name: vcenteraddress

Description: Set your vCenter address in FQDN

Code

[CmdletBinding()]
Param(
    [Parameter(Mandatory=$false)]
    [string]$installPath="not-set",
    [Parameter(Mandatory=$false)]
    [string]$jobId="not-set",
    [Parameter(Mandatory=$false)]
    [string]$action="not-set"
)

$debugScript = 0;
if ($debugScript -eq 1) {
    $installPath = "C:\addy\" #Debugging
    $jobId = "INSERT-YOUR-JOB-IT-TO-DEBUG" #only for debugging #
}
#Only use TLSv1.1 and TLSv1.2
$AllProtocols = [System.Net.SecurityProtocolType]'Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols


$errorCount = 0 #counting errors. If this variable is greater than 0, the script should not run
#loading functions #this is important!
write-host "$(get-date -f  "dd.MM.yyyy HH:mm:ss") include functions"
if (test-path "$($installPath)scripts\functions.global.ps1") {
    write-host "Functions-File exists"
    import-module "$($installPath)scripts\functions.global.ps1" -force
} else {
    write-host "Functions-File do not exist. Increasing ErrorCounter." 
    $errorCount++
}
#setting the location
set-location $installPath

#generate a unique machineID #this is important
$machineId = Get-MachineId
  
#write a log online and offline
if ($debugScript -eq 0) {
    write-log2 -Message "All parameter initialized"
    #write-log -Message "All parameter initialized" -MachineId $machineId -Privatekey $privatekey -Publickey $publickey -jobId $jobId -path "$($installPath)logs\$($jobId).txt"
}
############################################
#####Handling with parameters


if ($debugScript -eq 0) {
    ### Load parameter information about this job
    $jsonBody = @{ localCurrentTime = $(get-date -f  "dd.MM.yyyy HH:mm:ss")}
    $body = (ConvertTo-Json -Depth 4 $jsonBody) 
    $resultInitializeInvoke = Invoke-RestMethod -Uri "https://admins-buddy.de/api/v1/heartbeat-consumer?action=checkforjobs&jobId=$jobId" -Method POST -Body $body -ContentType 'application/json; charset=UTF-8' -Headers @{"Publickey"="$publickey";"Privatekey"="$privatekey";"MachineId" = "$machineId"} # -Headers @{'Authorization'='Basic YWRtaW46YWRtaW4'}
    $resultInitializeInvoke   
    write-log2 -Message "Job details: $resultInitializeInvoke"


    ### Get all Parameter and payload details
    $resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingPayload.payload



    ### Get resource parameter ###
    #cast scriptParameter string
    #[string]$ParamAnyString = $resultInitializeInvoke.scriptParameter.anyString #"anyString" is definied in the Resource Parameter. This are now a parameter for this script
    #$ParamAnyString = $ParamAnyString.trim()

    #cast scriptParameter int
    #[int]$ParamaNumber = "$($resultInitializeInvoke.scriptParameter.aNumber)" #"aNumber" is definied in the Resource Parameter. This are now a parameter for this script
    
    


}
### Get some Parameter with examples
#write-host "Here your Parameter: $($resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingPayload.payload.PUTHEREYOURPARAMETERNAME)";
############################################






###################### YOUR SCRIPT STARTS HERE ############################
write-log2 -Message "Start the Script." #-Level "INFO","ERROR", "WARN"
######################################################################################################################################################################################################
######################################################################################################################################################################################################




$isPSelevated = ([Security.Principal.WindowsPrincipal] `
  [Security.Principal.WindowsIdentity]::GetCurrent() `
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)



write-log2 -Message "vmware-create-new-vm" 
write-log2 -Message "Current user: $(whoami)" 
write-log2 -Message "Powershell elevated: $($isPSelevated)" 
write-log2 -Message "Script started $(whoami)" 






#https://communities.vmware.com/community/vmtn/automationtools/powercli
$moduleResult = Get-Module -Name VMware.* | Select-Object -Property Name,Version

if (($moduleResult).count -eq 0) {
    write-log2 -Message "There are no PowerCLI modules. Load it manually" -Level "WARN"
    
    #Install-Module -name VMware.PowerCLI #run as administrator

    import-module -name VMware.PowerCli

    $moduleResult = Get-Module -Name VMware.* | Select-Object -Property Name,Version
    if (($moduleResult).count -eq 0) {
        write-log2 -Message "The Module cannot be installed. Please check it manually." -Level "ERROR"
        $errorCount++;
    }


    
} else {
    write-log2 -Message "VMware Modules loaded."
}




write-log2 -Message "Initializing resource parameter"
$addyPayloadResourceParameter = $resultInitializeInvoke.scriptParameter
[string]$vcenteraddressParameter = $addyPayloadResourceParameter.vcenteraddress #"filename" is definied in the Resource Parameter. This are now a parameter for this script
$vcenteraddressParameter = $vcenteraddressParameter.trim()



$vcenterCredentialStoreItemPath = "$($installPath)SecureStrings\vcenter-cred.xml"
if (test-path $vcenterCredentialStoreItemPath) {
    write-log2 -Message "vCenter credential file exist"
    $vcentercreds = Get-VICredentialStoreItem -file $vcenterCredentialStoreItemPath
} else {
    write-log2 -Message "vCenter credential file does not exist. You have to create one manually" -Level "ERROR"
    new-item -ItemType Directory -Path "$($installPath)SecureStrings\" -Force
    New-VICredentialStoreItem -file $vcenterCredentialStoreItemPath -Host $vcenteraddressParameter #-User "DOMAIN\USERNAME" -Password "YOUR-PASSWORD" #easier: Type your password once
    $vcentercreds = Get-VICredentialStoreItem -file $vcenterCredentialStoreItemPath
}

#Get-PowerCLIConfiguration #=> invalidCertificateAction => Unset, this is default
#Set-PowerCLIConfiguration -InvalidCertificateAction Ignore

write-log2 -Message "Setting the certificate action to ignore"
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false | out-null


#$global:DefaultVIServer
$connectionSucceeded = 0
if ($connectionSucceeded -eq 0) {
    try {
    $connectViServer = Connect-viserver -Server $vcentercreds.Host -User $vcentercreds.User -Password $vcentercreds.Password
    $ErrorMessage = ""
    #Get-VIServer -Server $VCenterServer
    #Disconnect-VIServer -Server $VCenterServer
    }
    catch {
    
    $ErrorMessage = "ErrorMessage: "+$Error[0]
    write-log2 -Message "ErrorMessage: $ErrorMessage" 


    }
    finally {
        if ($connectViServer -eq $NULL) {
            #echo "Fail $ErrorMessage"
          
            write-log2 -Message "vCenter-Login failed" -Level "ERROR"

            $connectionSucceeded = 0
            #write-host "Debug: $ErrorMessage"
        } else {
            #echo "Works $ErrorMessage"
            $connectionSucceeded = 1
            write-log2 -Message "vCenter-Login successfully" 
        
        }
    }

}







write-log2 -Message "Get job data ..." 
$VMpayload = $resultInitializeInvoke.jobDataArray.businessAutomationJobsPendingPayload.payload
write-log2 -Message "job payload initialized."
write-log2 -Message "payload: $VMpayload" 
write-log2 -Message "hostname: $($VMpayload.hostname)" 
write-log2 -Message "vCPU: $($VMpayload.vCPU)" 
write-log2 -Message "memory: $($VMpayload.memory)"
write-log2 -Message "template: $($VMpayload.template)" 
write-log2 -Message "vLAN: $($VMpayload.vLAN)" 
write-log2 -Message "additionDisk1Size: $($VMpayload.additionDisk1Size)"


if ($debugScript -eq 1) {start-sleep 5}




if (($connectionSucceeded -eq 1) -and ($errorCount -eq 0)) {

    $VMname = $($VMpayload.hostname)
    $VMhost = $(Get-VMhost).name[0] #any host
    $VMdatastore = "" #when nothing is defined, then allocate a suitable datastore
    
    
 
    $VMnumCPU = $($VMpayload.vCPU)
    $VMramGB = $($VMpayload.memory)
    $VMtemplate = $($VMpayload.template) 
    $VMvlan = $($VMpayload.vLAN)
    $VMos = "" #when noting is definied, then choose a suitable OS
    $VMadditionDisk1Size = $($VMpayload.additionDisk1Size)
    
    
    ############ VM exists check ###############
    $VMexists = get-vm -name $VMname -ErrorAction SilentlyContinue  
    if ($VMexists){  
         write-log2 -Message "VMname $VMname already exist." -Level "WARN"
         write-log2 -Message "I will generate a new name"
         $randNumber = (Get-Random -Minimum 0 -Maximum 1000)
         $VMname = "$($VMname)-$($randNumber)";
         write-log2 -Message "Creating a new VMname: $VMname"
    }  
    else {  
        write-log2 -Message "VMname $VMname does not exist in current vsphere environment." 
    } 
    
    if (($VMos -ne "Windows") -and ($VMos -ne "Linux")) {
        write-log2 -Message "Define operation system..." 
    
        if (($VMtemplate -like "*w2012*") -or ($VMtemplate -like "*w2016*") -or ($VMtemplate -like "*w2019*") -or ($VMtemplate -like "*win*")) {
            write-log2 -Message "Template sounds like Windows. Setting OS to Windows."
            $VMos = "Windows"
        }
        if (($VMtemplate -like "*ubuntu*") -or ($VMtemplate -like "*sles*") -or ($VMtemplate -like "*linux*") -or ($VMtemplate -like "*oracle*")) {
            write-log2 -Message "Template sounds like Linux. Setting OS to Linux."
            $VMos = "Linux"
        }
    
        if (($VMos.length -lt 1) -or (($VMos -ne "Windows") -and ($VMos -ne "Linux"))) {
            write-log2 -Message "Can not define OS. Setting OS to Linux." -Level "WARN"
            $VMos = "Linux"
        }
    
    }
    
    
    
    
    
    
    
    if ($VMdatastore -eq "") {
        ##############Datastores ermitteln
        #$VMos = "Windows"
        $DatastoreArray = Get-Datastore | Where-Object {$_.name -like "*$VMos*"}

        #sort the Datastores by freespace (Top 5)
        #$DatastoreArray | Sort-Object -Property FreespaceGB -Descending:$true | Select-Object -First 5
    
        #take a random Datastore
        #$DatastoreArray[(Get-Random -Maximum ([array]$DatastoreArray).count)]
        $takeVMdatastore = $DatastoreArray[(Get-Random -Maximum ([array]$DatastoreArray).count)]
    
        $VMdatastore = $takeVMdatastore.name
      
        write-log2 -Message "The following datastore will be used: $VMdatastore" 
        start-sleep 2
    }
    
    
    
    
    
    #create a new VM
    #$vmArrayCounter++ #i dont need this there
    #write-host "Machine $vmArrayCounter of $($arrayRequest.count)" 

    write-log2 -Message "Creating virtual machine" 
    write-log2 -Message "Hostname: $VMname" 
    write-log2 -Message "Template: $VMtemplate" 
    write-log2 -Message "ESX-Host: $VMhost" 
    write-log2 -Message "Datastore: $VMdatastore" 
    write-log2 -Message "vLAN: $VMvlan" 
    
    start-sleep 3
    if ($VMos -like "*linux*") {
        new-vm -name $VMname -template $VMtemplate -VMHost $VMhost -datastore $VMdatastore -OSCustomizationSpec "Linux ServerLAN (Version 1)" #if you had a customizationspec #Get-OSCustomizationSpec
    }
    if ($VMos -like "*windows*") {
        new-vm -name $VMname -template $VMtemplate -VMHost $VMhost -datastore $VMdatastore -OSCustomizationSpec "Windows ServerLAN (Version 6)" #if you had a customizationspec #Get-OSCustomizationSpec
    }
    start-sleep 2
    
    
    
    
    
    
    
    
    ####################################################### START configure the VM if an additional disk requested #########################################################
    if ($VMadditionDisk1Size -gt 0) {

        write-log2 -Message "Add additional disk (thin). Disksize in GB: $VMadditionDisk1Size" 
        sleep 5
        #get-vm -name $VMname | New-HardDisk -CapacityGB $VMadditionDisk1Size -ThinProvisioned -Datastore $VMdatastore
        get-vm -name $VMname | New-HardDisk -CapacityGB $VMadditionDisk1Size -StorageFormat Thin -Datastore $VMdatastore
    } else {
       write-log2 -Message "No additional disk requested."  
    }
    ####################################################### END configure the VM if an additional disk requested ##########################################################
    
    
    
    
    
    ####################################################### START configure the CPU, RAM and Notes #########################################################

    write-log2 -Message "Configure virtual machine components ($VMname, vCPU: $VMnumCPU, RAM: $VMramGB) and set notes." 
    start-sleep 5
    set-vm -vm $VMname -NumCpu $VMnumCPU -MemoryGB $VMramGB -confirm:$false
    start-sleep 2
    ####################################################### END configure the CPU, RAM and Notes ##########################################################
    
    
    
    
    
    
    
    
    
    
    
    
    


    
    
    
    
    
    
    
    
    
 
    
    
    
    
    
    
    
    
    
    
  



    ####################################################### START assign the requested VLAN #########################################################
    if ($VMvlan -ne "") {
        $pgVMvlan = "pg_$VMvlan" #this is your vLAN named in vSphere -> e.g. pg_vlan1 
        write-log2 -Message "Set network adapter: $pgVMvlan"

        Get-NetworkAdapter -vm $VMname | Set-NetworkAdapter -NetworkName $pgVMvlan -Confirm:$false -StartConnected:$true
        
        
    }
    ####################################################### END assign the requested VLAN #########################################################
    
    
    
    
    
    
    
    
    
    
    
    if ($VMos -eq "windows") {
        write-log2 -Message "Starting Windows VM"
        start-vm -VM $VMname
    }
    
    
    if ($VMos -eq "linux") {
        write-log2 -Message "Starting Linux VM"
        start-vm -VM $VMname
    
        start-sleep 10
    }
    
    
    
    
    
} #if connectionSucceeded
    
    




######################################################################################################################################################################################################
######################################################################################################################################################################################################
###################### YOUR SCRIPT ENDS HERE ############################


#setting the state #this is important!
if ($debugScript -eq 0) {
    write-log -Message "update state of this job to done" -MachineId $machineId -Privatekey $privatekey -Publickey $publickey -jobId $jobId -path "$($installPath)logs\$($jobId).txt"
    update-modifiedState -jobId $jobId -modifiedState "done" -publickey $publickey -privatekey $privatekey -machineId $machineId

    Start-Sleep 5 
    write-log -Message "End of script reached" -MachineId $machineId -Privatekey $privatekey -Publickey $publickey -jobId $jobId -path "$($installPath)logs\$($jobId).txt"

    Start-Sleep 1
    exit
}

Rating

login and obtain the library resource to set a rating.