350 likes | 514 Views
Thinking, Building and Scripting Globally Julian Wood. London VMware User Group - 14 th July 2011 #lonvmug. Thinking, Building and Scripting Globally. Who? What? Why? How?. Who?. Julian Wood IT Infrastructure Architect & Blogger www.WoodITWork.com @julian_wood. What?.
E N D
Thinking, Building and Scripting GloballyJulian Wood London VMware User Group - 14th July 2011 #lonvmug
Thinking, Building and Scripting Globally Who? What? Why? How?
Who? Julian Wood IT Infrastructure Architect & Blogger www.WoodITWork.com @julian_wood
What? Have a single PowerCLI script to build ESX(i) anywhere in your organisation.
Why? • One script to maintain • One script to execute • Reduce errors • Set a global build standard • Maintain local differences • Remove reliance on COS Scripts • PowerCLI • Move From ESX to ESXi
ESX -> ESXi • vSphere 5 is ESXi only • Service Console to Management Interface • COS Scripts • Disk Partitioning • USB / SD • PXE • Agents • Inventory • Security • Backup • Hardware • Monitoring
Why are build standards important? • Repeatability • Reduce complexity • Champion simplicity • Reduce OpEx • Troubleshooting • Reporting • Automation
Cloud thinking…The way forward! • Not about IT but about the business • Strategy is top down, not bottom up • Moving from Systems to Services • Think big & tackle a piece at a time • It’s bigger than deploying VMs Service Catalogue Standardisation + Process + Automation
Your Cloud Foundation • Hosts • Strategy • Global layout • Make things the same • Try to make different things the same • Hardware • Number of Nics • Global Network plan • Global Storage plan • Accommodate local differences
Your buildWhat’s the same? • Naming Standard • Hardware Vendor • Number of Nics • Console Memory • Partitions • Storage Protocol • Switch Port Numbers • Version + Patches • NTP Servers • Search Domains
Your buildWhat’s different? • IP Addresses • Subnets • Gateways • Clusters • Hardware • DNS Servers • Host Names • Port Groups • Datastores • File Locations
Global LayoutCluster Requirement London Prod Servers Dev Servers Unix BigApp VDI New York Servers VDI Tokyo Servers VDI
Build basics • Build ESX(i) hosts • Blades • 4 x Nics • Directional Traffic • NFS • What’s Unique • Host Name • IP Address • Computing values • IP address / hostname gives you site • Host number can calculate IP info
Build basicsNaming Standards Host Naming Standards = $HostType • WIN Server hosts = <country><site><ESX><number> • Unix Server hosts = <country><site><ESXUX><number> • VDI hosts = <country><site><ESXVDI><number> • jptokesx78 • gblonesxux10 • usnycesxvdi22
Build basicsIP Addresses IP Address = $Site
Let’s get scripting!Connect #Ask for the host to connect to Write-Host"Enter ESX(i) Host FQDN /IP "-ForegroundColorMagenta $vmhost=read-host If ($vmhost-eq"") { Write-Host"No ESX(i) Host Supplied, Exiting"-ForegroundColorRed Exit} Write-Host"Enter ESX(i) host credentials to authenticate"-ForegroundColor ; Magenta $ESXCred=$host.ui.PromptForCredential("ESX(i) credentials", "Please enter the; ESX(i) host user name and password.", "", "") #Connect to the ESX(i) Host $ESXConnect=Connect-VIServer-Server$VMHost-Credential$ESXCred If ($ESXConnect.IsConnected-ne$true){ Write-Host"Cannot connect to ESX(i) Host, Exiting"-ForegroundColorRed Exit} $ESXHost=Get-VMHost
Let’s get scripting!Get the Basics #Get Host Network information Write-Host"Getting Host Networking Information"-ForegroundColorCyan $HostNetworkInfo=$ESXHost | Get-VMHostNetworkAdapter | where {($_.PortGroupName -eq"Service Console") -or ($_.PortGroupName -eq"Management Network")} $ConsoleNic= ($HostNetworkInfo | SelectIP).IP $ESXHostView=$ESXHost | Get-View #Get actual ESX hostname $vmhost=$vmhost=$ESXHostView.Name # Work out Host Number by pulling out numbers from $vmhost variable and storing as integer [int]$HostNum= (([regex]'\d+').matches($vmhost.Split(".")[0]) | select ; Value).Value gblonesx10/gblonesxvdi10/gblonesxus10 = 10 # Show & Tell Write-Host"Connected to "$ESXHostView.Config.Product.Name" host:- "$ESXHost.Manufacturer" "$ESXHost.Model": "$vmhost-Separator""- ForegroundColorGreen
Let’s get scripting!Where & what are you? # Determine Host Site information based on Service Console IP Address" switch-wildcard ($HostNetworkInfo.ConsoleGateway) { "10.1.*" {$Site="NYC"} "10.2.*" {$Site="LON"} "10.3.*" {$Site="TOK"} default {Write-Host"Can not determine ESX Host Site, Exiting“ ; -ForegroundColorRed Exit}} # Determine ESX(i) Product Version" If ($ESXHostView.Config.Product.Name-match"ESXi") { $ESXProduct="ESXi“ } Else { $ESXProduct="ESX“} # Determine Host Use Type" $HostType="SRV" If ($vmhost-match"VDI") {$HostType="VDI"} If ($vmhost-match“UX") {$HostType="UNIX"}
Let’s get scripting!Asking what Type? If ($Site-eq“LON") { while ($HostType-eq"SRV") { Write-Host"Enter ESX Host Type: " Write-Host"(P)roduction" -ForegroundColorGreen Write-Host"(D)evelopment" -ForegroundColorGreen Write-Host"(B)igApp"-ForegroundColorGreen $SRVAnswer=Read-host switch ($SRVAnswer.ToUpper()) { "P" {$HostType="SRVPROD"} "D" {$HostType="SRVDEV"} “B" {$HostType="SRVBIGAPP"} } } }
Let’s get scripting!Or calculating what type # Determine Site Specific Host Type" If ($Site-eq“LON") { while ($HostType-eq"SRV") { switch ($HostNum) { {$_-le 99} {$HostType="SRVBIGAPP"} {$_-le 79} {$HostType="SRVDEV"} {$_-le 49} {$HostType="SRVPROD"}}}} # Determine Site Specific File locations" switch ($Site) { "NYC" { $ISOLocation="nyc_vmiso" $PuttyFolder="\\usnycfile01\apps\Putty\"} "LON" { $ISOLocation="vmiso" $PuttyFolder="\\gblonfiler01\it\Utilities-Tools\Putty\"} "TOK" { $ISOLocation="vmiso" $PuttyFolder="\\jptokfs02\install\Putty\"} }
Let’s get scripting!Calculating IP Addresses # Generate Site Specific IP Settings" switch ($Site){ "LON" { $DNSServers="10.2.111.78","10.2.1.47" $VMkernelVLAN= 530 $VMkernelMask="255.255.254.0" $VMkernelGateway="10.2.17.254" $vMotionMask="255.255.255.0" switch-wildcard($HostType){ "SRV*“ {$VMkernelIP="10.2.17.$HostNum" $vMotionIP="192.168.0.$HostNum"} "UNIX“ {$VMkernelIP="10.2.17."+ ($HostNum+220) # Add 220 to HostNum value to work out Unix vmkernel IP $vMotionIP="192.168.0."+ ($HostNum+220)} # Add 220 to HostNum value to work out Unix vmotion IP "VDI“ {$VMkernelIP="10.2.17."+ ($HostNum+100) # Add 100 to HostNum value to work out VDI vmkernel IP $vMotionIP="192.168.0."+ ($HostNum+100)}}} # Add 100 to HostNum value to work out VDI vmotion IP
Let’s get scripting!Calculating IP Addresses "NYC" { $DNSServers="10.1.1.101","10.1.12.78" $VMkernelVLAN= 134 $VMkernelMask="255.255.254.0" $VMkernelGateway="10.1.15.254" $vMotionMask="255.255.255.0" switch-wildcard($HostType) { "SRV*“ {$VMkernelIP="10.1.15.$HostNum" $vMotionIP="192.168.0.$HostNum"} "VDI“ {$VMkernelIP="10.1.15."+ ($HostNum+100) # Add 100 to HostNum value to work out VDI vmkernel IP $vMotionIP="192.168.0."+ ($HostNum+100)}}} # Add 100 to HostNum value to work out VDI vmkernel IP "TOK" { $DNSServers="10.3.13.72","10.3.15.12" $VMkernelVLAN= 603 $VMkernelMask="255.255.255.0" $VMkernelGateway="10.3.91.1" $vMotionMask="255.255.255.0" switch-wildcard($HostType) { "SRV*“ {$VMkernelIP="10.3.91."+ ($HostNum+50) # Add 50 to HostNum value to work out VDI vmkernel IP $vMotionIP="192.168.0."+ ($HostNum+10)} # Add 10 to HostNum value to work out VDI vmkernel IP "VDI“ {$VMkernelIP="10.3.91."+ ($HostNum+170) # Add 170 to HostNum value to work out VDI vmkernel IP $vMotionIP="192.168.0."+ ($HostNum+100)}}}} # Add 100 to HostNum value to work out VDI vmkernel IP
Let’s get scripting!Port Groups # Generate Site and Host Type Specific Port Groups" switch ($Site){ "LON" { switch ($HostType){ "SRVPROD" {$PortGroups= ("servers_prod1",41), ("servers_lb1",39)} "SRVBIGAPP" {$PortGroups= ("servers_prod1",41), ("servers_lb1",39)} "SRVDEV" {$PortGroups= ("servers_dev1",33)} "VDI" {$PortGroups= ("vdi1",29), ("vdi2",34), ("vdi3",38)} "UNIX" {$PortGroups= ("unix_dhcp",37)}}} "NYC" { switch ($HostType){ "SRV" {$PortGroups= ("servers_prod1",216)} "VDI" {$PortGroups= ("vdi1",218)}}} "TOK" { switch ($HostType){ "SRV" {$PortGroups= ("servers1",500), ("servers_lb",532)} "VDI" {$PortGroups= ("vdi1",521), ("vdi2",522)}}}}
Let’s get scripting!Datastores # Generate Site and Host Type Specific Datastores" switch ($Site){ "LON" { switch ($HostType){ "SRVPROD" {$Datastores= ("vmiso","/vol/vmiso","gblonnfs01.wooditwork.com"), ("srvprod3_gblonnfs01","/vol/srvprod3","gblonnfs01.wooditwork.com"), ("vcenter_gblonnfs01","/vol/vcenter","gblonnfs01.wooditwork.com")} "SRVBIGAPP" {$Datastores= ("vmiso","/vol/vmiso","gblonnfs01.wooditwork.com"), ("srvprod3_gblonnfs02","/vol/srvprod3","gblonnfs02.wooditwork.com"), ("bigapp_gblonnfs02","/vol/bigapp","gblonnfs02.wooditwork.com"), ("vcenter_gblonnfs01","/vol/vcenter","gblonnfs01.wooditwork.com")} "SRVDEV" {$Datastores= ("vmiso","/vol/vmiso","gblonnfs01.wooditwork.com"), ("srvdev3_gblonnfs02","/vol/srvdev3","gblonnfs02.wooditwork.com")} "VDI" {$Datastores= ("vmiso","/vol/vmiso","gblonnfs01.wooditwork.com"), ("vdi1_gblonnfs03","/vol/vdi1","gblonnfs03.wooditwork.com"), ("vdi2_gblonnfs04","/vol/vdi2","gblonnfs04.wooditwork.com")} "UNIX" {$Datastores= ("vmiso","/vol/vmiso","gblonnfs01.wooditwork.com"), ("unix_servers1_gblonnfs01","/vol/uxrv1","gblonnfs01.wooditwork.com"), ("unix_ws2_gblonnfs03","/vol/uxws2","gblonnfs03.wooditwork.com")}}}
Let’s get scripting!Datastores “TOK" { switch ($HostType){ "SRV" {$Datastores= ("vmiso","/vol/vmiso1","jptokfiler01.wooditwork.com"), ("srvtok1_jptokfiler01","/vol/srvtok1","jptokfiler01.wooditwork.com"), ("vcenter_jptokfiler01","/vol/vcenter","jptokfiler01.wooditwork.com")} "VDI" {$Datastores= ("vmiso","/vol/vmiso1","jptokfiler01.wooditwork.com"), ("vdi1_jptokfiler01","/vol/vdi1","jptokfiler01.wooditwork.com"), ("vdi2_jptokfiler01","/vol/vdi2","jptokfiler01.wooditwork.com")}}} “NYC" { switch ($HostType){ "SRV" {$Datastores= ("vmiso","/vol/vmiso1","usnycfas01.wooditwork.com"), ("servers1_usnycfas01","/vol/servers1","usnycfas01.wooditwork.com")} "VDI" {$Datastores= ("vmiso","/vol/vmiso1","usnycfas01.wooditwork.com"), ("vdi1_usnycfas01","/vol/vdi1","usnycfas01.wooditwork.com"), ("vdi2_usnycfas01","/vol/vdi2","usnycfas01.wooditwork.com")}}}}
Let’s get scripting!It’s all worked out Write-Host"Build information has been generated"-ForegroundColorCyan Write-Host"------------------------------------"-ForegroundColorCyan Write-Host" ESX(i) Host Name: "-NoNewline Write-Host$vmhost-Separator""-ForegroundColorGreen Write-Host"ESX(i) Host Version: "-NoNewline Write-Host$ESXHostView.Config.Product.FullName-ForegroundColorGreen Write-Host" Site: "-NoNewline Write-Host$Site-ForegroundColorGreen Write-Host" Host Type: "-NoNewline Write-Host$HostType-ForegroundColorGreen Write-Host" ISO Location: "-NoNewline Write-Host$ISOLocation-ForegroundColorGreen Write-Host" Search Domain:"$SearchDomain Write-Host" DNS Servers:"$DNSServers Write-Host" NTP Servers:"$NTPServers Write-Host"" If ($ESXProduct-eq"ESX") { Write-Host"ESX VMkernel Networking"-ForegroundColorCyan Write-Host"-------------------"-ForegroundColorCyan Write-Host" VMkernel IP: "-NoNewline Write-Host$VMKernelIP-ForegroundColorGreen Write-Host" VMkernel VLAN:"$VMKernelVLAN Write-Host" VMkernel Mask:"$VMKernelMask Write-Host" VMkernel Gateway:"$VMKernelGateway Write-Host""} Write-Host"vMotion Networking"-ForegroundColorCyan Write-Host"------------------"-ForegroundColorCyan Write-Host" vMotion IP: "-NoNewline Write-Host$VmotionIP-ForegroundColorGreen Write-Host" vMotion Mask:"$VmotionMask Write-Host"" Write-Host" Port Groups"-ForegroundColorCyan Write-Host"-----------"-ForegroundColorCyan ForEach ($PortGroupin$PortGroups) { Write-Host" Port Group: "$PortGroup[0]" VLAN:"$PortGroup[1]} Write-Host"Storage"-ForegroundColorCyan Write-Host"-------"-ForegroundColorCyan ForEach ($Datastorein$Datastores) { Write-Host-Separator""" Datastore: "$Datastore[0]" - "$Datastore[2]":"$Datastore[1]} Write-Host"---------------------------------------------------"-ForegroundColorCyan Write-Host""-ForegroundColorCyan
Let’s get scripting!Start the standard build Write-Host"-----------------------------------------------"-ForegroundColorCyan Write-Host"Building ESX(i) Host:"$vmhost-ForegroundColorCyan Write-Host"-----------------------------------------------"-ForegroundColorCyan # Set Global Settings" $SearchDomain="wooditwork.com","mycompany.net" $NTPServers="usnycntp01.wooditwork.com","gblonntp01.wooditwork.com" $ConsoleMemory= 800 $vSwitch0PortNumber= 128 If ($ESXHost.ConnectionState-notmatch"Maintenance") { Write-Host"Putting Host into Maintenance Mode"-ForegroundColorCyan $ESXHost | Set-VMHost-Statemaintenance } Write-Host"Setting DNS Servers and Search Domains"-ForegroundColorCyan $ESXHost | Get-VMHostNetwork | Set-VMHostNetwork-DnsAddress$DNSServers-SearchDomain$SearchDomain If ($ESXProduct-eq"ESX") { Write-Host"Setting Console Memory"-ForegroundColorCyan $ESXHostView | %{(Get-View-Id ; $_.ConfigManager.MemoryManager).ReconfigureServiceConsoleReservation($Console Memory*1mb)}}
Let’s get scripting!Configure Networking… Write-Host"Remove any existing NTP Servers"-ForegroundColorCyan If (($ESXHost | Get-VMHostNtpServer) -ne$Null) {$ESXHost | Remove-VMHostNtpServer-NtpServer ($ESXHost | Get-VMHostNtpServer) -Confirm:$false} Write-Host"Adding NTP Servers"-ForegroundColorCyan $ESXHost | Add-VMHostNtpServer-NtpServer$NTPServers If ($ESXProduct-eq"ESX") { Write-Host"Enabling SSH on the host"-ForegroundColorCyan $ESXHost | Get-VmhostFirewallException"SSH Client" | Set-VMHostFirewallException-enabled:$true Write-Host"Enabling NTP Service in the firewall"-ForegroundColorCyan $ESXHost | Get-VMhostFirewallException"NTP Client" | Set-VMHostFirewallException-enabled:$true} If ($NTPService.Running -eq$True) { Restart-VMHostService-HostService$NTPService-Confirm:$false} Else { Start-VMHostService-HostService$NTPService-Confirm:$false} Write-Host"Setting the NTP Service Policy to Automatic"-ForegroundColorCyan $NTPService | Set-VMHostService-PolicyAutomatic Write-Host"Removing any VM networks"-ForegroundColorCyan $ESXHost | Get-VirtualPortGroup | Where-Object {$_.Port -eq$Null} | Remove-VirtualPortGroup-Confirm:$False Write-Host"Removing any empty Virtual Switches"-ForegroundColorCyan $ESXHost | Get-VirtualSwitch | Where-Object { $Null-eq (Get-VirtualPortGroup-VirtualSwitch$_)} | Remove-VirtualSwitch-Confirm:$False Write-Host"Configuring vSwitch0"-ForegroundColorCyan $vSwitch0=$ESXHost | Get-VirtualSwitch | where {$_.Name -like"vSwitch0"} Write-Host"Setting the Port Number on vSwitch0"-ForegroundColorCyan $vSwitch0 | Set-VirtualSwitch-NumPorts$vSwitch0PortNumber-Confirm:$false Write-Host"Add vmnic1 to vSwitch0"-ForegroundColorCyan $vSwitch0 | Set-VirtualSwitch-Nic vmnic0,vmnic1 -Confirm:$false Write-Host"Enable Beacon Probing on vSwitch0"-ForegroundColorCyan $vSwitch0 | Get-NicTeamingPolicy | Set-NicTeamingPolicy-NetworkFailoverDetectionPolicyBeaconProbing
Let’s get scripting!Configure Networking… If ($ESXProduct-eq"ESX") { Write-Host"Adding VMkernel Port Group"-ForegroundColorCyan $VMkernel=$vSwitch0 | New-VirtualPortGroup-NameVMkernel-vlanid$VMKernelVLAN Write-Host"Adding the VMkernel IP Address"-ForegroundColorCyan New-VMHostNetworkAdapter-PortGroup$VMkernel-VirtualSwitch$vSwitch0-IP$VMkernelIP-SubnetMask$VMkernelMask Write-Host"Adding the VMkernel Gateway"-ForegroundColorCyan Get-VMHostNetwork | Set-VMHostNetwork-VMkernelGateway$VMkernelGateway- VMkernelGatewayDevice"vmk0" Write-Host"Setting vmnic1 to an Active Adapter"-ForegroundColorCyan $VMkernel | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicActive"vmnic1" Write-Host"Setting vmnic0 to a Standby Adapter"-ForegroundColorCyan $VMkernel | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicStandby"vmnic0" Write-Host"Override the vSwitch failover order"-ForegroundColorCyan $VMkernel | Get-NicTeamingPolicy | Set-NicTeamingPolicy-InheritFailoverOrder$false- InheritFailback$true-InheritLoadBalancingPolicy$true- InheritNetworkFailoverDetectionPolicy$true-InheritNotifySwitches$true }
Let’s get scripting!Configure Networking… If ($ESXProduct-eq"ESXi") { Write-Host"Configuring Management Network"-ForegroundColorCyan $MgmtNet=$vSwitch0 | Get-VirtualPortGroup-Name"Management Network" Write-Host"Setting vmnic1 to an Active Adapter"-ForegroundColorCyan $MgmtNet | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicActive"vmnic1" Write-Host"Setting vmnic0 to a Standby Adapter"-ForegroundColorCyan $MgmtNet | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicStandby"vmnic0" Write-Host"Override the vSwitch failover order"-ForegroundColorCyan $MgmtNet | Get-NicTeamingPolicy | Set-NicTeamingPolicy-InheritFailoverOrder$false- InheritFailback$true-InheritLoadBalancingPolicy$true- InheritNetworkFailoverDetectionPolicy$true-InheritNotifySwitches$true } Write-Host"Creating the vMotion vSwitch1 and Port Group"-ForegroundColorCyan New-VirtualSwitch-Name"vSwitch1"-Nic vmnic2,vmnic3 | New-VirtualPortGroup-NamevMotion Write-Host"Adding the vMotionVMkernel IP Address"-ForegroundColorCyan New-VMHostNetworkAdapter-PortGroupvMotion-VirtualSwitchvSwitch1-IP$vmotionIP-SubnetMask$vMotionMask-VMotionEnabled$true Write-Host"Enabling Beacon Probing on vSwitch1"-ForegroundColorCyan $vSwitch1=Get-VirtualSwitch| where {$_.Name -like"vSwitch1"} $vSwitch1 | Get-NicTeamingPolicy | Set-NicTeamingPolicy-NetworkFailoverDetectionPolicyBeaconProbing
Let’s get scripting!Creating port groups Write-Host"Creating Virtual Machine Port Groups"-ForegroundColorCyan $PortGroups | %{$vSwitch0 | New-VirtualPortGroup-Name$_[0] -vlanid$_[1]} Write-Host"Setting VM Port Group Failover order"-ForegroundColorCyan $VMPortGroups=$vSwitch0 | Get-VirtualPortGroup | Where-Object {$_.Port -eq$Null} foreach ($VMPortGroupin$VMPortGroups){ Write-Host$VMPortGroup.Name": Set vmnic0 to an Active Adapter" $VMPortGroup | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicActive"vmnic0" Write-Host$VMPortGroup.Name": Set vmnic1 to a Standby Adapter" $VMPortGroup | Get-NicTeamingPolicy | Set-NicTeamingPolicy-MakeNicStandby"vmnic1" Write-Host$VMPortGroup.Name": Override the vSwitch failover order” $VMPortGroup | Get-NicTeamingPolicy | Set-NicTeamingPolicy-InheritFailoverOrder$false-InheritFailback$true- InheritLoadBalancingPolicy$true- InheritNetworkFailoverDetectionPolicy$true-InheritNotifySwitches$true }
Let’s get scripting!Handling site specifics # Add site specific additional network requirements" switch ($Site){ “TOK" { switch ($HostType){ "SRV" { Write-Host“Tokyo: Creating the DMZ vSwitch2 and Port Group"-; ForegroundColorCyan New-VirtualSwitch-Name"vSwitch2"-Nic vmnic6,vmnic7 | ; New-VirtualPortGroup-Nameservers_dmz Write-Host"Enabling Beacon Probing on vSwitch2"-ForegroundColorCyan $vSwitch2=$ESXHost | Get-VirtualSwitch | where {$_.Name -like"vSwitch2"} $vSwitch2 | Get-NicTeamingPolicy | Set-NicTeamingPolicy- ; NetworkFailoverDetectionPolicyBeaconProbing}}}}
Let’s get scripting!Handling versions If ($ESXProduct-eq"ESX") { Write-Host"Installing additional Network Patches"-ForegroundColorCyan switch ($ESXHost.Version){ "4.0.0" { Write-Host"Installing Patch: BCM-bnx2x-1.52.12.v40.8"-ForegroundColorCyan Install-VMHostPatch-VMHost$ESXHost-HostPath /vmfs/volumes/$ISOLocation/ESXPatches/BCM- bnx2x-1.52.12.v40.8-offline_bundle-324481/metadata.zip} "4.1.0" { Write-Host"Installing Patch: BCM-bnx2x-1.60.50.v41.2"-ForegroundColorCyan Install-VMHostPatch-VMHost$ESXHost-HostPath /vmfs/volumes/$ISOLocation/ESXPatches/BCM- bnx2x-1.60.50.v41.2-offline_bundle-320302/metadata.zip}}}
Thinking, Building and Scripting GloballyJulian Wood London VMware User Group - 14th July 2011 #lonvmug