Skip to content

Instantly share code, notes, and snippets.

@baradhiren
Last active Dec 21, 2020
Embed
What would you like to do?
A PowerShell script to deploy VMs, Rename them, Power them off etc. etc. It can also download builds from your distribution site and extract them from gzipped or tar formats. You might need to tweak a little for your setup. :)
####################################################################################################################
#   #
#    SCRIPT NAME        : Handle_VMs.ps1 #
# #
#    DESCRIPTION        : Here are the things that this script can do: #
# 1. Download build for given version, Extract it and delete the compressed files #
# 2. Generate log file #
# 3. Deploy VM with Given IP and downloaded OVF File #
# 4. Force parameter to power off and rename any existing VMs with same IP #
# 5. Generates logs based on Date and deletes older than given limit of days #
# #
#    AUTHOR             : Hiren Barad #
# #
#    CREATION DATE      : 25/08/2018 #
# #
# VERSION : 1.0 # #
#------------------------------------------------------------------------------------------------------------------#
#             R E V I S I O N    H I S T O R Y #
#------------------------------------------------------------------------------------------------------------------#
#     REVISED DATE    :     REVISED BY     :    CHANGE DESCRIPTION #
#------------------------------------------------------------------------------------------------------------------#
# 13/09/2018 Hiren Barad Incorporated Build downloading features #
# #
####################################################################################################################
$Global:BuildLocation = "C:\Users\$env:USERNAME\Downloads\Downloaded Builds\"
$LimitToDeleteLogs = (Get-Date).AddDays(-15)
$logFile = $Global:BuildLocation + "VMDeployment$(Get-Date -f yyyy-MM-dd).log"
[string]$Global:distSite=Distribution site URL if you are downloading your builds from somewhere
[string]$Global:distSiteUsername=Distribution site username if you have authentication in place
[string]$Global:distSitePassword=Distribution site Password if you have authentication in place
[string]$Global:vCenterURL= vCenter URL
[string]$Global:vCenterUsername = vCenter Username and Password
[string]$Global:vCenterPassword = vCenter Password
[bool]$Global:ForceParameter= $false #Keep this as true if you want to poweroff existing VMs and deploy your VM forcefully
[string]$Global:HostName = Hostname where your VM will be deployed
[string]$Global:DataStoreName = Data storename
[string]$Global:ResourcePoolName = Network name
#These fields are part of your OVF configuration file and might change from OVF to OVF
[string]$Global:DNS1 =
[string]$Global:DNS2 =
[string]$Global:Gateway =
[string]$Global:NetMask =
[string]$Global:NetworkName =
[string]$Global:RootPassword =
######################################################### Logger ###############################################################
Function Set-LogInfo{
Param(
[string]$infostatus,
[string]$topicName,
[string]$info
)
"$infostatus [$((Get-Date).ToString())] $topicName`t: $info" | Out-File $logFile -Append
Write-Host "$infostatus [$(Get-Date -Format "dd-MM-yyyy hh:mm:ss")] $topicName : $info"
}
#################################################### Requirements Start #########################################################
function copyDependencies{
$PowershellModules = "C:\Users\$env:USERNAME\Documents\WindowsPowerShell\Modules"
$pathToModule = "$PowershellModules\7Zip4Powershell\1.9.0\7Zip4PowerShell.psd1"
if(!$(Test-Path -Path $PowershellModules)){
md "C:\Users\$env:USERNAME\Documents\WindowsPowerShell\Modules"
}
$dependencies = Get-ChildItem "$PSScriptRoot\Dependencies" | Select-Object -ExpandProperty Name
$modsinModulesdir = Get-ChildItem $PowershellModules | Select-Object -ExpandProperty Name
foreach($a in $dependencies){
if(!($a -in $modsinModulesdir)){
Copy-Item -Path "$PSScriptRoot\Dependencies\$a" $PowershellModules
}
}
if(!$(Get-VIToolkitVersion -ErrorAction Ignore)){
Copy-Item -Path "$PSScriptRoot\Dependencies\*" $PowershellModules
}
elseif(-not (Get-Command Expand-7Zip -ErrorAction Ignore)){
Copy-Item -Path "$PSScriptRoot\Dependencies\7Zip4Powershell" $PowershellModules
}
if(-not (Get-Command Expand-7Zip -ErrorAction Ignore)){
Import-Module $pathToModule
}
}
copyDependencies
#################################################### Requirements End #########################################################
#################################################### Reusables Start #########################################################
Function validatePath{
Param(
[parameter(
Mandatory = $True)]
[string]$Path
)
if(Test-Path -Path $Path)
{
return $True
}else{
return $false
}
}
#Validate if given IP is correct or not
Function validateIP{
Param(
[parameter(
Mandatory = $True)]
[string]$IP
)
$IPValid = "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}"
if($IP -match $IPValid){
return $True
}else{
return $false
}
}
#extractBuild version from build name
Function extractVersion{
Param(
[parameter(
Mandatory = $True)]
[string]$buildFullName
)
$buildName = $buildFullName.Split("-")[1]
$buildName = $buildName -replace '.ovf.tar.gz$',''
return $buildName
}
#Check if folder exists or not
Function createFolder{
Param(
[parameter(
Mandatory = $True)]
[string]$folderPath
)
if(!(validatePath -Path $folderPath))
{
New-Item -ItemType directory -Path $folderPath
}
}
#Delete unnecessary files
#Delete unnecessary files
Function deletegZippedFiles{
Param(
[parameter(
Mandatory = $True)]
[string]$folderPath
)
Get-ChildItem $folderPath | Where{$_.Name -Match ".gz$"} | Remove-Item
}
Function deleteTarFiles{
Param(
[parameter(
Mandatory = $True)]
[string]$folderPath
)
Get-ChildItem $folderPath | Where{$_.Name -Match ".tar$"} | Remove-Item
}
#Clear out folder if the size increases more than 5GB
Function manageFolderSize{
Param(
[parameter(
Mandatory = $True)]
[string]$folderPath
)
$Filter = "*.vmdk"
$MaxSize = 5120 #Size in MB
$OldestFile = Get-ChildItem $folderPath -Filter $Filter | Sort LastWriteTime | Select -First 1
$FolderCurrentSize = (Get-ChildItem $folderPath -recurse | Measure-Object -property length -sum).sum / 1MB
if($FolderCurrentSize -GT $MaxSize)
{
Write-output "Deleting File $OldestFile, becuase the Current folder size $FolderCurrentSize MB, has exceeded the maximum size of $MaxSize MB"
Remove-Item $OldestFile.parent.parent.FullName
}
}
#################################################### Reusables End #########################################################
#################################################### Authentication Start #########################################################
#This funtion returns valid credentials to access Build distribution website
Function Get-BuildSiteCreds{
Param(
[string]$Username=$Global:distSiteUsername,
[string]$Password = $Global:distSitePassword
)
$PassAsSecureString = ConvertTo-SecureString $Password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$PassAsSecureString
#Set-LogInfo -infostatus "INFO" -topicName "CREDENTIALS" -info "User credentials generated successfully."
return $cred
}
Function ConnectToVcenter{
Param(
$URL = $Global:vCenterURL,
[string]$Username=$Global:vCenterUsername,
[string]$Password = $Global:vCenterPassword
)
if(!$($global:DefaultVIServers.count -eq 1)){
try{
$result = Connect-VIServer -Server $URL -User $Username -Password $Password -ErrorAction Stop
if($result){
Set-LogInfo -infostatus "INFO" -topicName "LOGIN" -info "Logged in to $URL"
}}catch{
$ErrorMessage = $_.Exception.Message
Set-LogInfo -infostatus "ERROR" -topicName "LOGIN" -info $ErrorMessage
throw 401
}
}
}
#Disconnect from vCenter
Function disconnectFromvCenter{
Set-LogInfo -infostatus "INFO" -topicName "LOGOUT" -info "Signing out from $vCenterURL."
if($global:DefaultVIServers.count -eq 1){
Disconnect-VIServer -confirm:$false -ErrorAction Stop
}
Set-LogInfo -infostatus "INFO" -topicName "LOGOUT" -info "Signed out from $vCenterURL."
}
#################################################### Authentication End #########################################################
#################################################### Build Download Features Start #########################################################
#Check if build is already downloaded in the downloads folder
Function checkBuildalreadyDownloaded{
Param(
[parameter(
Mandatory = $True)]
[string]$buildVersion,
[string]$buildPath
)
if(!(Test-Path -Path $buildPath)){
createFolder -folderPath $buildPath
}
$buildName = Get-ChildItem -Path $buildPath | Where-Object { $_.Name -match $buildVersion } | Select-Object -ExpandProperty Name
if($buildName){
return $buildName
}
return 1
}
#This function returns latest build names of given type
Function checkForAvailableBuilds{
Param(
[parameter(
Mandatory = $True)]
[string]$version="",
[string]$distributionSite=$Global:distSite,
[string]$distributionSiteUsername = $Global:distSiteUsername,
[string]$distributionSitePassword = $Global:distSitePassword
)
try{
#Defining Distribution Portal url and getting credentials
$URL = $distributionSite
$creds = Get-BuildSiteCreds -Username $distributionSiteUsername -Password $distributionSitePassword
$buildName = @()
#Fetching the URL to download links with given type
$type = ".ovf.tar.gz"
if($version -ne ""){
$links = (Invoke-WebRequest -Uri $URL -Credential $creds).Links | Where href -Like "*$type" | Where href -Like "*$version*" | Select-Object -ExpandProperty href
}else{
$links = (Invoke-WebRequest -Uri $URL -Credential $creds).Links | Where href -Like "*$type" | Select-Object -ExpandProperty href
}
$filestoGet = $links.Count
if($filestoGet -eq 1){
$buildName = $links.split("/")[1]
}
else{
while($filestoGet -gt 0)
{
$link = $links[$filestoGet-1]
$link = $link.split("/")[1]
$buildName += $link
$filestoGet -= 1
}
}
if($buildName.Count -gt 1){
Write-Host "Found multiple builds with same version please select which build to Download:"
$i=0
foreach($name in $buildName){
Write-Host "$($i+1). $name"
$i += 1
}
$correctInput= $false
while(!$correctInput){
try{
[int]$userschoice = Read-Host -Prompt "Please enter a valid number from above:"
if($userschoice -le 0 -or $userschoice -gt $buildName.Count)
{
$correctInput = $false
}else{
$correctInput = $true
}
}catch{
$correctInput = $false
}
}
$buildName = $buildName[$userschoice-1]
}else{
$buildName = $buildName
}
return $buildName
}catch{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Set-LogInfo -infostatus "ERROR" -topicName "QUERY BUILDS" -info "No builds found with that type"
}
}
#Download given build
Function downloadBuild{
Param(
[parameter(
Mandatory = $True)]
[string]$buildName,
[string]$downloadPath=$Global:BuildLocation
)
try{
$URL = $Global:distSite
$creds = Get-BuildSiteCreds -Username $Global:distSiteUsername -Password $Global:distSitePassword
#Fetching the URL to download links with given type
Set-LogInfo -infostatus "INFO" -topicName "BUILD DOWNLOAD" -info "Figuring out the requested build type."
$link = (Invoke-WebRequest -Uri $URL -Credential $creds).Links | Where href -Like "*$buildName*" | Select-Object -ExpandProperty href
$file = $link.split("/")[1]
$link = $URL + $link
Set-LogInfo -infostatus "INFO" -topicName "BUILD DOWNLOAD" -info "Build with name $buildName found successfully."
Set-LogInfo -infostatus "INFO" -topicName "BUILD INFO" -info "Downloading build with name $buildName............."
Invoke-WebRequest -Uri $link -Credential $creds -OutFile $downloadPath/$file
Set-LogInfo -infostatus "INFO" -topicName "BUILD DOWNLOAD" -info "Build $buildName downloaded successfully."
}catch{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Set-LogInfo -infostatus "ERROR" -topicName "BUILD DOWNLOAD" -info $ErrorMessage
Set-LogInfo -infostatus "ERROR" -topicName "BUILD DOWNLOAD" -info $FailedItem
}
}
#Extract from GZ compression
Function DeGZip-File{
Param(
$infile,
$outfile = ($infile -replace '\.gz$','')
)
$input = New-Object System.IO.FileStream $infile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$output = New-Object System.IO.FileStream $outfile, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
$gzipStream = New-Object System.IO.Compression.GzipStream $input, ([IO.Compression.CompressionMode]::Decompress)
$buffer = New-Object byte[](1024)
while($true){
$read = $gzipstream.Read($buffer, 0, 1024)
if ($read -le 0){break}
$output.Write($buffer, 0, $read)
}
$gzipStream.Close()
$output.Close()
$input.Close()
}
#Extract TAR File
Function Expand-Tar{
Param(
$infile,
$outfile = ($infile -replace '\.tar$','')
)
if (-not (Get-Command Expand-7Zip -ErrorAction Ignore))
{
copyDependencies
}
Expand-7Zip $infile $outfile
deletegZippedFiles -folderPath $Global:BuildLocation
deleteTarFiles -folderPath $Global:BuildLocation
}
#################################################### Build Download Features End #########################################################
#################################################### VM Deployment Features Start #########################################################
#return OVF File Path
Function Get-OVFPath{
Param(
[parameter(
Mandatory = $True)]
[string]$buildVersion,
[string]$buildPath
)
$buildVersionParts = $buildVersion.Split(".")
$newBuildVersion = $buildVersionParts[0] + $buildVersionParts[1] + "." + $buildVersionParts[2] + $buildVersionParts[3]
$OVFPATH = get-childitem $buildPath -recurse -File | where {$_.extension -eq ".ovf"} | where {$_.Name -like "*$newBuildVersion*" } | %{$_.FullName}
return $OVFPATH
}
Function Get-MFPath{
Param(
[parameter(
Mandatory = $True)]
[string]$buildVersion,
[string]$buildPath
)
$buildVersionParts = $buildVersion.Split(".")
$newBuildVersion = $buildVersionParts[0] + $buildVersionParts[1] + "." + $buildVersionParts[2] + $buildVersionParts[3]
$MFPATH = get-childitem $buildPath -recurse -File | where {$_.extension -eq ".mf"} | where {$_.Name -like "*$newBuildVersion*" } | %{$_.FullName}
return $MFPATH
}
Function Get-VMDKPath{
Param(
[parameter(
Mandatory = $True)]
[string]$buildVersion,
[string]$buildPath
)
$buildVersionParts = $buildVersion.Split(".")
$newBuildVersion = $buildVersionParts[0] + $buildVersionParts[1] + "." + $buildVersionParts[2] + $buildVersionParts[3]
$VMDKPATH = get-childitem $buildPath -recurse -File | where {$_.extension -eq ".vmdk"} | where {$_.Name -like "*$newBuildVersion*" } | %{$_.FullName}
return $VMDKPATH
}
#Validate build integrity with MF file
Function buildIntegrityCheck{
Param(
[parameter(
Mandatory = $True)]
[string]$MFFilePath,
[parameter(
Mandatory = $True)]
[string]$OVFFilePath,
[parameter(
Mandatory = $True)]
[string]$VMDKFilePath
)
if(($MFFilePath -eq '') -or ($OVFFilePath -eq '') -or ($VMDKFilePath -eq ''))
{
throw "Could not get Build files. Make sure your build folder has the build files(OVF, VMDK and MF.)"
}
$OVFFileHash = Get-FileHash -Algorithm SHA1 -Path $OVFFilePath | Select-Object -ExpandProperty Hash
$VMDKFileHash = Get-FileHash -Algorithm SHA1 -Path $VMDKFilePath | Select-Object -ExpandProperty Hash
$MFContent = Get-Content $MFFilePath
$actualOVFHash = $MFContent.split("\n")[0].Split("=")[1].Trim()
$actualVMDKHash = $MFContent.split("\n")[1].Split("=")[1].Trim()
echo $OVFFileHash.ToLower()
if(($actualOVFHash -contains $OVFFileHash.ToLower()) -and ($actualVMDKHash -contains $VMDKFileHash.ToLower())){
return $True
}
return $false
}
#Check if VM exist with This IP
Function CheckVMwithIP{
Param(
[string]$vmIP
)
ConnectToVcenter
Set-LogInfo -infostatus "INFO" -topicName "FINDINGVM" -info "Searching for VMs with IP: $vmIP"
$view = @(Get-View -ViewType VirtualMachine | ?{ $_.Guest.IPAddress -eq $vmIP })
$vmNamesFound = @()
if($view.Count -gt 1){
Set-LogInfo -infostatus "INFO" -topicName "FINDINGVM" -info "Found multiple VMs with IP: $vmIP"
foreach($vm in $view){
#Printing results
$vmName = $vm.Name
Set-LogInfo -infostatus "INFO" -topicName "FINDINGVM" -info "Found VM $vmName with IP: $vmIP"
$vmNamesFound += $vmName
}
return $vmNamesFound
}elseif($view.Count -eq 1){
$vmName = $view[0].Name
Set-LogInfo -infostatus "INFO" -topicName "FINDINGVM" -info "Found VM $vmName with IP: $vmIP"
return $vmName
}else{
Set-LogInfo -infostatus "INFO" -topicName "FINDINGVM" -info "No VM found with IP: $vmIP"
return ""
}
disconnectFromvCenter
}
#Check VM STATUS
Function checkRunStatusOfVM{
Param(
[VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl] $VM
)
if($VM.PowerState -eq "PoweredOn"){
return 10
}else{
return 0
}
}
#Generate VM Name
Function GenerateVMName{
Param(
[Parameter(Mandatory=$true)]
[String]$FilePath="1",
[String]$VMIP="1"
)
if($FilePath -eq 1 -or $VMIP -eq 1){
Set-LogInfo -infostatus "ERROR" -topicName "VMNAME" -info "VM IP or Filepath for the OVF not given correctly."
Exit
}
Set-LogInfo -infostatus "INFO" -topicName "VMNAME" -info "Generating VM name........"
$filename = [io.path]::GetFileNameWithoutExtension($FilePath)
$ipParts = @()
$ipParts = $VMIP.Split(".")
$first = $ipParts[2]
$second = $ipParts[3]
$vmName = "$first`_$second`_$filename"
Set-LogInfo -infostatus "INFO" -topicName "VMNAME" -info "VM Name will be $vmName"
return $vmName
}
#Power Off VM
Function PowerOff{
Param(
[string]$VMName
)
try{
ConnectToVcenter
$VMtoPowerOff = Get-VM -Name $VMName
Set-LogInfo -infostatus "INFO" -topicName "POWEROFF" -info "Powering off VM $VMName"
Stop-VM -VM $VMtoPowerOff -Confirm:$false
Set-LogInfo -infostatus "INFO" -topicName "POWEROFF" -info "VM $VMName powered off successfully."
disconnectFromvCenter
}catch{
$ErrorMessage = $_.Exception.Message
Set-LogInfo -infostatus "ERROR" -topicName "POWEROFF" -info "Unable to poweroff VM with name $VMName"
Set-LogInfo -infostatus "ERROR" -topicName "POWEROFF" -info $ErrorMessage
disconnectFromvCenter
throw 404
}
}
#Rename a VM
Function renameVM{
Param(
[string]$oldName,
[string]$newName,
[bool]$Force
)
try{
#Random number Generator
ConnectToVcenter
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Checking if VM with $newName already exists...."
$newVM = Get-VM -Name $newName -ErrorAction Ignore
while($newVM -or $oldName -like "DELETE*"){
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "VM $newName is already there."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Generating a new Random name for VM to delete."
$randomNumber = Get-Random -Maximum 100
$newName = "$newName`_$randomNumber"
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Setting VM name to $newName."
try{
$newVM = Get-VM -Name $newName -ErrorAction Stop
}catch{
Break
}
}
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Getting the VM with name $oldName"
$VMtoRename = Get-VM -Name $OldName
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Checking power status of VM $oldName"
$status = checkRunStatusOfVM -VM $VMtoRename
if($status -eq 0){
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "VM $oldName is already Powered Off."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Renaming VM $oldName to $newName."
Set-VM -VM $VMtoRename -Name $newName -Confirm:$false
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Renaming VM $oldName to $newName Successfull."
}elseif($status -eq 10 -and $Force){
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "VM $oldName is powered On."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Renaming VM Forcefully....."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Powering off VM $oldName"
Stop-VM $VMtoRename -Confirm:$false
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "VM $oldName powered off successfully."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Renaming VM $oldName to $newName."
Set-VM -VM $VMtoRename -Name $newName -Confirm:$false
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "Renaming VM $oldName to $newName successfull."
}else{
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "VM $oldName is powered On."
Set-LogInfo -infostatus "INFO" -topicName "RENAME" -info "If you want to continue run the script with Force parameter as True."
disconnectFromvCenter
throw 401
}
disconnectFromvCenter
}catch{
if($_.toString() -eq 401){
Set-LogInfo -infostatus "ERROR" -topicName "RENAME" -info "Error code 10 thrown."
Set-LogInfo -infostatus "ERROR" -topicName "RENAME" -info "VM with name $oldName is in Powered On state."
#Exit
disconnectFromvCenter
throw 401
}else{
$ErrorMessage = $_.Exception.Message
Set-LogInfo -infostatus "ERROR" -topicName "RENAME" -info $ErrorMessage}
disconnectFromvCenter
}
}
#################################################### VM Deployment Features END #########################################################
#Download requested version and extract the files
Function downloadVersion{
Param(
[parameter(
Mandatory = $True)]
[string]$buildVersion,
$buildPath=$Global:BuildLocation
)
manageFolderSize -folderPath $buildV
createFolder -folderPath $buildPath
$buildName = checkForAvailableBuilds -version $buildVersion
$buildVersion = extractVersion -buildFullName $buildName
$buildexists = checkBuildalreadyDownloaded -buildVersion $buildVersion -buildPath $buildPath
if($buildexists.Count -ne 1){
foreach($file in $buildexists){
if($file -match ".tar$"){
deletegZippedFiles -folderPath $buildPath
$buildexists = checkBuildalreadyDownloaded -buildVersion $buildVersion -buildPath $buildPath
}elseif($file -match ".ovf$"){
deleteTarFiles -folderPath $buildPath
$buildexists = checkBuildalreadyDownloaded -buildVersion $buildVersion -buildPath $buildPath
}
}
}
if($buildexists -eq 1){
downloadBuild -buildName $buildName -downloadPath $buildPath
DeGZip-File -infile "$buildPath$buildName"
$tarFile = $buildexists -replace '.gz$',''
Expand-Tar "$buildPath$tarFile"
}elseif($buildexists -match ".tar.gz$"){
DeGZip-File -infile "$buildPath$buildexists"
$tarFile = $buildexists -replace '.gz$',''
Expand-Tar "$buildPath$tarFile"
}elseif($buildexists -match ".tar$"){
Expand-Tar "$buildPath$buildexists"
}
$OVFFile = Get-OVFPath -buildVersion $buildVersion -buildPath $buildPath
$MFFile = Get-MFPath -buildVersion $buildVersion -buildPath $buildPath
$VMDKFile = Get-VMDKPath -buildVersion $buildVersion -buildPath $buildPath
if(!(buildIntegrityCheck -MFFilePath $MFFile -OVFFilePath $OVFFile -VMDKFilePath $VMDKFile)){
throw "Build integrity not correct. Redownload the build and try again."
}else{
return $OVFFile
}
}
Function deploy-VM{
Param(
[parameter(
Mandatory = $True)]
[string]$ip,
[parameter(
Mandatory = $True)]
[string]$OVFPath,
[string]$vCenterURL=$Global:vCenterURL,
[string]$vCenterUsername = $Global:vCenterUsername,
[string]$vCenterPassword = $Global:vCenterPassword,
[bool]$ForceParameter= $false,
[string]$HostName = $Global:HostName,
[string]$DataStoreName = $Global:DataStoreName,
[string]$ResourcePoolName = $Global:ResourcePoolName,
[string]$DNS1 = $Global:DNS1,
[string]$DNS2 = $Global:DNS2,
[string]$Gateway = $Global:Gateway,
[string]$NetMask = $Global:NetMask,
[string]$NetworkName = $Global:NetworkName,
[string]$RootPassword = $Global:RootPassword
)
if(!(validateIP -IP $ip)){
throw "Please enter a valid IP address."
}
try{
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Getting OVF Configuration....."
try{
ConnectToVcenter -Username $vCenterUsername -Password $vCenterPassword -URL $vCenterURL
$OVFConfig = Get-OvfConfiguration $OVFPath -ErrorAction Stop
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Finding $HostName....."
$VMHost = Get-VMHost -Name $HostName -ErrorAction Stop
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Finding $DataStoreName....."
$DataStore = $VMHost | Get-Datastore -Name $DataStoreName -ErrorAction Stop
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Finding $ResourcePoolName....."
$resourcePool = Get-ResourcePool -Name $ResourcePoolName -ErrorAction Stop
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Checking $NetworkName....."
$bridgedNetwork = Get-VirtualPortGroup -VMHost $VMHost | where {$_.Name -eq $NetworkName} -ErrorAction Stop
}catch{
Set-LogInfo -infostatus "ERROR" -topicName "INTIALIZING" -info "Could not find this resource. Compare the config file data with portal to correct."
throw $_
}
$VMName = GenerateVMName -FilePath $OVFPath -VMIP $ip
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Checking if VM with $VMName name already exist....."
try{
$VM = Get-VM -Name $VMName -ErrorAction Stop
}catch{
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "No VM found with $VMName name."
}
#Checking if VM with same name or IP exists.
if($VM){
renameVM -oldName $VMName -newName "DELETE_$VMName" -Force $ForceParameter
}
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "Checking if VM with IP $VM_IP already exist....."
$VM1 = CheckVMwithIP -vmIP $ip
if($VM1){
foreach($vmfound in $VM1){
if($vmfound -like "*DELETE_*"){
renameVM -oldName $vmfound -newName "$vmfound" -Force $ForceParameter
}else{
renameVM -oldName $vmfound -newName "DELETE_$vmfound" -Force $ForceParameter
}
}
}else{
Set-LogInfo -infostatus "INFO" -topicName "INTIALIZING" -info "No VM found with IP $VM_IP."
}
#Setting up VM
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting OVF Configuration....."
#EVERYTHING BELOW THIS YOU WILL NEED TO CONFIGURE BASED ON YOUR OVF FILE
# IP Address
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting IP Address $VM_IP"
$OVFConfig.<will change as per your OVF config object> = $ip
# Gateway
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting Gateway $GW"
$OVFConfig.<will change as per your OVF config object> = $Gateway
# Netmask
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting NetMask $netMask"
$OVFConfig.<will change as per your OVF config object> = $NetMask
# DNS1
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting First DNS Server $DNS1"
$OVFConfig.<will change as per your OVF config object> = $DNS1
# DNS2
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting Second DNS Server Address $DNS2"
$OVFConfig.<will change as per your OVF config object> = $DNS2
# HostName
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting Hostname Value : $HostName"
$OVFConfig.<will change as per your OVF config object> = $VMHost.Name
#Bridged Network Binding
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting Bridged Network as : $NetworkName"
$OVFConfig.<will change as per your OVF config object> = $bridgedNetwork
#Root Password
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Setting root Password as : $RootPassword"
$OVFConfig.<will change as per your OVF config object> = $RootPassword
#Deploying the VM
ConnectToVcenter -Username $vCenterUsername -Password $vCenterPassword -URL $vCenterURL
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Starting deployment of $VMName....."
try{
Import-VApp -Source $OVFPath -OvfConfiguration $OVFConfig -Name $VMName -Location $resourcePool -VMHost $VMHost -Datastore $DataStore -Confirm:$false -ErrorAction Stop
}catch{
Set-LogInfo -infostatus "ERROR" -topicName "DEPLOYMENT" -info "An error occured while deploying $VMName"
throw $_
}
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Deployment complete of $VMName."
#Starting the VM
$DeployedVM = Get-VM -Name $VMName
Set-LogInfo -infostatus "INFO" -topicName "START VM" -info "Starting $VMName......"
try{
Start-VM -VM $DeployedVM -Confirm:$false -ErrorAction Stop
}catch{
Set-LogInfo -infostatus "ERROR" -topicName "START VM" -info "An error occured while starting $VMName"
throw $_
}
Set-LogInfo -infostatus "INFO" -topicName "INITIALIZING" -info "Started $VMName successfully."
return $VMName
}catch{
if($_.toString() -eq 401){
Set-LogInfo -infostatus "ERROR" -topicName "DEPLOYMENT" -info "You are unauthorized to perform this operation. Please check log for more details."
}elseif($_.toString() -eq 404)
{
Set-LogInfo -infostatus "ERROR" -topicName "DEPLOYMENT" -info "Could not find correct resource to perform the operation. Refer preceding steps for more info."
}elseif($_.toString() -eq 406){
Set-LogInfo -infostatus "ERROR" -topicName "DEPLOYMENT" -info "Requesting with invalid data. Correct the config file and Run the script."
}elseif($_.toString() -eq 201){
Set-LogInfo -infostatus "INFO" -topicName "DEPLOYMENT" -info "Created basic folders. Please enter the required data in config file and Run the script."
}
$ErrorMessage = $_.Exception.Message
Set-LogInfo -infostatus "ERROR" -topicName "DEPLOYMENT" -info $ErrorMessage
}finally{
if($global:DefaultVIServers.count -eq 1){
Set-LogInfo -infostatus "INFO" -topicName "FINISHING UP" -info "Disconnecting from vCenter."
disconnectFromvCenter
Set-LogInfo -infostatus "INFO" -topicName "FINISHING UP" -info "Disconnected from vCenter."
}
Set-LogInfo -info ""
}
}
Function start-Deployment{
Param(
[parameter(
Mandatory = $True)]
[string]$ip,
[parameter(
Mandatory = $True)]
[string]$buildVersion,
[string]$downloadPath=$Global:BuildLocation,
[bool]$forceParameter=$false
)
$Global:BuildLocation = $downloadPath
# Delete files older than the $limit.
Get-ChildItem -Path $Global:BuildLocation -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $LimitToDeleteLogs -and $_.Name -like '*.log'} | Remove-Item -Force
$OVFFile = downloadVersion -buildVersion $buildVersion -buildPath $downloadPath
$VMName = deploy-VM -ip $ip -OVFPath $OVFFile -ForceParameter $forceParameter
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment