How to Configure an iSCSI Target on Windows Server 2012 R2
iSCSI (Internet Small Computer System Interface) is a storage networking protocol that transports SCSI commands over standard TCP/IP networks, allowing servers to access block-level storage on remote targets as if the storage were a locally attached disk. Windows Server 2012 R2 includes a built-in iSCSI Target Server role, enabling you to create software-based iSCSI targets without dedicated SAN hardware. This is particularly useful for providing shared storage to Hyper-V clusters, test environments, and SQL Server instances.
This guide covers installing the iSCSI Target Server, creating virtual disks and targets, connecting iSCSI initiators, and optimising iSCSI performance for production workloads.
Prerequisites
- Windows Server 2012 R2 for the iSCSI Target Server role.
- A dedicated storage volume on the target server (separate from the OS).
- A dedicated network for iSCSI traffic (1 GbE minimum; 10 GbE recommended for production).
- iSCSI initiator hosts (Windows servers or other OS) configured with the iSCSI initiator service.
- Jumbo frames configured on all iSCSI NICs and switches for performance (optional but recommended).
Step 1: Install the iSCSI Target Server Role
# Install iSCSI Target Server role with management tools
Install-WindowsFeature -Name FS-iSCSITarget-Server -IncludeManagementTools
# Also install iSCSI Target Storage Provider (VSS/VDS support)
Install-WindowsFeature -Name iSCSITarget-VSS-VDS
# Verify installation
Get-WindowsFeature -Name FS-iSCSITarget*, iSCSITarget* |
Where-Object { $_.InstallState -eq "Installed" } |
Select-Object Name, DisplayName
# Verify the iSCSI Target service is running
Get-Service -Name WinTarget | Select-Object Name, Status, StartType
Step 2: Create iSCSI Virtual Disks
iSCSI virtual disks are files stored on the target server that appear as raw block devices to the initiator. They can be fixed-size (allocated immediately) or dynamically expanding.
# Create the storage directory
New-Item -Path "D:iSCSIVirtualDisks" -ItemType Directory
# Create a fixed-size iSCSI virtual disk (100 GB)
# Fixed disks have better performance than dynamic
New-IscsiVirtualDisk `
-Path "D:iSCSIVirtualDisksCluster-Shared01.vhdx" `
-SizeBytes 100GB `
-Description "Shared disk for Failover Cluster"
# Create a dynamically expanding virtual disk
New-IscsiVirtualDisk `
-Path "D:iSCSIVirtualDisksSQLData01.vhdx" `
-SizeBytes 200GB `
-Description "SQL Server data volume" `
-UseFixed:$false
# Create a differencing virtual disk (based on a parent)
# Useful for test environments sharing a base image
New-IscsiVirtualDisk `
-Path "D:iSCSIVirtualDisksTestVM-Diff.vhdx" `
-ParentPath "D:iSCSIVirtualDisksBase.vhdx" `
-Description "Differencing disk for test VM"
# List all virtual disks
Get-IscsiVirtualDisk | Select-Object Path, Size, Description
Step 3: Create iSCSI Targets
An iSCSI target is the logical endpoint that initiators connect to. Each target has an IQN (iSCSI Qualified Name) and can have one or more virtual disks attached to it. Access control is based on the initiator’s IQN.
# Create an iSCSI target for a Failover Cluster
New-IscsiServerTarget `
-TargetName "cluster01-shared" `
-Description "Shared storage for CLUSTER01 failover cluster" `
-InitiatorIds @("IQN:iqn.1991-05.com.microsoft:node01.corp.example.com",
"IQN:iqn.1991-05.com.microsoft:node02.corp.example.com")
# Create a target for a SQL Server
New-IscsiServerTarget `
-TargetName "sql01-storage" `
-Description "Storage for SQL01 server" `
-InitiatorIds @("IQN:iqn.1991-05.com.microsoft:sql01.corp.example.com")
# Attach a virtual disk to the target
Add-IscsiVirtualDiskTargetMapping `
-TargetName "cluster01-shared" `
-Path "D:iSCSIVirtualDisksCluster-Shared01.vhdx"
# Attach the SQL disk to its target
Add-IscsiVirtualDiskTargetMapping `
-TargetName "sql01-storage" `
-Path "D:iSCSIVirtualDisksSQLData01.vhdx"
# List all targets
Get-IscsiServerTarget | Select-Object TargetName, IsChapEnabled, InitiatorIds, LunMappings
Step 4: Configure CHAP Authentication
CHAP (Challenge Handshake Authentication Protocol) secures iSCSI connections by requiring the initiator to prove its identity with a shared secret. Always enable CHAP in production environments.
# Enable one-way CHAP on the target (target validates the initiator)
Set-IscsiServerTarget `
-TargetName "sql01-storage" `
-ChapUserName "sql01-initiator" `
-ChapSecret "C0mpl3xCHAPSecret!"
# Enable mutual CHAP (both sides authenticate each other)
Set-IscsiServerTarget `
-TargetName "sql01-storage" `
-EnableChap $true `
-ChapUserName "sql01-initiator" `
-ChapSecret "C0mpl3xCHAPSecret!" `
-EnableReversedChap $true `
-ReversedChapUserName "iscsi-target01" `
-ReversedChapSecret "Rev3rs3CHAP!"
# On the initiator side (connecting server), configure CHAP in the iSCSI Initiator properties
# Control Panel -> iSCSI Initiator -> Discovery tab -> Advanced
# Or via PowerShell on the initiator:
New-IscsiTargetPortal `
-TargetPortalAddress "192.168.100.10" `
-AuthenticationType ONEWAYCHAP `
-ChapUsername "sql01-initiator" `
-ChapSecret "C0mpl3xCHAPSecret!"
Step 5: Connect the iSCSI Initiator
On each initiator server (the servers that will use the iSCSI storage), configure the iSCSI initiator service and connect to the target.
# On the INITIATOR server:
# Start and enable the Microsoft iSCSI Initiator Service
Start-Service -Name MSiSCSI
Set-Service -Name MSiSCSI -StartupType Automatic
# Get the initiator's IQN (note this and provide it to the target admin)
Get-InitiatorPort | Select-Object NodeAddress
# Add the iSCSI target portal (target server's IP)
New-IscsiTargetPortal -TargetPortalAddress "192.168.100.10"
# Discover available targets on the portal
Get-IscsiTarget | Select-Object NodeAddress, IsConnected
# Connect to the target (without CHAP)
Connect-IscsiTarget `
-NodeAddress "iqn.1991-05.com.microsoft:iscsisvr01-sql01-storage-target" `
-IsPersistent $true
# Connect to the target with CHAP
Connect-IscsiTarget `
-NodeAddress "iqn.1991-05.com.microsoft:iscsisvr01-sql01-storage-target" `
-AuthenticationType ONEWAYCHAP `
-ChapUsername "sql01-initiator" `
-ChapSecret "C0mpl3xCHAPSecret!" `
-IsPersistent $true
# Verify the connection
Get-IscsiSession | Select-Object SessionIdentifier, IsConnected, IsPersistent
Step 6: Configure Multipath IO (MPIO) for Redundancy
MPIO allows multiple physical network paths to the same iSCSI target, providing both bandwidth aggregation and failover if one network path fails.
# Install MPIO feature on the initiator server
Install-WindowsFeature -Name Multipath-IO
# Enable MPIO for iSCSI devices
Enable-MSDSMAutomaticClaim -BusType iSCSI
# Connect to the target via a second path (second NIC on initiator to same target)
Connect-IscsiTarget `
-NodeAddress "iqn.1991-05.com.microsoft:iscsisvr01-sql01-storage-target" `
-TargetPortalAddress "192.168.101.10" `
-InitiatorPortalAddress "192.168.101.20" `
-IsPersistent $true
# Set MPIO load balancing policy
Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy RR # Round Robin
# Other policies: LQD (Least Queue Depth), LB (Least Blocks), FO (Failover Only)
# View MPIO paths
Get-MSDSMSupportedHW
mpclaim -s -d
Step 7: Format and Use the iSCSI Disk
# After connecting, the iSCSI disk appears as a new disk in Disk Management
# Initialize and format it like any local disk
# Find the new disk
Get-Disk | Where-Object { $_.BusType -eq "iSCSI" } |
Select-Object Number, FriendlyName, Size, OperationalStatus
# Initialize and format
$disk = Get-Disk | Where-Object { $_.BusType -eq "iSCSI" -and $_.PartitionStyle -eq "RAW" }
Initialize-Disk -Number $disk.Number -PartitionStyle GPT -PassThru |
New-Partition -DriveLetter S -UseMaximumSize |
Format-Volume -FileSystem NTFS -NewFileSystemLabel "iSCSI-SQLData" -Confirm:$false
# Verify the volume
Get-Volume -DriveLetter S | Select-Object FileSystemLabel, SizeRemaining, Size
Summary
The iSCSI Target Server on Windows Server 2012 R2 provides a cost-effective way to deliver shared block storage to servers and clusters without dedicated SAN hardware. The key configuration steps are: install the iSCSI Target Server role, create virtual disk files on a dedicated storage volume, create targets with access control lists based on initiator IQNs, enable CHAP authentication for security, connect initiators from each client server using persistent connections, and deploy MPIO for redundant paths if availability is required. For production deployments — particularly shared storage for Failover Clusters — use a dedicated 10 GbE iSCSI network with jumbo frames enabled on all adapters and switches to achieve the lowest latency and highest throughput.