PureStorage.CBS.AVS.SPBM.ps1

function New-PfaVvolStoragePolicy {
  <#
  .SYNOPSIS
    Creates a new FlashArray vVol Storage Policy
  .DESCRIPTION
    Creates a new FlashArray vVol Storage Policy with specified capabilities
  .INPUTS
    Capabilities
  .OUTPUTS
    New storage policy
  .EXAMPLE
    New-PfaVvolStoragePolicy

    Creates the default SPBM policy that indicates a VM should be on a FlashArray using vVols. Default generated name and description.
  .EXAMPLE
    New-PfaVvolStoragePolicy -PolicyName myGreatPolicy

    Creates a SPBM policy with the specified name that indicates a VM should be on a FlashArray using vVols. Default generated description.
  .EXAMPLE
    New-PfaVvolStoragePolicy -PolicyName myGreatReplicationPolicy -ReplicationInterval (New-TimeSpan -Minutes 5) -ReplicationEnabled $true -ReplicationConcurrency 2

    Creates a replication-type SPBM policy with the specified name that indicates a VM should be on a FlashArray using vVols, replicated every 5 minutes to at least two other FlashArrays. Default generated description.
  .EXAMPLE
    $policy = Get-PfaVvolStoragePolicy -PolicyName myvVolreplicationpolicy
    $policyConfig = Build-PfavVolStoragePolicyConfig -Policy $policy
    $policyConfig.policyName = "MyEvenGreaterReplicationPolicy"
    $policyConfig.replicationInterval = New-TimeSpan -Minutes 10
    Edit-PfaVvolStoragePolicy -PolicyConfig $policyConfig

    Creates a new policy with the identical configuration of a previously created policy but with a different name and replication interval.
    #>


  Param(

        [String]$PolicyName,

        [String]$PolicyDescription,

        [String]$ReplicationEnabled,

        [int]$ReplicationIntervalSeconds = 0,

        [int]$ReplicationRetentionShortSeconds = 0,

        [int]$ReplicationConcurrency,

        [String]$ConsistencyGroupName,

        [String]$ReplicationRuleLocalSnapshotEnabled,

        [int]$ReplicationRuleLocalSnapshotIntervalSeconds = 0,

        [int]$ReplicationRuleLocalSnapshotRetentionShortSeconds = 0,

        [string]$TargetFlashArrays,

        [string]$SourceFlashArrays,

        [int]$PerVirtualDiskIOPSLimit,

        [String]$PerVirtualDiskIOPSLimitUnit,

        [int]$PerVirtualDiskBandwidthLimit,

        [String]$PerVirtualDiskBandwidthLimitUnit,

        [String]$VolumeTaggingKey,

        [String]$VolumeTaggingValue,

        [String]$VolumeTaggingCopyable,

        [int]$PlacementRuleLocalSnapshotIntervalSeconds = 0,

        [int]$PlacementRuleLocalSnapshotRetentionShortSeconds = 0,

        [int]$PlacementRuleLocalSnapshotForAdditionalSnapshots,

        [int]$PlacementRuleLocalSnapshotForAdditionalDays
  )

  if ($null -eq $policyConfig)
  {
    if ([string]::IsNullOrWhiteSpace($policyName))
    {
      $policyName = "FlashArray vVol Policy " + (Get-Random -Minimum 1000 -Maximum 9999).ToString()
    }

    $ReplicationInterval = If ($ReplicationIntervalSeconds -ne 0) { New-TimeSpan -Seconds $ReplicationIntervalSeconds } Else { 0 }
    $ReplicationIntervalShort = If ($ReplicationRetentionShortSeconds -ne 0) { New-TimeSpan -Seconds $ReplicationRetentionShortSeconds } Else { 0 }
    $ReplicationRetentionShort = If ($ReplicationRetentionShortSeconds -ne 0) { New-TimeSpan -Seconds $ReplicationRetentionShortSeconds } Else { 0 }
    $ReplicationRuleLocalSnapshotInterval = If ($ReplicationRuleLocalSnapshotIntervalSeconds -ne 0) { New-TimeSpan -Seconds $ReplicationRuleLocalSnapshotIntervalSeconds } Else { 0 }
    $ReplicationRuleLocalSnapshotRetentionShort = If ($ReplicationRuleLocalSnapshotRetentionShortSeconds -ne 0) { New-TimeSpan -Seconds $ReplicationRuleLocalSnapshotRetentionShortSeconds } Else { 0 }
    $PlacementRuleLocalSnapshotInterval = If ($PlacementRuleLocalSnapshotIntervalSeconds -ne 0) { New-TimeSpan -Seconds $PlacementRuleLocalSnapshotIntervalSeconds } Else { 0 }
    $PlacementRuleLocalSnapshotRetentionShort = If ($PlacementRuleLocalSnapshotRetentionShortSeconds -ne 0) { New-TimeSpan -Seconds $PlacementRuleLocalSnapshotRetentionShortSeconds } Else { 0 }

    # The user input would be string "yes", "no", or nothing.
    # We will translate it to nullable boolean
    [Nullable[bool]]$ReplicationEnabledBool = Convert-StringCapabilityToBoolean -StringCapabilityName "ReplicationEnabled" -StringCapabilityValue $ReplicationEnabled
    [Nullable[bool]]$ReplicationRuleLocalSnapshotEnabledBool = Convert-StringCapabilityToBoolean -StringCapabilityName "ReplicationRuleLocalSnapshotEnabled" -StringCapabilityValue $ReplicationRuleLocalSnapshotEnabled
    [Nullable[bool]]$VolumeTaggingCopyableBool = Convert-StringCapabilityToBoolean -StringCapabilityName "VolumeTaggingCopyable" -StringCapabilityValue $VolumeTaggingCopyable

    $SourceFlashArraysSeperated = If ($PSBoundParameters.ContainsKey('SourceFlashArrays')) { $SourceFlashArrays.Split(",") } else { $null }
    $TargetFlashArraysSeperated = If ($PSBoundParameters.ContainsKey('TargetFlashArrays')) { $TargetFlashArrays.Split(",") } else { $null }
    $policyConfig = ([FlashArrayvVolPolicyConfig]::new($policyName, $policyDescription, $SourceFlashArraysSeperated, $ReplicationEnabledBool, $replicationInterval, $replicationRetentionShort, $replicationConcurrency, $consistencyGroupName, $TargetFlashArraysSeperated, $ReplicationRuleLocalSnapshotEnabledBool , $ReplicationRuleLocalSnapshotInterval, $ReplicationRuleLocalSnapshotRetentionShort, $PerVirtualDiskIOPSLimit, $PerVirtualDiskIOPSLimitUnit, $PerVirtualDiskBandwidthLimit, $PerVirtualDiskBandwidthLimitUnit, $VolumeTaggingKey, $VolumeTaggingValue, $VolumeTaggingCopyableBool, $PlacementRuleLocalSnapshotInterval, $PlacementRuleLocalSnapshotRetentionShort, $PlacementRuleLocalSnapshotForAdditionalSnapshots, $PlacementRuleLocalSnapshotForAdditionalDays))
  }

  $checkExisting = $null
  $checkExisting = Get-SpbmStoragePolicy -Name $policyConfig.policyName -ErrorAction SilentlyContinue
  if ($null -ne $checkExisting)
  {
    throw "A storage policy with the name of $($policyConfig.policyName) already exists`n `n Please choose a unique name."
  }

  if ([string]::IsNullOrWhiteSpace($policyConfig.policyDescription))
  {
    $policyConfig.policyDescription = "Pure Storage Cloud Block Store vVol storage policy default description"
  }
  $checkforPure = $null
  $checkforPure = Get-SpbmCapability |where-object {$_.name -like "com.purestorage*"}
  if ($null -eq $checkforPure)
  {
    Write-Error "This vCenter does not have any Pure VASA providers registered and therefore no policy can be created. ..."
  }
  else {
    $ruleSet = New-pfaRuleSetfromConfig -policyConfig $policyConfig
    Write-Host "Creating policy $($policyConfig.policyName)..."
    New-SpbmStoragePolicy -Name $policyConfig.policyName -Description $policyConfig.policyDescription -AnyOfRuleSets $ruleSet
  }
}

function Convert-StringCapabilityToBoolean {
  param(
    [string]$StringCapabilityName,
    [string]$StringCapabilityValue
  )
  if ($StringCapabilityValue -eq "yes" -or $StringCapabilityValue -eq "true") {
    $true
  }
  ElseIf ( $StringCapabilityValue -eq "no" -or $StringCapabilityValue -eq "false") {
    $false
  }
  Elseif ([string]::IsNullOrEmpty($StringCapabilityValue)) {
    $null
  }
  Else {
    throw "$StringCapabilityName should either be 'yes', 'no', 'true', 'false' or no value"
  }
}

function Remove-PfaVvolStoragePolicy {
  <#
  .SYNOPSIS
    Remove a FlashArray vVol Storage Policy
  .DESCRIPTION
    Remove a FlashArray vVol Storage Policy using policy name. The policy must be unused
  .INPUTS
    SPBM policy name
  .OUTPUTS
    N.A.
  .NOTES
    Version: 1.0
  .EXAMPLE
    Remove-PfaVvolVmStoragePolicy -PolicyName myPolicyName
    #>


  Param(

        [Parameter(Position=0,mandatory=$true)]
        [string]$PolicyName
  )

  $policy = Get-SpbmStoragePolicy | Where-Object {$_.Name -eq $PolicyName}

  if ($null -eq $policy)
  {
    throw "No existing policy is associated with this policy configuration. Use the New-PfaVvolStoragePolicy instead to create a new policy."
  }

  $pureCapability = $policy.AnyOfRuleSets.AllOfRules.Capability | where {$_.Name -like "com.purestorage*"}
  if ($pureCapability.Count -eq 0) {
    throw "The policy is not managed by Pure Storage."
  }

  return (Remove-SpbmStoragePolicy -StoragePolicy $policy -confirm:$false)
}

#Custom Classes
Class FlashArrayvVolPolicyConfig{
  static [String] $version = "1.1.0"
  static [String] $vendor = "Pure Storage"
  static [String] $objectName = "vVol Storage Policy Configuration"
  static [String] $model = "FlashArray"
  static [System.Boolean]$flasharray = $true
  [String]$policyName = ""
  [String]$policyDescription = ""
  [String[]]$sourceFlashArrays = $null
  [Nullable[boolean]]$replicationEnabled = $null
  [System.TimeSpan]$replicationInterval = 0
  [System.TimeSpan]$replicationRetentionShort = 0
  [int]$replicationConcurrency = $null
  [ValidatePattern('(?# MUST BE 3+ digits, alphanumeric, also dashes or underscores can be in the middle)^[A-Za-z][a-zA-Z0-9\-_]+[a-zA-Z0-9]$|^$')]
  [String]$consistencyGroupName = ""
  [String[]]$targetFlashArrays = $null
  [Nullable[boolean]]$ReplicationRuleLocalSnapshotEnabled = $null
  [System.TimeSpan]$ReplicationRuleLocalSnapshotInterval = 0
  [System.TimeSpan]$ReplicationRuleLocalSnapshotRetentionShort = 0
  [int]$PerVirtualDiskIOPSLimit = $null
  [String]$PerVirtualDiskIOPSLimitUnit = ""
  [int]$PerVirtualDiskBandwidthLimit = $null
  [String]$PerVirtualDiskBandwidthLimitUnit = ""
  [String]$VolumeTaggingKey = ""
  [String]$VolumeTaggingValue = ""
  [Nullable[boolean]]$VolumeTaggingCopyable = $null
  [System.TimeSpan]$PlacementRuleLocalSnapshotInterval = 0
  [System.TimeSpan]$PlacementRuleLocalSnapshotRetentionShort = 0
  [int]$PlacementRuleLocalSnapshotForAdditionalSnapshots = $null
  [int]$PlacementRuleLocalSnapshotForAdditionalDays = $null
  FlashArrayvVolPolicyConfig ([String]$policyName, [String]$policyDescription, [String[]]$sourceFlashArrays, [Nullable[boolean]]$replicationEnabled, [System.TimeSpan]$replicationInterval, [System.TimeSpan]$replicationRetentionShort, [int]$replicationConcurrency, [String]$consistencyGroupName, [String[]]$targetFlashArrays, [Nullable[boolean]]$ReplicationRuleLocalSnapshotEnabled , [System.TimeSpan]$ReplicationRuleLocalSnapshotInterval, [System.TimeSpan]$ReplicationRuleLocalSnapshotRetentionShort, [int]$PerVirtualDiskIOPSLimit, [String]$PerVirtualDiskIOPSLimitUnit, [int]$PerVirtualDiskBandwidthLimit, [String]$PerVirtualDiskBandwidthLimitUnit, [String]$VolumeTaggingKey, [String]$VolumeTaggingValue, [Nullable[boolean]]$VolumeTaggingCopyable, [System.TimeSpan]$PlacementRuleLocalSnapshotInterval, [System.TimeSpan]$PlacementRuleLocalSnapshotRetentionShort, [int]$PlacementRuleLocalSnapshotForAdditionalSnapshots, [int]$PlacementRuleLocalSnapshotForAdditionalDays)
  {
    $this.sourceFlashArrays = $sourceFlashArrays
    $this.policyName = $policyName
    $this.policyDescription = $policyDescription
    $this.replicationEnabled = $replicationEnabled
    $this.replicationInterval = $replicationInterval
    $this.replicationRetentionShort = $replicationRetentionShort
    $this.replicationConcurrency = $replicationConcurrency
    $this.consistencyGroupName = $consistencyGroupName
    $this.targetFlashArrays = $targetFlashArrays
    $this.ReplicationRuleLocalSnapshotEnabled = $ReplicationRuleLocalSnapshotEnabled
    $this.ReplicationRuleLocalSnapshotInterval = $ReplicationRuleLocalSnapshotInterval
    $this.ReplicationRuleLocalSnapshotRetentionShort = $ReplicationRuleLocalSnapshotRetentionShort
    $this.PerVirtualDiskIOPSLimit = $PerVirtualDiskIOPSLimit
    $this.PerVirtualDiskIOPSLimitUnit = $PerVirtualDiskIOPSLimitUnit
    $this.PerVirtualDiskBandwidthLimit = $PerVirtualDiskBandwidthLimit
    $this.PerVirtualDiskBandwidthLimitUnit = $PerVirtualDiskBandwidthLimitUnit
    $this.VolumeTaggingKey = $VolumeTaggingKey
    $this.VolumeTaggingValue = $VolumeTaggingValue
    $this.VolumeTaggingCopyable = $VolumeTaggingCopyable
    $this.PlacementRuleLocalSnapshotInterval = $PlacementRuleLocalSnapshotInterval
    $this.PlacementRuleLocalSnapshotRetentionShort = $PlacementRuleLocalSnapshotRetentionShort
    $this.PlacementRuleLocalSnapshotForAdditionalSnapshots = $PlacementRuleLocalSnapshotForAdditionalSnapshots
    $this.PlacementRuleLocalSnapshotForAdditionalDays = $PlacementRuleLocalSnapshotForAdditionalDays
    if ($replicationEnabled -eq $false)
    {
      if ([System.TimeSpan]0 -ne $replicationInterval)
      {
        throw "Do not specify a replication interval if replicationEnabled is set to false."
      }
      if ([System.TimeSpan]0 -ne $replicationRetentionShort)
      {
        throw "Do not specify a replication retention if replicationEnabled is set to false."
      }
    }
    if ($ReplicationRuleLocalSnapshotEnabled -eq $false)
    {
      if ([System.TimeSpan]0 -ne $ReplicationRuleLocalSnapshotInterval)
      {
        throw "Do not specify a snapshot interval if ReplicationRuleLocalSnapshotEnabled is set to false."
      }
      if ([System.TimeSpan]0 -ne $ReplicationRuleLocalSnapshotRetentionShort)
      {
        throw "Do not specify a snapshot retention if ReplicationRuleLocalSnapshotEnabled is set to false."
      }
    }
  }
}

#internal functions
function New-pfaRuleSetfromConfig {

  Param(
        [FlashArrayvVolPolicyConfig]$policyConfig
  )

  $rules = @()
  if ($policyConfig.sourceFlashArrays.count -ne 0)
   {
    $rules += New-SpbmRule `
                -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.FlashArrayGroup) `
                -Value $policyConfig.sourceFlashArrays
   }
   $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.PureFlashArray) `
               -Value $true

   # Replication
   if ($null -ne $policyConfig.ReplicationRuleLocalSnapshotEnabled)
   {
     $rules += New-SpbmRule `
                 -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.LocalSnapshotPolicyCapable) `
                 -Value $policyConfig.ReplicationRuleLocalSnapshotEnabled
   }
   if ($policyConfig.ReplicationRuleLocalSnapshotInterval -ne 0)
   {
     $rules += New-SpbmRule `
                 -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.LocalSnapshotInterval) `
                 -Value $policyConfig.ReplicationRuleLocalSnapshotInterval
   }
   if ($policyConfig.ReplicationRuleLocalSnapshotRetentionShort -ne 0)
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.LocalSnapshotRetention) `
               -Value $policyConfig.ReplicationRuleLocalSnapshotRetentionShort
   }
   if ($policyConfig.targetFlashArrays.count -ne 0)
   {
    $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.ReplicationTarget) `
               -Value $policyConfig.targetFlashArrays
   }
   if ($null -ne $policyConfig.replicationEnabled)
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.RemoteReplicationCapable) `
               -Value $policyConfig.replicationEnabled
   }
   if ($policyConfig.replicationInterval -ne 0)
   {
   $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.RemoteReplicationInterval) `
             -Value $policyConfig.replicationInterval
   }
   if ($policyConfig.replicationRetentionShort -ne 0)
   {
             $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.RemoteReplicationRetention) `
             -Value $policyConfig.replicationRetentionShort
   }
   if (!([string]::IsNullOrWhiteSpace($policyConfig.consistencyGroupName)))
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.ReplicationConsistencyGroup) `
               -Value $policyConfig.consistencyGroupName
   }
   if (($null -ne $policyConfig.replicationConcurrency) -and ($policyConfig.replicationConcurrency -ne 0))
   {
     $rules += New-SpbmRule `
                 -Capability (Get-SpbmCapability -Name com.purestorage.storage.replication.replicationConcurrency) `
                 -Value $policyConfig.replicationConcurrency
   }

   # IOPS Limit
   if (($null -ne $policyConfig.PerVirtualDiskIOPSLimit) -and ($policyConfig.PerVirtualDiskIOPSLimit -ne 0))
   {
             $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.IopsLimit.IopsLimit) `
             -Value $policyConfig.PerVirtualDiskIOPSLimit
   }
   if (!([string]::IsNullOrWhiteSpace($policyConfig.PerVirtualDiskIOPSLimitUnit)))
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.IopsLimit.IopsLimitUnit) `
               -Value $policyConfig.PerVirtualDiskIOPSLimitUnit
   }

   # Bandwidth Limit
   if (($null -ne $policyConfig.PerVirtualDiskBandwidthLimit) -and ($policyConfig.PerVirtualDiskBandwidthLimit -ne 0))
   {
             $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.BandwidthLimit.BandwidthLimit) `
             -Value $policyConfig.PerVirtualDiskBandwidthLimit
   }
   if (!([string]::IsNullOrWhiteSpace($policyConfig.PerVirtualDiskBandwidthLimitUnit)))
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.BandwidthLimit.BandwidthLimitUnit) `
               -Value $policyConfig.PerVirtualDiskBandwidthLimitUnit
   }

   # Volume Tag
   if (!([string]::IsNullOrWhiteSpace($policyConfig.VolumeTaggingKey)))
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.VolumeTagging.TagKey) `
               -Value $policyConfig.VolumeTaggingKey
   }
   if (!([string]::IsNullOrWhiteSpace($policyConfig.VolumeTaggingValue)))
   {
     $rules += New-SpbmRule `
               -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.VolumeTagging.TagValue) `
               -Value $policyConfig.VolumeTaggingValue
   }
   if ($null -ne $policyConfig.VolumeTaggingCopyable)
   {
     $rules += New-SpbmRule `
                 -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.VolumeTagging.TagCopyable) `
                 -Value $policyConfig.VolumeTaggingCopyable
   }

   # Local snapshot
   if ($policyConfig.PlacementRuleLocalSnapshotInterval -ne 0)
   {
   $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.LocalSnapshotProtection.LocalSnapshotInterval) `
             -Value $policyConfig.PlacementRuleLocalSnapshotInterval
   }
   if ($policyConfig.PlacementRuleLocalSnapshotRetentionShort -ne 0)
   {
             $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.LocalSnapshotProtection.LocalSnapshotRetention) `
             -Value $policyConfig.PlacementRuleLocalSnapshotRetentionShort
   }
   if (($null -ne $policyConfig.PlacementRuleLocalSnapshotForAdditionalSnapshots) -and ($policyConfig.PlacementRuleLocalSnapshotForAdditionalSnapshots -ne 0))
   {
   $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.LocalSnapshotProtection.LocalSnapshotThenRetain) `
             -Value $policyConfig.PlacementRuleLocalSnapshotForAdditionalSnapshots
   }
   if (($null -ne $policyConfig.PlacementRuleLocalSnapshotForAdditionalDays) -and ($policyConfig.PlacementRuleLocalSnapshotForAdditionalDays -ne 0))
   {
             $rules += New-SpbmRule `
             -Capability (Get-SpbmCapability -Name com.purestorage.storage.policy.LocalSnapshotProtection.LocalSnapshotForAdditionalDays) `
             -Value $policyConfig.PlacementRuleLocalSnapshotForAdditionalDays
   }

   #create policy
   return New-SpbmRuleSet -AllOfRules $rules
}