PowerShell automated install of vShield 5

I have been learning a little about vShield lately, mainly for some work I had to complete for VMworld Las Vegas but also as I started coming up with some cool stuff when using PowerShell to talk the the REST API of vShield.  More on that will come in a following post but I wanted to give just a quick idea of what was possible.

Starting from the beginning, the first thing we will need to do is install vShield 5 into your existing environment, this could be done by downloading the software and installing it manually but why would we do this ? Automation is king !

So the following PowerShell script will show you how to automate the following:

  • Install the vShield ova file into vSphere as a new VM
  • Start the vShield VM
  • Set the IP information
  • Restart the vShield VM
  • Use the vShield API to connect it to vCenter

Of course once we have done this we will need to install the vShield Agent VMs onto our hosts but that’s a great start and we need to leave some things for me to write about in future blog posts !

I would like to point out at this point that I struggled with setting the IP address on the machine, I knew I could connect to the VM using the great Invoke-VMScript cmdlet but tried several ways until I asked for help from the legend that is Mr William Lam, you can see from this post how he managed to do this.  Thanks to William I was also able to follow his method (but with less of that Perl stuff) and enable the last piece of the jigsaw.

A big thanks to Jeff Hicks who also wrote a nice easy to use function to test if your website is available, this came in useful when I was waiting for the management website to come up before I could hook into the API and connect vShield to vCenter.

Demonstration Video

The Script

Function New-ZebraFile ($vShieldHostName, $vShieldIP, $vShieldID, $vShieldGW) {
$ZebraFile = @"
!
hostname $vShieldHostName
!
interface mgmt
 ip address $vShieldIP/$vShieldID
!
ip route 0.0.0.0/0 $vShieldGW
!
line vty
 no login
!
web-manager
!
"@

$ZebraFile | Out-File $ENV:TEMP\zebra.conf -Encoding "ASCII"
}
Function Post-vShieldAPI ($URL, $Body) {
	$wc = New-Object System.Net.WebClient

	# Add Authorization headers
	$authbytes = [System.Text.Encoding]::ASCII.GetBytes($vshieldUser + ":" + $vShieldPass)
	$base64 = [System.Convert]::ToBase64String($authbytes)
	$authorization = "Authorization: Basic " + $base64
	$wc.Headers.Add($authorization)

	$response = $wc.UploadString($URL, "POST", $Body)
}
Function Set-vShieldConfiguration ($vCenter, $Username, $Password, $PrimaryDNS, $SecondaryDNS) {
	$Body = @"


		$($vCenter)
		$($Username)
		$($Password)

		$($PrimaryDNS)
		$($SecondaryDNS)


"@
	Post-vShieldAPI -URL "https://$vShieldIP/api/2.0/global/config" -Body $Body
}
Function Wait-vShieldBoot {
	do {
		$VM = Get-VM $vShieldHostName
		Sleep 5
	} until ($VM.ToolsStatus -eq "toolsOK")
}
Function Test-WebSite {
    [cmdletBinding()]
    Param (
          [Parameter(
           ValueFromPipeline=$True,Position=0,Mandatory=$True,
           HelpMessage="The URL to test. Include http:// or https://")]
           [string]$url
           )

    Begin {
        Write-Verbose "Begin function"
        }
    Process {
        Write-Verbose "Requesting $url"

        $wr=[system.net.webrequest]::Create($url)
        #set timeout to 7 seconds
        $wr.Timeout=7000
        $start=Get-Date

        Try {
            $response=$wr.GetResponse()
            if ($response) {
                 Write-Verbose "Response returned"
                $Status=$response.StatusCode
                $StatusCode=($response.Statuscode -as [int])
            }
        }
        Catch  [system.net.webexception] {
            Write-Verbose "Failed to get a response from $url"
            $status =  $_.Exception.Response.StatusCode
            $statuscode = ( $_.Exception.Response.StatusCode -as [int])
        }

        $end=Get-Date
        $timespan=$end-$start
        $ResponseMS=$timespan.TotalMilliseconds

        Write-Verbose "status is $status"
        Write-Verbose "statuscode is $statuscode"
        Write-Verbose "timer is $responseMS"

        $obj=New-Object PSObject -Property @{
            DateTime=$start
            URL=$url
            Status=$status
            StatusCode=$statuscode
            ResponseMS=$ResponseMS
         }
         Write-Output $obj

      } #end Process
     End {
        Write-Verbose "End function"
     }
}
Function Wait-vShieldWebsite {
	do {
		$web = test-website https://$vShieldIP
		Sleep 5
	} until ($Web.Status -eq "OK")
}

# Thanks to Jeff Hicks for the Test-Website Function: http://jdhitsolutions.com/blog/2010/04/hey-are-you-awake/
# Thanks to William Lam for the trick to change the Zebra file: http://www.virtuallyghetto.com/2011/09/how-to-automate-deployment.html

$Newproperty = New-VIProperty -Name ToolsStatus -ObjectType VirtualMachine -Value {
	param($vm)
	$vm.ExtensionData.Guest.ToolsStatus
} -Force

$vshieldOVA = "Y:\VMware\vShield\VMware-vShield-Manager-5.0.0-473791.ova"
$vShieldHostName = "vShield"
$vShieldFQDN = "vshield.virtu-al.local"
$vShieldDS = "IX2NFS-VMW1"
$vShieldCluster = "Management"
$vShieldIP = "192.168.0.88"
$vShieldID = "24"
$vShieldGW = "192.168.0.1"
$vShieldPrimaryDNS = "192.168.0.10"
$vShieldSecondaryDNS = "192.168.0.1"
$vShieldUser = "admin"
$vShieldPass = "default"

$vCenter = "192.168.0.11"
$vcUsername = "Administrator"
$vcPass = "Ra1nb0w"

Write-Host "Connecting to vCenter"
$Connect = Connect-VIServer $vCenter -User $vcUsername -Password $vcPass

Write-Host "Importing the OVF file"
$va = Import-VApp -Name $vShieldHostName -Datastore $vShieldDS -VMHost (Get-Cluster $vShieldCluster | Get-VMHost | Select -First 1) -Source $vshieldOVA

Write-Host "Starting the vShield VM"
$Start = Start-VM $vShieldHostName -Confirm:$false

Write-Host "Waiting until the vShield VM has started"
Wait-vShieldBoot

Write-Host "Setting the initial IP address after boot"
$Zebrafile = New-Zebrafile -vShieldHostName $vShieldFQDN -vShieldIP $vShieldIP -vShieldID $vShieldID -vShieldGW $vShieldGW
$invoke = Invoke-VMScript -VM $vShieldHostName -ScriptText "mv /common/configs/cli/zebra.conf /common/configs/cli/zebra.conf.bak" -ScriptType Bash -GuestUser $vShieldUser -GuestPassword $vShieldPass
$ReIP = Copy-VMGuestFile -VM $vShieldHostName -Source $ENV:TEMP\zebra.conf -Destination "/common/configs/cli/" -LocalToGuest -GuestUser $vShieldUser -GuestPassword $vShieldPass

Write-Host "Powering Off the vShield VM"
Sleep 5
$Stop = Stop-VM $vShieldHostName -Confirm:$false

Write-Host "Starting the vShield VM"
$Start = Start-VM $vShieldHostName -Confirm:$false

Write-Host "Waiting until the vShield VM has started"
Wait-vShieldBoot
Write-Host "Waiting until the vShield Management site has started"
Wait-vShieldWebsite

Write-Host "Linking vShield to vCenter and set DNS entries"
$SetIP = Set-vShieldConfiguration -vCenter $vCenter -Username $vcUsername -Password $vcPass -PrimaryDNS $vShieldPrimaryDNS -SecondaryDNS $vShieldSecondaryDNS

Write-Host "Configuration Complete"

11 thoughts on “PowerShell automated install of vShield 5”

  1. Hi Alan,

    With vShield 5.1 OVA, even I’m running into error “Failed to authenticate with the guest OS using supplied credentials” even though I’m using default credentials. Could you please suggest if there is a workaround?

    Thank you

  2. Hi Alan,

    Thanks for the post. When I tried running it against my vShield Manager, I get an invalid login error. But the vShield Manager log says access denied for user “admin” from vmtoolsd. I suspect I am missing some configuration step. Any suggestions?

    Regards,
    Amit

  3. Now with 5.1 VSEM version “Invoke-VMScript -VM $vShieldHostName” command fails with Invalid login error.

  4. Ideas:
    1. Create a default rule after installation that sets “Allow All” on the vCenter VM running on the same cluster. Keep admins from shooting themselves in the foot!!
    It should be right before you link to vCenter. This would be a godsend and would add serious value to using this method to install and configure vShield.

    2. Add functionality to run the script interactively or via a CSV file rather than having to edit the script.

Leave a Reply