Skip to main content

Configuring iSCSI on ESXi using PowerCLI

In one of my previous post I stepped through the method of connecting my ESXi host to an iSCSI array using manual steps from creating the Standard vSwitch to port binding. In this post, I will talk about how I used powercli with esxcli to automate the steps so that it can be repeatable and quicker to deploy to your host. This will ensure each host is built with the same consistency and should anything go wrong it will be easier to rectify as all your host are built using a script.

I will go through my script to explain each section of how to configure:
  • A new standard vSwitch
  • Assign two physical network adapter to the vSwitch
  • Create 2 VMKernel adapters for iSCSI
  • Bind the 2 VMKernel adapters to create the port binding
  • Create the connection to your iSCSI storage array
The full script is available here at github

The first bit is to define all the values for our variables that we would use within the script. If we were to run this script against another host you will need to just modify the values at the start of the script instead of looking for those values within the script. So here we go....

The first three variables are the ones that will need to be changed as they will be unique to each ESXi host you run this script on;

Define the IP address/FQDN of the host that you will be working on
$ESXHostName = "You ESXi Host IP or FQDN"
Define IP address to be given for iSCSI VMKernel adapter 1
$iSCSIIP1 = "IP Address for iSCSI VMKernel adapter 1"
Define IP address to be given for iSCSI VMKernel adapter 2
$iSCSIIP2 =  "IP Address for iSCSI VMKernel adapter 2"

The remaining variables should not change for each host as you deploy this script to. They should remain the same i.e. vSwitch names and physical network cards that would be used;

Define the subnet for iSCSI VMkernel adapters that have been defined above. As they are in the same subnet we just need a single variable for this
$iSCSISubnet = "Subnet for iSCSI VMKernel adapter"
Define the name you want to give for this vSwitch
$iSCSISwName = "Name you want to give for vSwitch"
Define the MTU size you are using for iSCSI. Make sure this value is the same from end to end for the iSCSI connection otherwise you could encounter issues
$iSCSIMTU = "MTU Size for iSCSI"
Define Name of the 1st iSCSI port group name
$iSCSIPg1Name = "Port Group 1 name"
Define Name of the 2nd iSCSI port group name
$iSCSIPg2Name = "Port Group 2 name"
Define the physical network card 1 that will be assigned to the vSwitch
$iSCSIPhyNic1 = "Your physical Adapter Nic 1 Name"
Define the physical network card 2 that will be assigned to the vSwitch
$iSCSIPhyNic2 = "Your physical Adapter Nic 2 Name"
Define the target iSCSI Array IP address for iSCSI connection
$iSCSItargetIP = "IP address of your iSCSI Array"

First thing is to connect to our esxi host that we defined in our variable and put it in maintenance mode
Connect-VIServer $ESXHostName
Set-VMHost -State "Maintenance"

Now we create our standard vSwitch using the switch name, MTU and assign the physical network cards defined in our variables
New-VirtualSwitch -Name $iSCSISwName -Mtu $iSCSIMTU -confirm:$false
$VMHostPhysicalNic1 = Get-vmhost | Get-VMHostNetworkAdapter -Physical -Name $iSCSIPhyNic1
get-virtualSwitch -name $iSCSISwName | Add-VirtualSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $VMHostPhysicalNic1 -Confirm:$false
$VMHostPhysicalNic2 = Get-vmhost | Get-VMHostNetworkAdapter -Physical -Name $iSCSIPhyNic2
get-virtualSwitch -name $iSCSISwName | Add-VirtualSwitchPhysicalNetworkAdapter -VMHostPhysicalNic $VMHostPhysicalNic2 -Confirm:$false

Next step is to set the vSwitch policies to what we want. By default most of the settings I have set in the script is the default settings but to be sure I prefer apply it in case VMware changes the default settings out of the box in the future. This way we can ensure we know the exact settings we have applied on the vSwitch. You will see that “Set-NicTeamingPolicy” I have split the command into a few lines and this is just for ease of reading. All the settings could be done using a one-liner
Get-VirtualSwitch -Name $iSCSISwName | Get-SecurityPolicy | Set-SecurityPolicy -AllowPromiscuous $false -MacChanges $true -ForgedTransmits $true -confirm:$false
Get-VirtualSwitch -Name $iSCSISwName | Get-NicTeamingPolicy | Set-NicTeamingPolicy -MakeNicActive $iSCSIPhyNic1,$iSCSIPhyNic2
Get-VirtualSwitch -Name $iSCSISwName | Get-NicTeamingPolicy | Set-NicTeamingPolicy -LoadBalancingPolicy LoadBalanceSrcId
Get-VirtualSwitch -Name $iSCSISwName | Get-NicTeamingPolicy | Set-NicTeamingPolicy -NetworkFailoverDetectionPolicy LinkStatus
Get-VirtualSwitch -Name $iSCSISwName | Get-NicTeamingPolicy | Set-NicTeamingPolicy -FailbackEnabled:$true -NotifySwitches:$true  

Now we create the VMKernel iSCSI adapters and the portgroups for them. Each VMKernel adapter will have its own portgroup
New-VMHostNetworkAdapter -VirtualSwitch $iSCSISwName -Portgroup $iSCSIPg1Name -IP $iSCSIIP1 -SubnetMask $iSCSISubnet -mtu $iSCSIMTU
New-VMHostNetworkAdapter -VirtualSwitch $iSCSISwName -Portgroup $iSCSIPg2Name -IP $iSCSIIP2 -SubnetMask $iSCSISubnet -mtu $iSCSIMTU

We now modify the port group settings for the 1st iSCSI and make the necessary changes where we inherit all the policies from the vSwitch. We set one network card as active and the other one as unused
get-virtualportgroup -Name $iSCSIPg1Name | get-nicteamingpolicy | Set-NicTeamingPolicy -MakeNicActive $iSCSIPhyNic1 -MakeNicUnused $iSCSIPhyNic2
Get-Virtualportgroup -Name $iSCSIPg1Name | Get-SecurityPolicy | Set-SecurityPolicy -AllowPromiscuousInherited $true -ForgedTransmitsInherited $true -MacChangesInherited $true -confirm:$false
get-virtualportgroup -Name $iSCSIPg1Name | get-nicteamingpolicy | Set-NicTeamingPolicy -InheritLoadBalancingPolicy:$true -InheritNetworkFailoverDetectionPolicy:$true
get-virtualportgroup -Name $iSCSIPg1Name | get-nicteamingpolicy | Set-NicTeamingPolicy -InheritNotifySwitches:$true -InheritFailback:$true -InheritFailoverOrder:$false

We now modify the port group settings for the other/2nd iSCSI and make the necessary changes where we inherit all the policies from the vSwitch. On this portgroup we do the opposite to the other port group. The unused network card on the port group above is set to active on this one and the active one is set to unused
get-virtualportgroup -Name $iSCSIPg2Name | get-nicteamingpolicy | Set-NicTeamingPolicy -MakeNicActive $iSCSIPhyNic2 -MakeNicUnused $iSCSIPhyNic1
Get-Virtualportgroup -Name $iSCSIPg2Name | Get-SecurityPolicy | Set-SecurityPolicy -AllowPromiscuousInherited $true -ForgedTransmitsInherited $true -MacChangesInherited $true -confirm:$false
get-virtualportgroup -Name $iSCSIPg2Name | get-nicteamingpolicy | Set-NicTeamingPolicy -InheritLoadBalancingPolicy:$true -InheritNetworkFailoverDetectionPolicy:$true
get-virtualportgroup -Name $iSCSIPg2Name | get-nicteamingpolicy | Set-NicTeamingPolicy -InheritNotifySwitches:$true -InheritFailback:$true -InheritFailoverOrder:$false

We will enable the iSCSI software adapter and let the script sleep for 30 seconds. This is really to let the iSCSI software enable itself in this period of time before moving on
Get-vmhoststorage | set-vmhoststorage -SoftwareIScsiEnabled $true
Write-Host "Sleeping for 30 Seconds..." -ForegroundColor Green
Start-Sleep -Seconds 30

We now get all VMKernel adapters information to be used later for port binding
$vmks = Get-VMHostNetworkAdapter | where {$ -like "vmk*"}

We store the iSCSI HBA details to be used later as well
$hba = Get-vmhost | Get-VMHostHba -Type iScsi | Where {$_.Model -eq "iSCSI Software Adapter"}

We create the connection using to our iSCSI target IP address from our variables using the hba details we got from above
New-IScsiHbaTarget -IScsiHba $hba -Address $iSCSItargetIP

Now we must filter out our VMKernel adapters and only get the ones that are connected to the iSCSI portgroups. We need to capture the device name and store those information
ForEach ($vmk in $vmks){If ($vmk.PortGroupName -eq $iSCSIPg1Name) {$vmkscsi01 = $vmk.DeviceName}}
ForEach ($vmk in $vmks){If ($vmk.PortGroupName -eq $iSCSIPg2Name) {$vmkscsi02 = $vmk.DeviceName}}

To do port binding we have to use esxcli commands but as you can run that in powershell context we will do that
$esxcli = Get-EsxCli -VMHost $ESXHost -v2

We issue the esxcli commands to create the port bindings with the two VMKernel adapters
$esxcli.iscsi.networkportal.add.invoke(@{adapter = $hba.device;nic = $vmkscsi01})
$esxcli.iscsi.networkportal.add.invoke(@{adapter = $hba.device;nic = $vmkscsi02})

I have got the command to print the iSCSI iqn out to screen. If your array just needs this information to create connections, then at this point you could put your code there if it supports powershell so that it goes in to the SAN array to finish off the configurations

We issue a command to get the host to rescan all the HBA and hopefully this will pick up all the LUNS that has been presented to this host and let the script sleep for 30 seconds before carrying on
Get-VMHostStorage -VMHost $ESXHost -RescanAllHba
Write-Host "Sleeping for 30 Seconds to let the host scan and pick up all the luns ..." -ForegroundColor Green
Start-Sleep -Seconds 30
Finally we just disconnect from the host to complete the task
Disconnect-VIServer $ESXHostName -Force -Confirm:$false

Hope this script can come to some use for people that want to automate the build of the iSCSI connections from their ESXi host to iSCSI array. The script could be further enhanced where the variables information of all your host could be in a CSV file and you get the script to just read from the CSV file.


Popular posts from this blog

Rolling back a version of ESXi

There is an option in VMware where after you have performed an major upgrade of ESXi you can roll back to your previous version. The benefit of this is that you would not need to reinstall your ESXi and its configuration if you had issues with the new software. I had to do this on one occassion in my lab where I upgraded from 6.5 to 6.7 and my VMs would not run because the CPU was not supported in 6.7. Please remember if you are using ISO method to upgrade ESXi please ensure you select "Upgrade ESXi, preserve VMFS datastore". Selecting "Install ESXi, preserve VMFS datastore" does not mean preserving datastore means retaining ESXi as it will still do a clean install of ESXi. This method does not work for vSphere 7.0 as there are changes to the partitions on the boot device. Below are the steps to roll back to a previous version which is quite straight forward. As always perform an backup of your host configuration before you upgrade or rollback ( KB2042141 ). I have

Configuring ESXi 6 host to send logs to Syslog Server

In my previous post I talked about configuring VMware Syslog server for Windows which is installed and enabled by default on installation of vCenter 6 for Windows. I will now describe the basic configuration that is required on an ESXi 6 host to be able to send logs out to a syslog server using my vCenter as the example. 1) Navigate to your ESXi host within vCenter. Go to "Manage" tab and select "Settings" followed by "Advanced System Settings". Look for the settings "" and highlight this settings. Click the pencil icon to edit the configuration for this setting. 2) You can now add the host name or ip address of your syslog server/s. You can enter just hostname or IP address, use udp://hostname:514 or ssl://hostname:1514 to be more specific on the port and protocol to be used. If you have multiple hosts then you use the comma (,) to separate each server i.e. udp://,udp:// 3)We n

Custom ESXi Image - ISO using PowerCLI

There comes a time when you have purchased a new hardware to run your ESXi software and discover that the installable base media provided by VMware does not include the drivers or the drivers are out of date. In the world of Windows (Plug and Play) it would discover the hardware and prompt you to provide the drivers so that Windows would install/update the drivers for the hardware. For ESXi if the drivers are not present during load time then the hardware will possibly not work. VMware uses VIB (vSphere Installation Bundle) as a way for vendors to distribute their drivers. To install these VIBs you can either use Update Manager or command line (esxcli). Now this is all good but it does mean you have to first install the base ESXi then use one of the steps above to install/update the drivers.   Some people might feel that it is OK to update the drivers using the above methods but what if it was the network card that was the new hardware and you needed new drivers. Without the net