Public/Add-DMLunToProtectionGroup.ps1
|
<#
.SYNOPSIS Adds one or more OceanStor LUNs to a protection group. .DESCRIPTION Associates a LUN with a protection group via the OceanStor protection group interface. The protection group can be identified by Name or by Id; the LUN(s) can be identified by Name (one LUN), Id (one or more, comma-separated), or a LUN object piped in from Get-DMLun. Name and Id are mutually exclusive for the same object, enforced by PowerShell parameter sets. Name parameters are validated at parameter-binding time with tab completion; Id parameters are validated too, but have no tab completion. Note: -LunName cannot itself be pipeline-bound by property, since the protection group's own -Name parameter would collide with a piped object's Name property (PowerShell rejects a parameter alias that matches another parameter's literal name). Piping a LUN in uses the whole-object pipeline instead (see -InputObject). When exactly one LUN Id resolves (LunName, a single LunId, or one LUN piped in), the single-LUN "add" interface is used. When -LunId resolves to more than one Id, the batch "add" interface is used instead, sending all of them in a single REST call. Accepts multiple LUN objects from the pipeline. Each LUN is added independently: a REST error is reported as a non-terminating error and does not stop the rest from being processed. .PARAMETER WebSession Optional session object returned by Connect-deviceManager. When omitted, the module's cached $script:CurrentOceanstorSession session is used. .PARAMETER Name Name of the protection group to add the LUN(s) to. Validated against existing protection groups and supports tab completion. Mutually exclusive with Id. .PARAMETER Id Id of the protection group to add the LUN(s) to. Validated against existing protection groups, no tab completion. Mutually exclusive with Name. .PARAMETER LunName Name of a single LUN to add. Validated against existing LUNs and supports tab completion. Mutually exclusive with LunId and InputObject. .PARAMETER LunId Id of one or more LUNs to add, either as native PowerShell array syntax (-LunId 1,2,3) or a single comma-separated string (-LunId "1,2,3"). Each Id is validated against existing LUNs, no tab completion. Mutually exclusive with LunName and InputObject. .PARAMETER InputObject A LUN object (from Get-DMLun) piped in to add. Mutually exclusive with LunName and LunId. .INPUTS System.Management.Automation.PSCustomObject OceanstorLunv3, OceanstorLunv6 .OUTPUTS System.Management.Automation.PSCustomObject Returns the OceanStor API error object (single LUN) or an array of per-LUN result objects (multiple LUN Ids). .EXAMPLE PS> Get-DMLun 'production-db' | Add-DMLunToProtectionGroup -Id 5 Adds production-db to protection group 5, using the single-LUN interface. .EXAMPLE PS> Add-DMLunToProtectionGroup -Name 'pg-production' -LunName 'production-db' .EXAMPLE PS> Add-DMLunToProtectionGroup -Name 'pg-production' -LunId 12,13,14 Adds three LUNs to pg-production in a single batch REST call. .NOTES Filename: Add-DMLunToProtectionGroup.ps1 #> function Add-DMLunToProtectionGroup { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ProtectionGroupByName_LunByName')] param( [Parameter(ValueFromPipelineByPropertyName = $true)] [pscustomobject]$WebSession, [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunByName')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunById')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunByObject')] [ValidateNotNullOrEmpty()] [ValidateScript({ $session = if ($WebSession) { $WebSession } else { $script:CurrentOceanstorSession } $matchingItems = @(Get-DMProtectionGroup -WebSession $session -Name $_ | Where-Object Name -EQ $_) if ($matchingItems.Count -eq 1) { return $true } if ($matchingItems.Count -gt 1) { throw "Name is ambiguous because more than one protection group is named '$_'." } throw 'Invalid Name.' })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $session = if ($fakeBoundParameters.ContainsKey('WebSession')) { $fakeBoundParameters.WebSession } else { $script:CurrentOceanstorSession } (Get-DMProtectionGroup -WebSession $session).Name | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } })] [string]$Name, [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunByName')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunById')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunByObject')] [ValidateScript({ $session = if ($WebSession) { $WebSession } else { $script:CurrentOceanstorSession } $matchingItems = @(Get-DMProtectionGroup -WebSession $session -Id $_) if ($matchingItems.Count -eq 1) { return $true } throw 'Invalid Id.' })] [string]$Id, [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunByName')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunByName')] [ValidateScript({ $session = if ($WebSession) { $WebSession } else { $script:CurrentOceanstorSession } $matchingItems = @(Get-DMlun -WebSession $session -Name $_ | Where-Object Name -EQ $_) if ($matchingItems.Count -eq 1) { return $true } if ($matchingItems.Count -gt 1) { throw "LunName is ambiguous because more than one LUN is named '$_'." } throw 'Invalid LunName.' })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $session = if ($fakeBoundParameters.ContainsKey('WebSession')) { $fakeBoundParameters.WebSession } else { $script:CurrentOceanstorSession } (Get-DMlun -WebSession $session).Name | Sort-Object -Unique | Where-Object { $_ -like "$wordToComplete*" } })] [string]$LunName, [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunById')] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunById')] [ValidateScript({ $session = if ($WebSession) { $WebSession } else { $script:CurrentOceanstorSession } $ids = ($_ -join ',') -split ',' | Where-Object { $_ } foreach ($lunId in $ids) { $matchingItems = @(Get-DMlun -WebSession $session -Id $lunId) if ($matchingItems.Count -ne 1) { throw "Invalid LunId '$lunId'." } } return $true })] [string[]]$LunId, [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupByName_LunByObject', ValueFromPipeline = $true)] [Parameter(Mandatory = $true, ParameterSetName = 'ProtectionGroupById_LunByObject', ValueFromPipeline = $true)] [psobject]$InputObject ) process { try { $session = if ($WebSession) { $WebSession } else { $script:CurrentOceanstorSession } switch -Wildcard ($PSCmdlet.ParameterSetName) { 'ProtectionGroupByName_*' { $protectionGroup = @(Get-DMProtectionGroup -WebSession $session -Name $Name | Where-Object Name -EQ $Name)[0] if ($null -eq $protectionGroup) { throw "Could not resolve 'Name' - the object may have been removed since parameter validation." } } 'ProtectionGroupById_*' { $protectionGroup = @(Get-DMProtectionGroup -WebSession $session -Id $Id)[0] if ($null -eq $protectionGroup) { throw "Could not resolve 'Id' - the object may have been removed since parameter validation." } } } $lunIds = @(switch -Wildcard ($PSCmdlet.ParameterSetName) { '*_LunByName' { $lun = @(Get-DMlun -WebSession $session -Name $LunName | Where-Object Name -EQ $LunName)[0] if ($null -eq $lun) { throw "Could not resolve 'LunName' - the object may have been removed since parameter validation." } @($lun.Id) } '*_LunById' { @(($LunId -join ',') -split ',' | Where-Object { $_ }) } '*_LunByObject' { if ($null -eq $InputObject.Id) { throw "InputObject does not have an 'Id' property; pipe a LUN object from Get-DMLun." } @($InputObject.Id) } }) if ($lunIds.Count -le 1) { $body = @{ protectGroupId = $protectionGroup.Id ASSOCIATEOBJTYPE = 11 ASSOCIATEOBJID = $lunIds[0] } if ($PSCmdlet.ShouldProcess("$($lunIds[0]) -> $($protectionGroup.Name)", 'Add LUN to protection group')) { $response = Invoke-DeviceManager -WebSession $session -Method 'POST' -Resource 'protectgroup/associate' -BodyData $body -ApiV2 $response = $response | Assert-DMApiSuccess return $response.error } } else { $body = @($lunIds | ForEach-Object { @{ ID = $protectionGroup.Id; ASSOCIATEOBJTYPE = 11; ASSOCIATEOBJID = $_ } }) if ($PSCmdlet.ShouldProcess("$($lunIds -join ', ') -> $($protectionGroup.Name)", 'Add LUNs to protection group')) { $response = Invoke-DeviceManager -WebSession $session -Method 'POST' -Resource 'protectgroup/associate/batch' -BodyData $body $response = $response | Assert-DMApiSuccess return $response.data } } } catch { $PSCmdlet.WriteError($_) } } } |