Introduction to iSCSI Initiator and SAN Connectivity on Windows Server 2019

The iSCSI Initiator in Windows Server 2019 allows the server to connect to iSCSI targets (LUNs) exposed by SAN storage arrays, NAS devices, or other Windows servers running the iSCSI Target Server role. The initiator is built into Windows Server 2019 as the Microsoft iSCSI Initiator service (MSiSCSI) and requires no additional hardware — it runs over standard TCP/IP networking. For production SAN connectivity, dedicated network adapters on a separate storage VLAN with jumbo frames are strongly recommended to isolate storage traffic and maximise performance.

iSCSI storage is commonly used for SQL Server databases, Hyper-V virtual machine storage, and Exchange message databases. Windows Server 2019 supports MPIO (Multipath I/O) for iSCSI, which provides redundancy and load balancing across multiple network paths to the SAN.

Starting the iSCSI Initiator Service

The iSCSI Initiator service is installed by default but may not be running. Start and configure it to start automatically:

Start-Service -Name MSiSCSI
Set-Service -Name MSiSCSI -StartupType Automatic

Verify the service is running:

Get-Service -Name MSiSCSI

Find the IQN (iSCSI Qualified Name) of this initiator — you need this to configure the SAN to allow access from this server:

Get-InitiatorPort | Select NodeAddress, ConnectionType, OperationalStatus

The IQN format looks like: iqn.1991-05.com.microsoft:servername. Provide this IQN to your SAN administrator to add to the storage array’s initiator group.

Configuring iSCSI Target Portals

A target portal is the IP address and port of the iSCSI target (SAN controller). Add the target portal to discover available LUNs:

New-IscsiTargetPortal -TargetPortalAddress "10.30.0.20" -TargetPortalPortNumber 3260

Add a second controller portal for redundancy (most SANs have dual controllers):

New-IscsiTargetPortal -TargetPortalAddress "10.30.0.21" -TargetPortalPortNumber 3260

Specify which local initiator IP address to use for each portal (important when you have multiple storage NICs):

New-IscsiTargetPortal -TargetPortalAddress "10.30.0.20" -InitiatorPortalAddress "10.30.0.100" -TargetPortalPortNumber 3260
New-IscsiTargetPortal -TargetPortalAddress "10.30.0.21" -InitiatorPortalAddress "10.30.0.101" -TargetPortalPortNumber 3260

View all configured target portals:

Get-IscsiTargetPortal

Discovering and Connecting to iSCSI Targets

After adding the target portals, discover available targets:

Update-IscsiTarget

List discovered targets:

Get-IscsiTarget | Select NodeAddress, IsConnected

Connect to a target. Use -IsPersistent $true to reconnect automatically after reboots:

Connect-IscsiTarget -NodeAddress "iqn.2000-01.com.sanarray:vol01" -TargetPortalAddress "10.30.0.20" -InitiatorPortalAddress "10.30.0.100" -IsPersistent $true

For CHAP-authenticated targets, provide credentials:

Connect-IscsiTarget -NodeAddress "iqn.2000-01.com.sanarray:vol01" -TargetPortalAddress "10.30.0.20" -InitiatorPortalAddress "10.30.0.100" -AuthenticationType OneWayCHAP -ChapUsername "iscsiuser" -ChapSecret "CHAPsecret123!" -IsPersistent $true

Verify the connection:

Get-IscsiSession | Select TargetNodeAddress, IsConnected, ConnectionIdentifier, InitiatorIPAddress, TargetAddress

Configuring MPIO for iSCSI

Multipath I/O (MPIO) provides redundancy and load balancing across multiple iSCSI paths. Install the MPIO feature:

Install-WindowsFeature -Name Multipath-IO -IncludeManagementTools

Enable MPIO support for iSCSI devices:

Enable-MSDSMAutomaticClaim -BusType iSCSI

Configure the MPIO load balance policy. RoundRobin distributes I/O across all paths:

Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy RR

After configuring MPIO, connect to the same iSCSI target through the second path (second storage NIC to second SAN controller):

Connect-IscsiTarget -NodeAddress "iqn.2000-01.com.sanarray:vol01" -TargetPortalAddress "10.30.0.21" -InitiatorPortalAddress "10.30.0.101" -IsMultipathEnabled $true -IsPersistent $true

Verify MPIO paths are active:

Get-Disk | Get-StorageReliabilityCounter
mpclaim -s -d

Initialising and Formatting iSCSI LUNs

After connecting, the iSCSI disk appears as an offline disk in Windows. Bring it online and initialise it:

Get-Disk | Where-Object {$_.OperationalStatus -eq "Offline" -and $_.BusType -eq "iSCSI"} | Set-Disk -IsOffline $false
Get-Disk | Where-Object {$_.PartitionStyle -eq "RAW" -and $_.BusType -eq "iSCSI"} | Initialize-Disk -PartitionStyle GPT

Create a partition and format it:

$iSCSIDisk = Get-Disk | Where-Object {$_.BusType -eq "iSCSI" -and $_.PartitionStyle -eq "GPT" -and $_.NumberOfPartitions -eq 0} | Select-Object -First 1
New-Partition -DiskNumber $iSCSIDisk.Number -UseMaximumSize -AssignDriveLetter
Format-Volume -DriveLetter F -FileSystem NTFS -NewFileSystemLabel "SAN-LUN01" -AllocationUnitSize 65536 -Confirm:$false

The iSCSI-attached SAN LUN is now formatted and ready for use by SQL Server, Hyper-V, or any other application requiring high-performance block storage.