Azure Local with Everpure FlashArray Quick Start Guide for Hyperconverged Deployments

Microsoft Platform Guide

Audience
Public
Source Type
Documentation

This guide provides a high-level workflow for integrating the Everpure FlashArray as the primary block storage for Azure Local (formerly Azure Stack HCI). This solution combines the cloud-integrated benefits of Azure Local with the high-performance, data-reduced storage of FlashArray.

Prerequisites to Using the Quick Start Guide

Before you begin, ensure that the following requirements are met:

Everpure FlashArray

  • A deployed and configured Everpure FlashArray.

  • Fibre Channel (FC) must be enabled and configured on the array, with active zoning and connectivity established between the FlashArray and all Azure Local nodes.

  • SAN Guidelines for Maximizing FlashArray Performance

  • Minimum Recommended Purity Version: 6.5.3
    Note: Currently FC is the only supported protocol for external block storage on Azure Local.
Azure Local Deployment (Base)

Before connecting FlashArray storage, the Azure Local cluster must be deployed and registered with Azure.

  • Refer to the Microsoft Azure Local Deployment Documentation for hardware validation, networking and cloud deployment steps.

  • A minimum of 1 Azure Local node is required

  • Minimum Azure Local Version: 2604

  • Ensure that the Azure Local Cluster Name Object (CNO) is created and that the cluster and its nodes are healthy and visible. This can be verified in several ways:

    • Azure Portal: Azure Local Connection Status

      • In the Azure portal, navigate to the Azure Local cluster resource and review the Overview page. The cluster should show a healthy and connected status with no errors. This indicates that the cluster identity, including the CNO, is functioning correctly with Azure.

    • Azure Portal: Cluster Nodes (Resources)

      • Within the same Azure Local resource, review the list of machines under Resources. All cluster nodes should be present, online, and reporting a healthy state. This confirms that the nodes are properly joined to the cluster and recognized by Azure.

At a high-level, the Azure Local integration with FlashArray includes the following steps once the prerequisites are completed:

  1. Configure the Azure Local nodes

  2. Everpure FlashArray Setup

  3. Azure Local Cluster Storage Configuration

While graphical interfaces such as Windows Admin Center or Failover Cluster Manager are available for setup and administration, PowerShell is the recommended method for the initial setup of Azure Local deployments. PowerShell provides a higher degree of precision, consistency across nodes, and scriptability for configurations. This guide focuses on PowerShell-based execution, supplemented by GUI screenshots to illustrate key validation points.

For the best experience and compatibility, it is recommended to use PowerShell 7.6 or later when performing the steps outlined in this guide.
Note: Before you begin naming your resources, it is important to note that Azure does not support the use of underscores (_) for these resource types. While the FlashArray is flexible with naming, we recommend using hyphens (-) for your Host, Host Group, and Volume names instead. This ensures your configuration remains fully compatible with Azure Arc-enabled services and allows for a seamless management experience within the Azure Portal
  1. Configure the Azure Local Instances

    Multipath I/O (MPIO) is a critical configuration requirement for Azure Local nodes. It provides hardware resiliency by establishing redundant physical paths between the node and the storage array, ensuring connectivity remains uninterrupted during a path failure. Additionally, MPIO facilitates performance load balancing by distributing I/O traffic across all active paths, preventing bottlenecks on a single interface.

    1. HBA Driver and Firmware
      Before proceeding with software configuration, the physical Host Bus Adapters (HBAs) must be upgraded to vendor-specific versions. Using default HBA drivers is insufficient for production environments.
      • All HBAs (e.g., Marvell/QLogic or Broadcom/Emulex) must run vendor-specific drivers and firmware versions found in the Windows Server Catalog for Azure Stack HCI (Azure Local).

      • In addition, the selected HBA must be supported by the server vendor for the specific server model in use. This includes validation of the adapter, firmware, and driver combination as part of the server vendor’s supported configuration to ensure compatibility and supportability for Azure Local deployments.

      • Install and confirm that the latest validated drivers are running on the HBAs.

    2. Enable the MPIO Feature
      The MPIO framework must be installed and active on every node in the cluster to manage the redundant connections to the FlashArray.
      Prerequisite
      Attention: If you plan to remotely access an Azure Local node to run PowerShell commands, Remote Management must be enabled on the target node using the SConfig utility (Option 4). Ensure the firewall allows WinRM traffic to support the connection.
      Note: All MPIO setup and configuration commands in this section must be executed individually on each Azure node
      • PowerShell Connection Command: Enter-PSSession -ComputerName <Node_Name> -Credential (Get-Credential)
        • Use his command to establish a remote PowerShell session to one of the nodes in the Azure Local cluster from your local device.

      • PowerShell Command: Install-WindowsFeature -Name Multipath-IO

    3. Claim FlashArray as an MPIO Target

      By default, the operating system does not automatically claim external storage arrays for multipathing. The FlashArray hardware identifiers must be registered with the Microsoft Device Specific Module (MSDSM).

      • PowerShell Command: New-MSDSMSupportedHw -VendorId "PURE" -ProductId "FlashArray"

        • This command registers Everpure devices as MPIO-capable. Modern versions of PowerShell automatically handle the character padding (e.g. extra spaces) for these IDs.

      Note: A reboot is required after running this command for the MSDSM to begin claiming the FlashArray.
    4. Configure MPIO Best Practices

      Once the MPIO feature is enabled, global settings must be configured to ensure the system handles multipathing in accordance with FlashArray performance and resiliency standards.

      Recommendation:
      • 10 or fewer paths: Use Round Robin (RR). This ensures that as soon as FlashArray volumes are presented, the node automatically utilizes all available paths in a rotating fashion.

      • More than 10 paths: Use Least Queue Depth (LQD). In environments with a high number of paths, LQD can provide better performance by directing I/O to the path with the fewest outstanding requests.

      • Powershell Commands: Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy RR OR Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy LQD

      Note: For a deeper dive into choosing the correct policy for your specific storage topology, refer to the Setting the MPIO Policy KB article in the Everpure Microsoft Platform Guide. Note that Round Robin with Subset (RRWS) is also an option for high path counts but cannot be set as a global default and must be configured on a per-volume basis.

      Configure Path Verification and Timeouts

      Properly tuning MPIO timers prevents premature path failovers and ensures the system can recover gracefully from momentary network hiccups.

      • PowerShell Command: Set-MPIOSetting -NewPathRecoveryInterval 20 -NewPathVerificationPeriod 30 -NewPDORemovePeriod 30

        • These settings define the "grace period" for path failures. Specifically, NewPDORemovePeriod determines how many seconds the Azure node OS will wait for a failed path to recover. By holding the failover for 30 seconds, the system allows MPIO to complete a path-level failover without the Cluster Storage Service seeing the disk as "gone" and prematurely triggering a resource failover to a different node.
          Note: The values provided above are recommended values for FlashArray integration and were found internally from lab testing. Customers with highly specific latency requirements or complex fabric topologies may require additional testing and tuning to determine the optimal timeout values for their specific workload.
    5. Verification of Azure Node Readiness

      Before moving to Phase 2 (FlashArray Preparation), verify that the environment is correctly staged and gather the necessary identifiers.

      Check MPIO Settings:
      • PowerShell Command: Get-MPIOSetting

        • Ensure the PathVerificationPeriod and PDORemovePeriod match the values configured in step 1.4.

      Check Global Policy:

      • PowerShell Command: Get-MSDSMGlobalDefaultLoadBalancePolicy

        • Confirm the output returns RR (Round Robin) or LQD (Least Queue Depth).

      Check Claimed Hardware:
      • PowerShell Command: Get-MSDSMSupportedHw

        • Confirm that "PURE" and "FlashArray" appear in the list of supported hardware.

      Collect WWNs for FlashArray Configuration:
      • PowerShell Command: Get-InitiatorPort

        • Execute this command to identify and record the World Wide Names (WWNs) of the HBAs for each node. These identifiers are required in the next phase to create the host objects on the FlashArray.

  2. Everpure FlashArray Setup

    Once the Azure Local nodes are prepared and their HBA identifiers (WWNs) have been collected, the next phase involves provisioning the storage resources on the Everpure FlashArray.

    This guide utilizes the Everpure PowerShell SDK v2. This programmatic approach is often preferred over the CLI or GUI for its repeatability and ease of integration into larger deployment scripts.

    • PowerShell Command: Install-Module -Name PureStoragePowerShellSDK2 -Force -AllowClobber

      Import-Module -Name PureStoragePowerShellSDK2

      • Install and import the Everpure PowerShell SDK v2 module to your management workstation. These modules should not be installed on your Azure Local node as they are locked down from a security perspective.

    • PowerShell Command: $Conn = Connect-PFA2Array -Endpoint "<FlashArray_Management_VIP>" -Credential (Get-Credential) -IgnoreCertificateError

      • Establish a secure connection to the FlashArray management VIP. Alternative authentication methods such as using a FlashArray-based API token are also supported.

    1. Create Host Objects
      A host object must be created on the FlashArray for every physical node in the Azure Local instance. This allows the array to map specific WWNs to each node.
      • PowerShell Command: New-Pfa2Host -Array $Conn -Name "<Node_Name>" -Wwn "<WWN_1>", "<WWN_2>"

        • Execute this command for each node in the cluster. Replace <Node_Name> with the hostname of the Azure Local node and and the WWNs found at the end of the previous section.

    2. Create and Configure the Host Group
      In a clustered environment, hosts should be managed via a Host Group. This ensures that all nodes in the Azure Local deployment have consistent, simultaneous access to the same volumes, which is a requirement for Clustered Shared Volumes (CSV).
      • PowerShell Command: New-Pfa2HostGroup -Array $Conn -Name "<Host_Group_Name>"

        • Create a single host group to represent the entire Azure Local cluster (e.g., Azure-Local-Cluster-01).

      • PowerShell Command: New-Pfa2HostGroupHost -Array $Conn -GroupName "<Host_Group_Name>" -MemberName "<Node_1_Name>", "<Node_2_Name>"

        • Add all previously created host objects into the newly created host group.

    3. Create the Storage Volume
      Define the FlashArray volume that will serve as the shared storage for the cluster.
      • PowerShell Command: New-Pfa2Volume -Array $Conn -Name "<Volume_Name>" -Provisioned <Size_in_TB>TB

        • Create the volume. Replace <Size_in_TB> with the desired numeric capacity (GB and other capacity values are also supported) and <Volume_Name> with a descriptive name.

    4. Connect Volume to Host Group
      Mapping the volume to the Host Group makes the storage visible to all member nodes.
      • PowerShell Command: New-Pfa2Connection -Array $Conn -VolumeName "<Volume_Name>" -HostGroupName "<Host_Group_Name>"

        • By connecting the volume to the Host Group rather than individual hosts, the FlashArray ensures LUN ID consistency across all nodes in the cluster.

      This completes provisioning storage on the FlashArray. The FlashArray is now presenting the volume to the Azure Local nodes, and it can now be set up as a Cluster Shared Volume.

  3. Azure Local Cluster Storage Configuration

    Once the FlashArray volume is mapped to the host group, the final phase is to initialize and format the storage on the Azure Local nodes and promote it to a Clustered Shared Volume (CSV). This process transitions the storage from a raw LUN to a shared namespace (C:\ClusterStorage\) usable by every node in the cluster simultaneously.

    Note: The steps in this section are typically executed while connected to a single Azure Local Node. Once the storage is integrated into the cluster and promoted to a CSV, the configuration is automatically synchronized and available to all other member nodes.
    Important:

    Before attempting to connect, Remote Management must be enabled on the target node via the SConfig utility (Option 4). Ensure your firewall allows WinRM traffic to facilitate the connection.

    PowerShell Connection Command:Enter-PSSession -ComputerName <Node_Name> -Credential (Get-Credential)

    • Use his command to establish a remote PowerShell session to one of the nodes in the Azure Local cluster.

    1. Storage Rescan and Identification
      Before the node can interact with the new FlashArray volume, the storage stack must be refreshed to detect the newly mapped LUN.
      • PowerShell Command: Update-HostStorageCache

        • Execute this command to force the operating system to discover the volume presented in Procedure 2.

      • PowerShell Command: Get-Disk

        • Locate the new FlashArray disk in the list. It will typically appear as "Offline" with a status of "Uninitialized." Identify and record the <Disk_Number>.

      • PowerShell Command: mpclaim -s -d

        • Use this command to list all MPIO managed disks and identify the correct disk by its MPIO Disk number (shown in the first column). If needed, you can correlate this with the Windows disk number from Get-Disk by matching the underlying device (for example, size or vendor such as PURE FlashArray).

        • Sample Output:
          MPIO Disk    System Disk  LB Policy    DSM Name
          ------------------------------------------------------------
          MPIO Disk2   Disk 5       RR           Microsoft DSM
          
        • Once identified, specify the disk by its MPIO Disk number to view detailed information: mpclaim -s -d <MPIO_Disk_Number>

          Verify the MPIO state of the selected disk. The output should show multiple active paths, the load balancing policy (such as Round Robin), and the DSM in use. Confirm that multiple paths are present to ensure that load balancing and resiliency configurations are active on this specific volume.

          Sample Output:
          MPIO Disk2
          ------------------------------------------------------------
          Paths:                     4
          Load Balance Policy:       Round Robin
          Access Type:               Symmetric Access
          Controlling DSM:           Microsoft DSM
          Serial Number (SN):        624A9370F269A91400C5408F008EF2B2
          Supported Load Balance Policies:
          FOO, RR, RRWS, LQD, WP, LB
          Path Details:
          ---------------------------------------------------------------------------
          Path ID           State              SCSI Address     Weight
          ---------------------------------------------------------------------------
          0000000077030001  Active/Optimized   003|000|001|254  0
                            TPG State: Active/Optimized | TPG ID: 0
          0000000077030000  Active/Optimized   003|000|000|254  0
                            TPG State: Active/Optimized | TPG ID: 1
          .
          .
          
    2. Disk Preparation and Formatting
      The raw disk must be initialized, partitioned, and formatted before it can be introduced to the cluster.
      • PowerShell Command: Set-Disk -Number <Disk_Number> -IsOffline $false

        • Transitions the disk to an Online state to allow for initialization.

      • PowerShell Command: Initialize-Disk -Number <Disk_Number> -PartitionStyle GPT

        • Prepares the disk using a GPT partition table, which is required for all Azure Local storage volumes.

      • PowerShell Command: New-Partition -DiskNumber <Disk_Number> -UseMaximumSize

        • Creates a new partition using the full available capacity. Note the assigned <Partition_Number> (typically 2 for GPT disks) for the following formatting step.

      • PowerShell Command: Get-Partition -DiskNumber <Disk_Number> -PartitionNumber <Partition_Number> | Format-Volume -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel "<Volume_Label>" -Confirm:$false

        • Formats the partition. NTFS with a 64KB (65536 bytes) allocation unit size is the recommended configuration for Azure Local to optimize Hyper-V performance and leverage features like block cloning. However, alternative allocation unit sizes remain a supported option.

    3. Cluster Integration and CSV Promotion
      Once the disk is formatted, it is moved into the Azure Local cluster's control and promoted to a shared resource.
      • Option A: Automated Disk Addition

        If the volume has been correctly formatted and is the only available disk not yet in the cluster, the following PowerShell pipeline will add the ClusterDisk:

        • PowerShell Command: Get-ClusterAvailableDisk -All | Add-ClusterDisk | Add-ClusterSharedVolume

          • Automatically identifies all eligible storage, adds it to the cluster, and promotes it to a Clustered Shared Volume in a single operation.
            Warning: The command above is a "bulk" operation. It will automatically capture all disks currently presented to the nodes that are initialized and online but not yet members of the cluster. If you have multiple new volumes intended for different purposes, do not use this pipeline, as it will convert every available disk into a Clustered Shared Volume, instead use Option B below.
      • Option B: Targeted Disk Addition

        If you need to target a specific disk number or if the automated command does not return the expected disk, use the manual method:

        • PowerShell Command: Get-Disk -Number <Disk_Number> | Add-ClusterDisk

          • Manually adds the specific FlashArray disk to the cluster's "Available Storage" pool.

        • PowerShell Command: Add-ClusterSharedVolume -Name "Cluster Disk X"

          • Converts the specific cluster resource to a CSV. In this context, "Cluster Disk X" refers to the Name assigned by the Failover Cluster service when the disk was added in the previous step.

          • When you execute Add-ClusterDisk in the previous step, the cluster automatically names the new resource (e.g., Cluster Disk 1, Cluster Disk 2, etc.) in the order it was discovered. To identify the correct name before running this command, you can run Get-ClusterResource | Where-Object {$_.ResourceType -eq "Physical Disk"} to see a list of all disks currently in the "Available Storage" pool.

      • Cluster Disk Renaming <Optional>:

        • PowerShell Command: (Get-ClusterSharedVolume -Name "Cluster Disk 1").Name = "<New_CSV_Name>"

          • You can optionally rename the generic cluster resource (e.g., "Cluster Disk 1") to your preferred <New_CSV_Name> to be more easily able to see what CSV maps to the FlashArray.

    4. Verification of Clustered Shared Storage
      Validate the final state of the CSV to ensure it is healthy and available across the cluster.
      • PowerShell Command: Get-ClusterSharedVolume -Name "<CSV_Name>"

        • Confirm the volume state is "Online" and that the "Shared Volume" property is correctly set

    5. Creating an Azure Storage Path

      After the CSV is online, it must be registered as a Storage Path in the Azure Portal. This allows Azure Arc-enabled service and Azure VM management to use FlashArray storage.

      Finding the Local CSV Path

      Once a disk is promoted to a Clustered Shared Volume (CSV), it is mounted as a folder under C:\ClusterStorage on every Azure Local node in the cluster. While the FlashArray volume might have a descriptive name, Windows typically assigns these folders generic names like Volume1, Volume2, etc. by default unless they are manually renamed. Record the CSV path for use in the next steps.

      Powershell
      Get-ClusterSharedVolume | Select-Object Name -ExpandProperty SharedVolumeInfo | Select-Object Name, FriendlyVolumeName
      
      1. Login to the Azure Portal and search for Azure Local . Select your cluster from the list under All Systems .

      2. In the left-hand navigation blade, under the Resources section, select Storage Paths .

      3. Click on the +Create storage path button.

      4. Fill in the two fields:

        File system path: Provide the local directory of the CSV as seen on an Azure Local node as described above. For example: C:\ClusterStorage\Volume1

        Name: Provide a friendly name for the storage path

        Click on the Create button.

      5. After a few minutes the Storage Path will appear within the Azure Portal.

Appendix

IMPORTANT: The following script block is a collection of reference commands for configuring Nutanix/Azure Local environments with Everpure FlashArray.

DO NOT run this entire set of commands sequentially. These commands are executed across different platforms:
  • Everpure PowerShell SDK: Commands are run from a management workstation to configure the FlashArray.

  • Remote PowerShell/Windows: Commands are run within an Azure Local node session to configure MPIO, disk initalization and Cluster Shared Volumes.

Ensure you replace all placeholders (e.g., `<FlashArray_Management_VIP>`, `<Volume_Name>`) with your environment-specific values before execution.
#PreReq
if (!(Get-Module -ListAvailable -Name PureStoragePowerShellSDK2)) { Install-Module -Name PureStoragePowerShellSDK2 -Force -AllowClobber -Scope CurrentUser }; Import-Module -Name PureStoragePowerShellSDK2

#Connect to Array Endpoint
$Conn = Connect-PFA2Array -Endpoint "<FlashArray_Management_VIP>" -Credential (Get-Credential) -IgnoreCertificateError 

#Create Host Object(s)
New-Pfa2Host -Array $Conn -Name "<Node_Name>"  -
Update-Pfa2Host -Array $Conn -Name "<Node_Name>" -Wwns "<WWN_1>", "<WWN_2>" 
New-Pfa2HostGroup -Array $Conn -Name "<Host_Group_Name>" 
New-Pfa2HostGroupHost -Array $Conn -GroupName "<Host_Group_Name>" -MemberName "<Node_1_Name>", "<Node_2_Name>" 

#Create Volume
New-Pfa2Volume -Array $Conn -Name "<Volume_Name>" -Provisioned <Size_in_TB>TB 

#Add Volume to HostGroup
New-Pfa2Connection -Array $Conn -HostGroupName "<Host_Group_Name>"  -VolumeName "<Volume_Name>"

#Enter Azure Local Node for Remote Powershell
Enter-PSSession -ComputerName <Node_Name> -Credential (Get-Credential)

#Install MPIO
Install-WindowsFeature -Name Multipath-IO

#Claim Pure FlashArray as an MPIO Target
New-MSDSMSupportedHw -VendorId "PURE" -ProductId "FlashArray"


#Set Default Load Balance Policy
Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy RR #Less Than 10 Paths
Set-MSDSMGlobalDefaultLoadBalancePolicy -Policy LQD #More than 10 Paths

#Configure MPIO Settings
Set-MPIOSetting -NewPathRecoveryInterval 20 -NewPathVerificationPeriod 30 -NewPDORemovePeriod 30

#Rescan Storage
Update-HostStorageCache

#Identify Disk
Get-Disk
$DiskNumber = Disk_Number

#Online Disk
Set-Disk -Number $DiskNumber -IsOffline $false

#Initialize Disk
Initialize-Disk -Number $DiskNumber -PartitionStyle GPT

#Partition Disk
$Partition = New-Partition -DiskNumber $DiskNumber -UseMaximumSize

#Format Disk
Get-Partition -DiskNumber $DiskNumber -PartitionNumber $Partition.PartitionNumber | Format-Volume -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel "<Volume_Label>" -Confirm:$false

#Add Disk as Clustered Disk
$ClusterDisk = Get-Disk -Number $DiskNumber | Add-ClusterDisk

#Add Cluster Shared Volume
Add-ClusterSharedVolume -Name $ClusterDisk.Name

#Rename Cluster Shared Volume
(Get-ClusterSharedVolume -Name $ClusterDisk.Name).Name = "<New_CSV_Name>"