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
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
}
login and obtain the library resource to set a rating.