Automated deployment & configuration of Log Insight with PowerCLI

As part of my datacenter build I needed to install and configure Log Insight automatically, this is easier than it sounds, its easy enough to deploy and OVA file with PowerCLI but the configuration of Log Insight is all done via a configuration website and not through OVF properties or VM properties.

What’s more, the normal trick of using Invoke-VMscript to reach inside the VM and perform some configuration by manipulating files would not work as the administrator password is not set until you complete the web page configuration.

Thankfully PowerShell has some great ways to manipulate Internet Explorer, with this I was able to automatically fill in the website and configure Log Insight to automatically connect to my infrastructure to start collecting data.  For debug purposes I have left the automation of internet explorer visible in the below script when it is run, this can easily be turned off by altering the $ie.visible = $true line below to change it to $false.

You will see my script automatically chooses a host and datastore based upon the cluster and the size needed, you can of course change it for your environment if you would prefer to choose where it was deployed.

Don’t forget that as a follow on you can also bulk configure your ESXi hosts to send their logs to Log Insight with the following PowerCLI script.

Sample Screenshots

image

SNAGHTML15f6ad

The Script

Connect-VIServer 192.168.1.50 -user "administrator@vsphere.local" -pass vmware
$LIInstallFile = "C:\tmp\VMware-vCenter-Log-Insight-1.0.4-1169900_OVF10.ova"
$LIName = "LI01"
$LINetwork = "VM Network"
$LIIP = "192.168.1.150"
$LISNM = "255.255.255.0"
$LIDGW = "192.168.1.1"
$LIDNS = "192.168.1.1"
$LICluster = "Production"
$LIEmail = "myemail@vsphere.local"
$LIPassword = "VMware123!"
$LISMTPServer = "mail.vsphere.local"
$LISMTPport = 25 
$LILicense = "YOUR-KEY-GOES-HERE"
$LINTP = "0.us.pool.ntp.org, 1.us.pool.ntp.org, 2.us.pool.ntp.org, 3.us.pool.ntp.org"
$LIvC = "192.168.1.50"
$LIvCUser = "administrator@vsphere.local"
$LIvCPass = "vmware"
$SleepTime = 15
$LISpaceNeededGB = "5"

Write-Host "$(Get-Date): Selecting host for $LIName from $LICluster Cluster"
$LIVMHost = Get-Cluster $LICluster | Get-VMHost | Where {$_.PowerState -eq "PoweredOn" -and $_.ConnectionState -eq "Connected" } | Get-Random
Write-Host "$(Get-Date): $LIVMHost selected for $LIName"
Write-Host "$(Get-Date): Selecting Datastore for $LIName"
$LIDatastore = $LIVMHost | Get-Datastore | Where {$_.ExtensionData.Summary.MultipleHostAccess} | Where {$_.FreeSpaceGB -ge $LISpaceNeededGB} | Get-Random
if (!$LIDatastore) {
	Write-Host "$(Get-Date): No shared datastore found with $LISpaceNeededGB GB Free"
	Write-Host "$(Get-Date): LogInsight will not be installed"
} Else {
	Write-Host "$(Get-Date): $LIDatastore selected for $LIName"
	Write-Host "$(Get-Date): Importing $LIName from $LIInstallFile"
	$LIDeployedVMTask = $LIVMHost | Import-vApp -Name $LIName -Source $LIInstallFile -Datastore $LIDatastore -Force -RunAsync

	do {
		Sleep $SleepTime
		Write-Progress -Activity "Deploying Log Insight to $LIVMHost" -status "Progress" -PercentComplete $LIDeployedVMTask.PercentComplete 
		
	} until ($LIDeployedVMTask.PercentComplete -eq 100 )
	Write-Host "$(Get-Date): $LIName deployed and the task result was $($LIDeployedVMTask.State)"
	If ($LIDeployedVMTask.State -ne "success") {
		Write-Host "$(Get-Date): Unable to deploy LogInsight, deploy failed with $($LIDeployedVMTask.ExtensionData.Info.Error.LocalizedMessage)"
	} Else {
		$LIDeployedVM = Get-VM $LIName

		# Reconfigure the vApp with Name and IP details.
		$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
		$spec.changeVersion = $LIDeployedVM.ExtensionData.Config.ChangeVersion
		$spec.vAppConfig = New-Object VMware.Vim.VmConfigSpec
		$spec.vAppConfig.property = New-Object VMware.Vim.VAppPropertySpec[] (6)
		$spec.vAppConfig.ipAssignment = New-Object VMware.Vim.VAppIPAssignmentInfo
		$spec.vAppConfig.ipAssignment.ipAllocationPolicy = "fixedPolicy"

		$spec.vAppConfig.property[0] = New-Object VMware.Vim.VAppPropertySpec
		$spec.vAppConfig.property[0].operation = "edit"
		$spec.vAppConfig.property[0].info = New-Object VMware.Vim.VAppPropertyInfo
		$spec.vAppConfig.property[0].info.key = 0
		$spec.vAppConfig.property[0].info.value = $LIDGW

		$spec.vAppConfig.property[1] = New-Object VMware.Vim.VAppPropertySpec
		$spec.vAppConfig.property[1].operation = "edit"
		$spec.vAppConfig.property[1].info = New-Object VMware.Vim.VAppPropertyInfo
		$spec.vAppConfig.property[1].info.key = 1
		$spec.vAppConfig.property[1].info.value = $LIDNS

		$spec.vAppConfig.property[2] = New-Object VMware.Vim.VAppPropertySpec
		$spec.vAppConfig.property[2].operation = "edit"
		$spec.vAppConfig.property[2].info = New-Object VMware.Vim.VAppPropertyInfo
		$spec.vAppConfig.property[2].info.key = 2
		$spec.vAppConfig.property[2].info.value = $LIIP

		$spec.vAppConfig.property[3] = New-Object VMware.Vim.VAppPropertySpec
		$spec.vAppConfig.property[3].operation = "edit"
		$spec.vAppConfig.property[3].info = New-Object VMware.Vim.VAppPropertyInfo
		$spec.vAppConfig.property[3].info.key = 3
		$spec.vAppConfig.property[3].info.value = $LISNM

		$spec.vAppConfig.property[4] = New-Object VMware.Vim.VAppPropertySpec
		$spec.vAppConfig.property[4].operation = "edit"
		$spec.vAppConfig.property[4].info = New-Object VMware.Vim.VAppPropertyInfo
		$spec.vAppConfig.property[4].info.key = 4
		$spec.vAppConfig.property[4].info.value = $LIName


		$Reconfig = $LIDeployedVM.ExtensionData

		Write-Host "$(Get-Date): Reconfiguring $LIName after deployment"
		$Configtask = $Reconfig.ReconfigVM_Task($spec)

		Write-Host "$(Get-Date): Reconfiguring Network on $LIName to join $LINetwork"
		$NetworkChange = $LIDeployedVM | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $LINetwork -Confirm:$false

		Write-Host "$(Get-Date): Power On $LIName for first time"
		$LIDeployedVM | Start-VM | Out-Null

		Write-Host "$(Get-Date): Waiting for Log Insight Website to be active before configuration"
		$NumConnections = 0
		do {
			Sleep 7
			$Port = 443
			$Connection = New-Object Net.Sockets.TcpClient
			Try { 
				$Connection.Connect($LIIP,$Port)
				If ($Connection.Connected) {
					Write-Host "$(Get-Date): Waiting for Log Insight Website to be active before configuration"
					$NumConnections ++
				}
			}
			Catch {}
			Finally {}
			
		} until ($NumConnections -gt 10)

		$LIURI = "https://$LIIP"
		$ie = new-object -com "InternetExplorer.Application"
		$ie.navigate($LIURI)
		while($ie.ReadyState -ne 4) {start-sleep 1} 
		$ie.visible = $true
		$doc = $ie.Document
		If ($doc.nameProp -eq "Certificate Error: Navigation Blocked") {
			$doc.getElementByID("overridelink").Click()
			while($doc.nameProp -ne "vCenter Log Insight - Startup") {
				$doc = $ie.Document
				start-sleep 1
				Write-Host "$(Get-Date): Waiting for Log Insight Config Page"
			} 
		}
		$doc = $ie.Document
		$ie.Document.getElementById("skip-button").Click()
		Write-Host "$(Get-Date): Configuring Password"
		Start-Sleep 5
		$ie.Document.getElementsByName("user.email")| Foreach {$_.value=$LIEmail}
		$ie.Document.getElementsByName("newPassword")| Foreach {$_.value=$LIPassword}
		$ie.Document.getElementsByName("newPasswordConfirm")| Foreach {$_.value=$LIPassword}
		$ie.Document.getElementById("save-button").Click()
		Write-Host "$(Get-Date): Configuring License Key"
		Start-Sleep 5
		$ie.Document.getElementsByName("licenseKey")| Foreach {$_.value=$LILicense}
		$ie.Document.getElementById("skip-button").Click()
		Write-Host "$(Get-Date): Configuring Alert Email address"
		Start-Sleep 5
		$ie.Document.getElementsByName("alertsConfig.adminAlertReceivers")| Foreach {$_.value=$LIEmail}
		$ie.Document.getElementById("save-button").Click()	
		Write-Host "$(Get-Date): Configuring NTP"
		Start-Sleep 5
		$ie.Document.getElementsByName("ntpConfig.ntpServersCsv")| Foreach {$_.value=$LINTP}
		$ie.Document.getElementById("save-button").Click()
		Write-Host "$(Get-Date): Configuring SMTP"
		Start-Sleep 5
		$ie.Document.getElementsByName("smtpConfig.server")| Foreach {$_.value=$LISMTPServer}
		$ie.Document.getElementsByName("smtpConfig.port")| Foreach {$_.value=$LISMTPport}
		$ie.Document.getElementById("save-button").Click()
		Write-Host "$(Get-Date): Configuring vCenter Integration"
		Start-Sleep 5
		$ie.Document.getElementsByName("vsphereConfig.credentials[0].enabled")| Foreach {$_.Checked=$True}
		#TODO GO back and adjust for multi vCenter env
		$ie.Document.getElementsByName("vsphereConfig.credentials[0].hostname")| Foreach {$_.value=$LIvC}
		$ie.Document.getElementsByName("vsphereConfig.credentials[0].username")| Foreach {$_.value=$LIvCUser}
		$ie.Document.getElementsByName("vsphereConfig.credentials[0].password")| Foreach {$_.value=$LIvCPass}
		$testlinks = $ie.Document.get_links()
		$testlinks | Foreach { $_ | Where {$_.OuterText -eq "Test"} | Foreach { $_.Click() } }
		Start-Sleep 60
		$ie.Document.getElementById("save-button").Click()
		Start-Sleep 5
		$ie.Document.getElementById("save-button").Click()
		Start-Sleep 5
		$ie.Document.getElementById("skip-button").Click()
		$ie.Quit()
		Write-Host "$(Get-Date): $LIName deployment and configuration completed."
	}
}

2 thoughts on “Automated deployment & configuration of Log Insight with PowerCLI”

Leave a Reply