Pure Storage PowerShell SDK2 version 2.43.46 released!
We released the Pure Storage PowerShell SDK version 2.43.30 not too long ago. We have since received reports of users having issue with the Connect-Pfa2Array cmdlet only when using PowerShell version 5.x. The error would something similar to this: Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral, PublicKeyToken=someToken' or one of its dependencies. We have released a fix for this in the PowerShell Gallery. https://www.powershellgallery.com/packages/PureStoragePowerShellSDK2/2.43.46. This was the only fix for this release and the issue does not affect the cmdlet when used with PowerShell version 7.x. To upgrade, run Install-Module: Install-Module -Name PureStoragePowerShellSDK2 -Repository PSGallery -RequiredVersion 2.43.46 -Verbose -Force We do apologize for any inconvenience this may have caused.14Views1like0CommentsNew Pure Code site is live!
After many months of messing with some very old code, we have launched a revised site for the Pure Code Portal. It is much more minimalistic and cleaner than the old one, and we have plans to add our Code videos and Pure Employee website links in the near future. Have a look and feel free to leave a comment if you would like to see something on the site. https://code.purestorage.com/ Cheers, //Mike35Views2likes1CommentSome Fleet Python code using the response module
This is the Python sister script to the posted PowerShell version. This script is a Python script that uses the response module to do the tasks. It does not use the Pure Storage pyClient. This is for folks who do raw API calls using automation packages, runbooks, and scripts. It is not intended to use in it's entirety, but rather to be used as code snippets and starters for your own scripts. The full script is available in this GitHub repository. This script will: Use native Python calls to the FlashArray API Authenticates an API Token user and gets the x-auth-token for requests Query a fleet and determine the fleet members Query fleet Presets & Workloads List fleet volumes and hosts (top X, configurable) Create a host, volume, and then connect the volume to the host on a member array. #!/usr/bin/env python3 import json import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Set target array address target = "10.0.0.10" # API version to use # TO-DO: dynamically get the latest version latest_api_version = "2.45" # Authenticate and get x-auth-token session = requests.Session() login_url = f'https://{target}/api/{latest_api_version}/login' session.headers.update({ "api-token": "<your_api_token_here>" }) response = session.post(login_url, verify=False) x_auth_token = response.headers.get("x-auth-token") if x_auth_token: session.headers.update({"x-auth-token": x_auth_token}) else: print("Error: x-auth-token not found in response headers.") print(x_auth_token) Query the fleet: # Get fleet info fleets_url = f'https://{target}/api/{latest_api_version}/fleets' fleets_response = session.get(fleets_url, verify=False) fleets_json = fleets_response.json() fleet_name = fleets_json['items'][0]['name'] print (f"Selected fleet: {fleet_name}") # Get fleet members members_url = f"https://{target}/api/{latest_api_version}/fleets/members?fleet_name={fleet_name}" fleets_response_members = session.get(members_url, verify=False) VAR1 = fleets_response_members.json() VAR_RESULTS = [item['member']['name'] for item in VAR1['items']] print(f"Fleet members: {VAR_RESULTS}") Enumerate volumes and hosts with pagination: # Enumerate all volumes in the fleet with pagination print("\nEnumerating volumes in the fleet:") limit = 10 # Adjust as needed continuation_token = None all_volumes = [] volumes_base_url = f"https://{target}/api/{latest_api_version}/volumes?context_names={','.join(VAR_RESULTS)}" while True: params = {'limit': limit} if continuation_token: params['continuation_token'] = continuation_token volumes_response = session.get(volumes_base_url, params=params, verify=False) volumes_json = volumes_response.json() all_volumes.extend(volumes_json.get('items', [])) continuation_token = volumes_response.headers.get('x-next-token') if not continuation_token: break print(f"Total volumes found: {len(all_volumes)}") print(json.dumps(all_volumes, indent=2)) # Enumerate hosts in the fleet with pagination print("\nEnumerating hosts in the fleet:") limit = 10 # Adjust as needed continuation_token = None all_hosts = [] hosts_base_url = f"https://{target}/api/{latest_api_version}/hosts?context_names={','.join(VAR_RESULTS)}" while True: params = {'limit': limit} if continuation_token: params['continuation_token'] = continuation_token hosts_response = session.get(hosts_base_url, params=params, verify=False) hosts_json = hosts_response.json() all_hosts.extend(hosts_json.get('items', [])) continuation_token = hosts_response.headers.get('x-next-token') if not continuation_token: break print(f"Total hosts found: {len(all_hosts)}") print(json.dumps(all_hosts, indent=2)) Enumerate Presets and Workloads in the fleet: # Enumerate all Presets in the fleet print("\nEnumerating presets in the fleet:") presets_url = f"https://{target}/api/{latest_api_version}/presets?context_names={','.join(VAR_RESULTS)}" presets_response = session.get(presets_url, verify=False) presets_json = presets_response.json() print(f"Total presets found: {len(presets_json.get('items', []))}") # Enumerate all Woorkloads in the fleet print("\nEnumerating workloads in the fleet:") workloads_url = f"https://{target}/api/{latest_api_version}/workloads?context_names={','.join(VAR_RESULTS)}" workloads_response = session.get(workloads_url, verify=False) workloads_json = workloads_response.json() print(f"Total workloads found: {len(workloads_json.get('items', []))}") Create a host on a member array, create a volume, and connect the volume to the host: # Select a member array (not the target) member_array = next((name for name in VAR_RESULTS if name != target), None) if not member_array: print("No other member array found in the fleet.") exit(1) print(f"Selected member array for operations: {member_array}") # Create a new host on the member array host_name = "demo-host-01" host_iqn = "iqn.2025-08.com.fleetdemo:host01" host_payload = { "names": host_name, "iqn": [host_iqn], "context": { "name": member_array } } hosts_url = f"https://{target}/api/{latest_api_version}/hosts" host_resp = session.post(hosts_url, json=host_payload, verify=False) print(f"Host creation response: {host_resp.json()}") # Create a new volume on the member array volume_name = "APIDemo-vol1" volume_payload = { "names": volume_name, "provisioned": 10737418240, # 10 GB in bytes "context": { "name": member_array } } volumes_url = f"https://{target}/api/{latest_api_version}/volumes" volume_resp = session.post(volumes_url, json=volume_payload, verify=False) print(f"Volume creation response: {volume_resp.json()}") # Connect the volume to the host connect_payload = { "volume_names": volume_name, "context_names":member_array, "host_names": host_name, } connections_url = f"https://{target}/api/{latest_api_version}/connections" connect_resp = session.post(connections_url, json=connect_payload, verify=False) print(f"Connection response: {connect_resp.json()}")17Views0likes0CommentsSome Fleet PowerShell code using Invoke-RestMethod
Hello fellow scripters! This script is a PowerShell script that uses native PowerShell cmdlets to do the tasks. It does not use the Pure Storage PowerShell SDK2. This is for folks who do raw API calls using automation packages, runbooks, and scripts. It is not intended to use in it's entirety, but rather to be used as code snippets and starters for your own scripts. The full script is available in this GitHub repository. This script will: Use native PowerShell (non-SDK) Invoke-RestMethod calls to the FlashArray API Authenticates an API Token user and gets the x-auth-token for requests Query a fleet and determine the fleet members Query fleet Presets & Workloads List fleet volumes and hosts (top X, configurable) Create a host, volume, and then connect the volume to the host on a member array. <# .SYNOPSIS Authenticates to Pure Storage FlashArray REST API and retrieves session token. .DESCRIPTION - Authenticates using API token. - Retrieves the x-auth-token from response headers for subsequent requests. - Dynamically queries the FlashArray for the latest available API version and uses it for requests. .PARAMETER Target Required. The FQDN or IP address of the FlashArray to target for REST API calls. .PARAMETER ApiToken Required. The API token used for authentication with the FlashArray REST API. .EXAMPLE .\Connect-FAApi.ps1 -Target "10.0.0.100" -ApiToken "<Your API Token here>" .NOTES Author: mnelson@purestorage.com Origin Date: 10/23/2023 Version: 1.1 #> param ( [Parameter(Mandatory = $true)] [string]$Target, [Parameter(Mandatory = $true)] [string]$ApiToken ) ################ SETUP ################ # Query the array for the latest available API version try { $apiVersions = Invoke-RestMethod -Uri "https://$Target/api/api_version" -Method Get -SkipCertificateCheck $numericApiVersions = $apiVersions.version | Where-Object { $_ -match '^\d+(\.\d+)*$' -and $_ -notmatch '^2\.x$' } $latestApiVersion = ($numericApiVersions | Sort-Object { [version]$_ } -Descending)[0] Write-Host "Latest API Version detected:" $latestApiVersion } catch { Write-Host "Could not retrieve API version, defaulting to 2.45" $latestApiVersion = "2.45" } # Set the Base Uri if ($latestApiVersion) { $baseUrl = "https://$Target/api/$latestApiVersion" } # Prepare headers for authentication $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers["api-token"] = $ApiToken # Authenticate and get session token $response = Invoke-RestMethod "https://$Target/api/$latestApiVersion/login" -Method 'POST' -Headers $headers -SkipCertificateCheck -ResponseHeadersVariable "respHeaders" # Display the value of "username" from the response, if present if ($response.items -and $response.items[0].username) { Write-Host "Username:" $response.items[0].username } else { Write-Host "Username field not found in response." } # TO-DO: Check if user is LDAP or local # Parse "x-auth-token" from response headers and store in $xAuthHeader $xAuthHeader = $respHeaders["x-auth-token"] Write-Host "x-auth-token:" $xAuthHeader # Add x-auth-token to headers for subsequent requests $headers.Add("x-auth-token", $xAuthHeader) # You can now use $headers for further authenticated requests to the FA API ########################################################################### Add pagination, query the fleet: # optional pagination & limit code $continuation_token = $null $limit = 10 # Adjust as needed ################ FLEETS ################ # Get Fleet name $fleetsResponse = Invoke-RestMethod -Uri "$baseUrl/fleets" -Method Get -Headers $headers -SkipCertificateCheck $fleetName = $fleetsResponse.items[0].name #Write-Host "Fleet Name: $fleetName" # Get fleet members $membersUrl = "$baseUrl/fleets/members?fleet_name=$fleetName" $membersResponse = Invoke-RestMethod -Uri $membersUrl -Method Get -Headers $headers -SkipCertificateCheck if (-not $membersResponse.items -or $membersResponse.items.Count -eq 0) { Write-Error "No fleet members found." exit 1 } # Extract Fleet member names $VAR_RESULTS = @() foreach ($item in $membersResponse.items) { if ($item.member -and $item.member.name) { $VAR_RESULTS += $item.member.name } elseif ($item.name) { $VAR_RESULTS += $item.name } } if ($VAR_RESULTS.Count -eq 0) { Write-Error "No member names found in fleet members response." exit 1 } # Write out the fleet members #Write-Host "Extracted Member Names: $($VAR_RESULTS -join ', ')" Query for volumes, hosts: ################ FLEET VOLUMES QUERY ################ # Query volumes for extracted member names $volumesUrl = "$baseUrl/volumes?context_names=$($VAR_RESULTS -join ',')" ## uncomment for full response - no limit, and comment out pagination code below #$volumesResponse = Invoke-RestMethod -Uri $volumesUrl -Method Get -Headers $headers -SkipCertificateCheck #$volumesResponse | ConvertTo-Json -Depth 5 ## with paginated reponse do { ## Build the query string for pagination $queryString = "?limit=$limit" if ($continuation_token) { $queryString += "&continuation_token=$continuation_token" } $volumesUrl = "$baseUrl/volumes$queryString" ## Invoke REST method and capture response headers $volumesResponse = Invoke-RestMethod -Uri $volumesUrl -Method Get -Headers $headers -SkipCertificateCheck -ResponseHeadersVariable respHeaders ## Output volumes data $volumesResponse | ConvertTo-Json -Depth 5 ## Extract x-next-token from response headers for next page $continuation_token = $respHeaders["x-next-token"] ## Continue if x-next-token is present } while ($continuation_token) ################ FLEET HOSTS QUERY ################ # Query hosts for extracted member names $hostsUrl = "$baseUrl/hosts?context_names=$($VAR_RESULTS -join ',')" ## full response - no limit, and comment out pagination code below #$hostsResponse = Invoke-RestMethod -Uri $hostsUrl -Method Get -Headers $headers -SkipCertificateCheck #$hostsResponse | ConvertTo-Json -Depth 5 ## with paginated reponse do { ## Build the query string for pagination $queryString = "?limit=$limit" if ($continuation_token) { $queryString += "&continuation_token=$continuation_token" } $hostsUrl = "$baseUrl/hosts$queryString" ## Invoke REST method and capture response headers $hostsResponse = Invoke-RestMethod -Uri $hostsUrl -Method Get -Headers $headers -SkipCertificateCheck -ResponseHeadersVariable respHeaders ## Output hosts data $hostsResponse | ConvertTo-Json -Depth 5 ## Extract x-next-token from response headers for next page $continuation_token = $respHeaders["x-next-token"] ## Continue if x-next-token is present } while ($continuation_token) Query for Presets & Workloads: ################ FLEET PRESETS QUERY ################ $presetsUrl = "$baseUrl/presets?context_names=$($VAR_RESULTS -join ',')" $presetsResponse = Invoke-RestMethod -Uri $presetsUrl -Method Get -Headers $headers -SkipCertificateCheck -ResponseHeadersVariable respHeaders $presetsResponse | ConvertTo-Json -Depth 5 ################ FLEET WORKLOADS QUERY ################ $workloadsUrl = "$baseUrl/workloads?context_names=$($VAR_RESULTS -join ',')" $workloadsResponse = Invoke-RestMethod -Uri $workloadsUrl -Method Get -Headers $headers -SkipCertificateCheck -ResponseHeadersVariable respHeaders $workloadsResponse | ConvertTo-Json -Depth 5 Create a Host on a fleet member array, create a volume, connect the volume to the host: ################ CREATE VOLUME, HOST, AND CONNECT THEM ON ANOTHER FLASHARRAY IN THE FLEET ################ # Select a secondary FlashArray in the fleet $otherArrayName = $VAR_RESULTS | Where-Object { $_ -ne $Target } | Select-Object -First 1 if (-not $otherArrayName) { Write-Error "No other FlashArray found in the fleet." exit 1 } Write-Host "Selected secondary FlashArray for operations: $otherArrayName" # Create a new volume on the secondary FlashArray $newVolumeName = "APIDemo-Vol01" $volumePayload = @{ name = $newVolumeName size = 10737418240 # 10 GiB in bytes context = @{ name = $otherArrayName } } $createVolumeUrl = "$baseUrl/volumes" $createVolumeResponse = Invoke-RestMethod -Uri $createVolumeUrl -Method Post -Headers $headers -Body ($volumePayload | ConvertTo-Json) -ContentType "application/json" -SkipCertificateCheck Write-Host "Created volume:" $newVolumeName "on" $otherArrayName # Create a new host on the secondary FlashArray $newHostName = "FleetDemoHost01" $IQN = "iqn.2023-07.com.fleetdemo:host01" $hostPayload = @{ name = $newHostName iqn = @($IQN) context = @{ name = $otherArrayName } } $createHostUrl = "$baseUrl/hosts" $createHostResponse = Invoke-RestMethod -Uri $createHostUrl -Method Post -Headers $headers -Body ($hostPayload | ConvertTo-Json) -ContentType "application/json" -SkipCertificateCheck Write-Host "Created host:" $newHostName "with IQN:" $IQN "on" $otherArrayName # Connect the newly created volume to the newly created host $connectPayload = @{ volume = @{ name = $newVolumeName context = @{ name = $otherArrayName } } host = @{ name = $newHostName context = @{ name = $otherArrayName } } } $connectUrl = "$baseUrl/host-volume-connections" $connectResponse = Invoke-RestMethod -Uri $connectUrl -Method Post -Headers $headers -Body ($connectPayload | ConvertTo-Json) -ContentType "application/json" -SkipCertificateCheck Write-Host "Connected volume" $newVolumeName "to host" $newHostName "on" $otherArrayName # Output results $createVolumeResponse | ConvertTo-Json -Depth 5 $createHostResponse | ConvertTo-Json -Depth 5 $connectResponse | ConvertTo-Json -Depth 525Views2likes0CommentsVirtualization Anonymous - Pittsburgh PUG
Welcome to Our 2nd Pure User Group (PUG) Discussion on Server Virtualization! We’re excited to bring our community together again for our second PUG session focused on server virtualization — a topic that's constantly evolving and critical to modern infrastructure. This is part of our ongoing effort to host these discussions every six months, continuing as long as there's interest from our user community. Whether you joined us for the first session or you're new to the group, we’re glad to have you here. Let’s learn, share, and grow together — and as always, your feedback helps shape future PUG topics! Event Details This will be a customer driven and customer focused discussion to hear from people like you related to the experiences and journey you have been on as we all seek the recovery we need to build a virtualization strategy for the future. Pure Storage and Expedient will provide experts and guidance to take that first step with you. After our presentation, we invite you to join us for happy hour and appetizers at the Federal Galley located here. Prizes will be provided to help encourage open collaboration. Space is extremely limited for this event. Sign up now to grab your spot to this exciting event. Registration https://info.purestorage.com/2025-Q3AMS-COMREDTFSPUGPittsburghLP_01---Registration-Page.html Parking Enter the Parking garage on level 2 off of S Commons, Take the east or west stairs to the Plaza Level, Exit the plaza level by the information desk to the outdoor plaza, walk towards the Federal Galley, The conference center entrance is located to the left of the Federal Galley. (follow Pure Storage Signage) Agenda 2:00PM Check In 2:30PM - 4:30PM Presentation 4:30PM - Giveaway Raffle (Pirate Tickets, Pure Swag, Autographed Pirate Baseballs) 5:00PM - 6:30PM Happy Hour with Pure69Views1like0CommentsPowerShell SDK v2.43.30 released!
The Pure PowerShell SDK version 2.43.30 has been released! There are a boatload of changes in this release, and all of those changes can be found in the release notes. New cmdlets for Fleets, tags, realms, and more. New parameters for context_names (fleets) and Allow_Errors. Install the SDK today! Install-Module PureStoragePowerShellSDK2 Update your current version: Update-Module PureStoragePowerShellSDK2 PowerShell Gallery Link20Views1like0CommentsBoston PUG - August 21, 2025
Hey there Connecticut PUG members. I wanted to let you all know there is a Boston PUG event taking place August 21, 2025 at Trillium - Fort Point in the Seaport. If you have time to spare to hang with Pure and other like-minded, beer-loving individuals then please drive up to hang out with us. You can find more about the event at the link below: Boston PUG information link I hope some of you are interested in driving up for the afternoon. We will host a PUG in Connecticut in the near future. Stay tuned...16Views0likes0CommentsBoston Pure User Group (PUG) at Trillium - Fort Point!
Simplify IT, Empower Data - Over a Pint at Trillium - Fort Point Join us August 21, 2025, and connect, learn, and engage with your fellow IT pros for an afternoon filled with exciting announcements from the recent Pure//Accelerate event and our vision for the Enterprise Data Cloud, as well as an engaging discussion on modern virtualization and a demo of Fusion. Fusion is a fully integrated platform that federates multiple arrays—such as FlashArray and FlashBlade—into a unified fleet, enabling centralized, cloud-like management, streamlined resource provisioning, and enhanced visibility across multi-array environments. Rob Quast, Principal Technologist from Pure Storage will be presenting on the above topics with additional input from other Pure technologists. The complete agenda is below. Please register if you plan on attending at the following link: Register Here Agenda 2:00 PM - Welcome & Cheers Light intro by host & Pure representatives. Local brew served!! 2:15 PM - Accelerate Highlights: What You Missed (or Want More Of) A high-level recap of key announcements: Fusion, Evergreen One, FlashBlade//SR2 2:45 PM - Enterprise Data Cloud: The Vision and The Why Why it matters: cutting complexity, controlling cost, and scaling for AI 3:15 PM - Fusion in Action: Simplifying Storage with Intelligence Live demo or use-case storytelling around automation, presets, and governance 3:45 PM - Break & Bites Grab a drink, mingle, enjoy local food 4:15 PM - Rethinking Virtualization in 2025 What’s next after VMware? Discuss Pure + Nutanix, KubeVirt, Azure/AWS paths 4:45 PM - Ask Me Anything (AMA) Panel Interactive Q&A with Pure team + customer guest if available 5:15 PM - Cheers & Networking Open networking, brewery tour optional We look forward to seeing you!18Views0likes0Comments