CLI/CPGManagement.psm1
#################################################################################### ## © 2020,2021 Hewlett Packard Enterprise Development LP ## ## Permission is hereby granted, free of charge, to any person obtaining a ## copy of this software and associated documentation files (the "Software"), ## to deal in the Software without restriction, including without limitation ## the rights to use, copy, modify, merge, publish, distribute, sublicense, ## and/or sell copies of the Software, and to permit persons to whom the ## Software is furnished to do so, subject to the following conditions: ## ## The above copyright notice and this permission notice shall be included ## in all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ## OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ## ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ## OTHER DEALINGS IN THE SOFTWARE. ## ## File Name: CPGManagement.psm1 ## Description: CPG Management cmdlets ## ## Created: October 2019 ## Last Modified: May 2021 ## History: v3.0 - Created ##################################################################################### $Info = "INFO:" $Debug = "DEBUG:" $global:VSLibraries = Split-Path $MyInvocation.MyCommand.Path [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ############################################################################################################################################ ## FUNCTION Test-CLIObject ############################################################################################################################################ Function Test-CLIObject { Param( [string]$ObjectType, [string]$ObjectName , [string]$ObjectMsg = $ObjectType, $SANConnection = $global:SANConnection ) $IsObjectExisted = $True $ObjCmd = $ObjectType -replace ' ', '' $Cmds = "show$ObjCmd $ObjectName" $Result = Invoke-CLICommand -Connection $SANConnection -cmds $Cmds if ($Result -like "no $ObjectMsg listed") { $IsObjectExisted = $false } return $IsObjectExisted } # End FUNCTION Test-CLIObject ##################################################################################################################### ## FUNCTION Get-CPG ##################################################################################################################### Function Get-CPG { <# .SYNOPSIS Get list of common provisioning groups (CPGs) in the system. .DESCRIPTION Get list of common provisioning groups (CPGs) in the system. .EXAMPLE Get-CPG List all/specified common provisioning groups (CPGs) in the system. .EXAMPLE Get-CPG -cpgName "MyCPG" List Specified CPG name "MyCPG" .EXAMPLE Get-CPG -Detailed -cpgName "MyCPG" Displays detailed information about the CPGs. .EXAMPLE Get-CPG -RawSpace -cpgName "MyCPG" Specifies that raw space used by the CPGs is displayed. .EXAMPLE Get-CPG -AlertTime -cpgName "MyCPG" Show times when alerts were posted (when applicable). .EXAMPLE Get-CPG -Domain_Name XYZ -cpgName "MyCPG" Show times with domain name depict. .PARAMETER cpgName Specify name of the cpg to be listed. .PARAMETER ListCols List the columns available to be shown in the -showcols option described below (see "clihelp -col showcpg" for help on each column). .PARAMETER Detailed Displays detailed information about the CPGs. The following columns are shown: Id Name Warn% VVs TPVVs TDVVs UsageUsr UsageSnp Base SnpUsed Free Total LDUsr LDSnp RC_UsageUsr RC_UsageSnp DDSType DDSSize .PARAMETER RawSpace Specifies that raw space used by the CPGs is displayed. The following columns are shown: Id Name Warn% VVs TPVVs TDVVs UsageUsr UsageSnp Base RBase SnpUsed SnpRUsed Free RFree Total RTotal .PARAMETER Alert Indicates whether alerts are posted. The following columns are shown: Id Name Warn% UsrTotal DataWarn DataLimit DataAlertW% DataAlertW DataAlertL DataAlertF .PARAMETER Alerttime Show times when alerts were posted (when applicable). The following columns are shown: Id Name DataAlertW% DataAlertW DataAlertL DataAlertF .PARAMETER SAG Specifies that the snapshot admin space auto-growth parameters are displayed. The following columns are displayed: Id Name AdmWarn AdmLimit AdmGrow AdmArgs .PARAMETER SDG Specifies that the snapshot data space auto-growth parameters are displayed. The following columns are displayed: Id Name DataWarn DataLimit DataGrow DataArgs .PARAMETER Space Show the space saving of CPGs. The following columns are displayed: Id Name Warn% Shared Private Free Total Compaction Dedup DataReduce Overprov .PARAMETER Hist Specifies that current data from the CPG, as well as the CPG's history data is displayed. .PARAMETER Domain_Name Shows only CPGs that are in domains with names matching one or more of the <domain_name_or_pattern> argument. This option does not allow listing objects within a domain of which the user is not a member. Patterns are glob-style (shell-style) patterns (see help on sub,globpat). .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: Get-CPG LASTEDIT: 17-10-2019 KEYWORDS: Get-CPG .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param ( [Parameter(Position=0, Mandatory=$false)] [switch] $ListCols, [Parameter(Position=1, Mandatory=$false)] [switch] $Detailed, [Parameter(Position=2, Mandatory=$false)] [switch] $RawSpace, [Parameter(Position=3, Mandatory=$false)] [switch] $Alert, [Parameter(Position=4, Mandatory=$false)] [switch] $AlertTime, [Parameter(Position=5, Mandatory=$false)] [switch] $SAG, [Parameter(Position=6, Mandatory=$false)] [switch] $SDG, [Parameter(Position=7, Mandatory=$false)] [switch] $Space, [Parameter(Position=8, Mandatory=$false)] [switch] $History, [Parameter(Position=9, Mandatory=$false)] [System.String] $Domain_Name, [Parameter(Position=10, Mandatory=$false)] [System.String] $cpgName, [Parameter(Position=11, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Get-CPG - validating input values" $Debug #check if connection object contents are null/empty if(!$SANConnection) { #check if connection object contents are null/empty $Validate1 = Test-CLIConnection $SANConnection if($Validate1 -eq "Failed") { #check if global connection object contents are null/empty $Validate2 = Test-CLIConnection $global:SANConnection if($Validate2 -eq "Failed") { Write-DebugLog "Connection object is null/empty or the array address (FQDN/IP Address) or user credentials in the connection object are either null or incorrect. Create a valid connection object using New-CLIConnection or New-PoshSshConnection" "ERR:" Write-DebugLog "Stop: Exiting Get-CPG since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet Get-CPG since no active storage connection session exists. `nUse New-PoshSSHConnection or New-CLIConnection to start a new storage connection session." } } } $plinkresult = Test-PARCli -SANConnection $SANConnection if($plinkresult -match "FAILURE :") { write-debuglog "$plinkresult" "ERR:" return $plinkresult } $GetCPGCmd = "showcpg " if($ListCols) { $GetCPGCmd += "-listcols " } if($Detailed) { $GetCPGCmd += "-d " } if($RawSpace) { $GetCPGCmd += "-r " } if($Alert) { $GetCPGCmd += "-alert " } if($AlertTime) { $GetCPGCmd += "-alerttime " } if($SAG) { $GetCPGCmd += "-sag " } if($SDG) { $GetCPGCmd += "-sdg " } if($Space) { $GetCPGCmd += "-space " } if($History) { $GetCPGCmd += "-hist " } if($Domain_Name) { $GetCPGCmd += "-domain $Domain_Name " } if ($cpgName) { $objType = "cpg" $objMsg = "cpg" ## Check cpg Name ## if ( -not ( Test-CLIObject -objectType $objType -objectName $cpgName -objectMsg $objMsg -SANConnection $SANConnection)) { write-debuglog " CPG name $cpgName does not exist. Nothing to display" "INFO:" return "FAILURE : No cpg $cpgName found" } $GetCPGCmd += " $cpgName" } $Result = Invoke-CLICommand -Connection $SANConnection -cmds $GetCPGCmd if($ListCols -or $History) { write-debuglog "$Result" "ERR:" return $Result } if ( $Result.Count -gt 1) { $3parosver = Get-Version -S -SANConnection $SANConnection if($3parosver -eq "3.2.2") { if($Alert -Or $AlertTime -Or $SAG -Or $SDG) { $Cnt if($Alert) { $Cnt=2 } if($AlertTime -Or $SAG -Or $SDG ) { $Cnt=1 } $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count $incre = "true" foreach ($s in $Result[$Cnt..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() if($AlertTime) { $TempRep = $s -replace 'L','L_Date,L_Time,L_Zone' $s = $TempRep } if($incre -eq "true") { $sTemp1=$s $sTemp = $sTemp1.Split(',') if($Alert) { $sTemp[3]="Total_MB_Data" $sTemp[10]="Total_MB_Adm" $sTemp[11]="W%_Alerts_Adm" $sTemp[12]="F_Alerts_Adm" } if($AlertTime) { $sTemp[2]="W%_DataAlerts" $sTemp[3]="W_DataAlerts" $sTemp[7]="F_DataAlerts" $sTemp[8]="W%_AdmAlerts" $sTemp[9]="F_AdmAlerts" } $newTemp= [regex]::Replace($sTemp,"^ ","") $newTemp= [regex]::Replace($sTemp," ",",") $newTemp= $newTemp.Trim() $s=$newTemp } Add-Content -Path $tempFile -Value $s $incre="false" } if ($CPGName) { Import-Csv $tempFile | where {$_.Name -like $CPGName} } else { Import-Csv $tempFile } del $tempFile } elseif($Space -or $Domain_Name) { $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count-2 $incre = "true" foreach ($s in $Result[2..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() if($incre -eq "true") { $sTemp1=$s $sTemp = $sTemp1.Split(',') if($Space) { $sTemp[2]="Warn%_User_MB" $sTemp[3]="Total_User_MB" $sTemp[4]="Used_User_MB" $sTemp[5]="Total_Snp_MB" $sTemp[6]="Used_Snp_MB" $sTemp[7]="Total_Adm_MB" $sTemp[8]="Used_Adm_MB" } if($Domain_Name) { $sTemp[8]="Total_User_MB" $sTemp[9]="Used_User_MB" $sTemp[10]="Total_Snp_MB" $sTemp[11]="Used_Snp_MB" $sTemp[12]="Total_Adm_MB" $sTemp[13]="Used_Adm_MB" } $newTemp= [regex]::Replace($sTemp,"^ ","") $newTemp= [regex]::Replace($sTemp," ",",") $newTemp= $newTemp.Trim() $s=$newTemp } Add-Content -Path $tempFile -Value $s $incre="false" } if ($CPGName) { Import-Csv $tempFile | where {$_.Name -like $CPGName} } else { Import-Csv $tempFile } del $tempFile } else { $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count - 2 $incre = "true" foreach ($s in $Result[2..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() if($incre -eq "true") { $sTemp1=$s $sTemp = $sTemp1.Split(',') if($Detailed) { $sTemp[6]="Usr_Usage" $sTemp[7]="Snp_Usage" $sTemp[8]="Total_User_MB" $sTemp[9]="Used_User_MB" $sTemp[10]="Total_Snp_MB" $sTemp[11]="Used_Snp_MB" $sTemp[12]="Total_Adm_MB" $sTemp[13]="Used_Adm_MB" $sTemp[14]="Usr_LD" $sTemp[15]="Snp_LD" $sTemp[16]="Adm_LD" $sTemp[17]="Usr_RC_Usage" $sTemp[18]="Snp_RC_Usage" } elseif($RawSpace) { $sTemp[6]="Usr_Usage" $sTemp[7]="Snp_Usage" $sTemp[8]="Total_User_MB" $sTemp[9]="RTotal_User_MB" $sTemp[10]="Used_User_MB" $sTemp[11]="RUsed_User_MB" $sTemp[12]="Total_Snp_MB" $sTemp[13]="RTotal_Snp_MB" $sTemp[14]="Used_Snp_MB" $sTemp[15]="RUsed_Snp_MB" $sTemp[16]="Total_Adm_MB" $sTemp[17]="RTotal_Adm_MB" $sTemp[18]="Used_Adm_MB" $sTemp[19]="RUsed_Adm_MB" } else { $sTemp[6]="Usr_Usage" $sTemp[7]="Snp_Usage" $sTemp[8]="Total_User_MB" $sTemp[9]="Used_User_MB" $sTemp[10]="Total_Snp_MB" $sTemp[11]="Used_Snp_MB" $sTemp[12]="Total_Adm_MB" $sTemp[13]="Used_Adm_MB" } $newTemp= [regex]::Replace($sTemp,"^ ","") $newTemp= [regex]::Replace($sTemp," ",",") $newTemp= $newTemp.Trim() $s=$newTemp } Add-Content -Path $tempFile -Value $s $incre="false" } if ($CPGName) { Import-Csv $tempFile | where {$_.Name -like $CPGName} } else { Import-Csv $tempFile } del $tempFile } } else { if($Alert -Or $AlertTime -Or $SAG -Or $SDG) { $Cnt if($Alert) { $Cnt=2 } if($AlertTime -Or $SAG -Or $SDG ) { $Cnt=1 } $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count foreach ($s in $Result[$Cnt..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() Add-Content -Path $tempFile -Value $s } if ($CPGName) { Import-Csv $tempFile | where {$_.Name -like $CPGName} } else { Import-Csv $tempFile } del $tempFile } elseif($Space -or $Domain_Name) { $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count-2 $incre = "true" foreach ($s in $Result[1..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() if($incre -eq "true") { $sTemp1=$s $sTemp = $sTemp1.Split(',') if($Space) { $sTemp[3]="Base(Private(MiB))" $sTemp[4]="Snp(Private(MiB))" $sTemp[5]="Shared(MiB)" $sTemp[6]="Free(MiB)" $sTemp[7]="Total(MiB)" $sTemp[8]="Compact(Efficiency)" $sTemp[9]="Dedup(Efficiency)" $sTemp[10]="Compress(Efficiency)" $sTemp[11]="DataReduce(Efficiency)" $sTemp[12]="Overprov(Efficiency)" } if($Domain_Name) { $sTemp[3]="VVs(Volumes)" $sTemp[4]="TPVVs(Volumes)" $sTemp[5]="TDVVs(Volumes)" $sTemp[6]="Usr(Usage)" $sTemp[7]="Snp(Usage)" $sTemp[8]="Base(MiB)" $sTemp[9]="Snp(MiB)" $sTemp[10]="Free(MiB)" $sTemp[11]="Total(MiB)" } $newTemp= [regex]::Replace($sTemp,"^ ","") $newTemp= [regex]::Replace($sTemp," ",",") $newTemp= $newTemp.Trim() $s=$newTemp } Add-Content -Path $tempFile -Value $s $incre="false" } if ($CPGName) { Import-Csv $tempFile | where {$_.Name -like $CPGName} } else { Import-Csv $tempFile } del $tempFile } else { $tempFile = [IO.Path]::GetTempFileName() $LastItem = $Result.Count - 2 $incre = "true" foreach ($s in $Result[1..$LastItem] ) { $s= [regex]::Replace($s,"^ ","") $s= [regex]::Replace($s," +",",") $s= [regex]::Replace($s,"-","") $s= $s.Trim() if($incre -eq "true") { $sTemp1=$s $sTemp = $sTemp1.Split(',') if($Detailed) { $sTemp[3]="VVs(Volumes)" $sTemp[4]="TPVVs(Volumes)" $sTemp[5]="TDVVs(Volumes)" $sTemp[6]="Usr(Usage)" $sTemp[7]="Snp(Usage)" $sTemp[8]="Base(MiB)" $sTemp[9]="Snp(MiB)" $sTemp[10]="Free(MiB)" $sTemp[11]="Total(MiB)" $sTemp[12]="Usr(LD)" $sTemp[13]="Snp(LD)" $sTemp[14]="Usr(RC_Usage)" $sTemp[15]="Snp(RC_Usage)" } elseif($RawSpace) { $sTemp[3]="VVs(Volumes)" $sTemp[4]="TPVVs(Volumes)" $sTemp[5]="TDVVs(Volumes)" $sTemp[6]="Usr(Usage)" $sTemp[7]="Snp(Usage)" $sTemp[8]="Base(MiB)" $sTemp[9]="RBase(MiB)" $sTemp[10]="Snp(MiB)" $sTemp[11]="RSnp(MiB)" $sTemp[12]="Free(MiB)" $sTemp[13]="RFree(MiB)" $sTemp[14]="Total(MiB)" $sTemp[15]="RTotal(MiB)" } else { $sTemp[3]="VVs(Volumes)" $sTemp[4]="TPVVs(Volumes)" $sTemp[5]="TDVVs(Volumes)" $sTemp[6]="Usr(Usage)" $sTemp[7]="Snp(Usage)" $sTemp[8]="Base(MiB)" $sTemp[9]="Snp(MiB)" $sTemp[10]="Free(MiB)" $sTemp[11]="Total(MiB)" } $newTemp= [regex]::Replace($sTemp,"^ ","") $newTemp= [regex]::Replace($sTemp," ",",") $newTemp= $newTemp.Trim() $s=$newTemp } Add-Content -Path $tempFile -Value $s $incre="false" } if ($CPGName) { Import-Csv $tempFile } else { Import-Csv $tempFile } del $tempFile } } } elseif($Result -match "FAILURE") { write-debuglog "$Result" "ERR:" return $Result } else { #write-host "FINALY RETURN.." return $Result } } # End Get-CPG ############################################################################################################################################ ## FUNCTION New-CPG ############################################################################################################################################ Function New-CPG { <# .SYNOPSIS The New-CPG command creates a Common Provisioning Group (CPG). .DESCRIPTION The New-CPG command creates a Common Provisioning Group (CPG). .EXAMPLE New-CPG -cpgName "MyCPG" -Size 32G -RAIDType r1 Creates a CPG named MyCPG with initial size of 32GB and Raid configuration is r1 (RAID 1) .EXAMPLE New-CPG -cpgName asCpg .EXAMPLE New-CPG -cpgName asCpg1 -TemplateName temp .EXAMPLE New-CPG -cpgName asCpg1 -AW 1 .EXAMPLE New-CPG -cpgName asCpg1 -SDGS 1 .EXAMPLE New-CPG -cpgName asCpg1 -SDGL 12241 .EXAMPLE New-CPG -cpgName asCpg1 -saLD_name XYZ .EXAMPLE New-CPG -cpgName asCpg1 -sdLD_name XYZ .EXAMPLE New-CPG -cpgName asCpg1 -RAIDType r1 .PARAMETER TemplateName Use the options defined in template <template_name>. The template is created using the createtemplate command. Options specified in the template are read-only or read-write. The read-write options may be overridden with new options at the time of their creation, but read-only options may not be overridden at the time of creation. Options not explicitly specified in the template take their default values, and all of these options are either read-only or read-write (using the -nro or -nrw options of the createtemplate command). .PARAMETER AW Specifies the percentage of used snapshot administration or snapshot data space that results in a warning alert. A percent value of 0 disables the warning alert generation. The default is 0. This option is deprecated and will be removed in a subsequent release. .PARAMETER SDGS Specifies the growth increment, the amount of logical disk storage created on each auto-grow operation. The default growth increment may vary according to the number of controller nodes in the system. If <size> is non-zero it must be 8G or bigger. The size can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 disables the auto-grow feature. The following table displays the default and minimum growth increments per number of nodes: Number of Nodes Default Minimum 1-2 32G 8G 3-4 64G 16G 5-6 96G 24G 7-8 128G 32G .PARAMETER SDGL Specifies that the auto-grow operation is limited to the specified storage amount. The storage amount can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 (default) means no limit is enforced. To disable auto-grow, set the limit to 1. .PARAMETER SDGW Specifies that the threshold of used logical disk space, when exceeded, results in a warning alert. The size can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 (default) means no warning limit is enforced. To set the warning for any used space, set the limit to 1. .PARAMETER saLD_name Specifies that existing logical disks are added to the CPG and are used for snapshot admin (SA) space allocation. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER sdLD_name Specifies that existing logical disks are added to the CPG and are used for snapshot data (SD) space allocation. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER Domain Specifies the name of the domain with which the object will reside. The object must be created by a member of a particular domain with Edit or Super role. The default is to create it in the current domain, or no domain if the current domain is not set. .PARAMETER RAID_type Specifies the RAID type of the logical disk: r0 for RAID-0, r1 for RAID-1, r5 for RAID-5, or r6 for RAID-6. If no RAID type is specified, then the default is r6. .PARAMETER SSZ Specifies the set size in terms of chunklets. The default depends on the RAID type specified: 2 for RAID-1, 4 for RAID-5, and 8 for RAID-6. .PARAMETER RS Specifies the number of sets in a row. The <size> is a positive integer. If not specified, no row limit is imposed. .PARAMETER SS Specifies the step size from 32 KB to 512 KB. The step size should be a power of 2 and a multiple of 32. The default value depends on raid type and device type used. If no value is entered and FC or NL drives are used, the step size defaults to 256 KB for RAID-0 and RAID-1, and 128 KB for RAID-5. If SSD drives are used, the step size defaults to 32 KB for RAID-0 and RAID-1, and 64 KB for RAID-5. For RAID-6, the default is a function of the set size. .PARAMETER HA Specifies that the layout must support the failure of one port pair, one cage, or one drive magazine (mag). This option has no meaning for RAID-0. The default is cage availability. .PARAMETER CH Specifies the chunklet location characteristics: either first (attempt to use the lowest numbered available chunklets) or last(attempt to use the highest numbered available chunklets). If no argument is specified, the default characteristic is first. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: New-CPG LASTEDIT: 17-10-2019 KEYWORDS: New-CPG .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [System.String] $cpgName, [Parameter(Position=1, Mandatory=$false)] [System.String] $TemplateName, [Parameter(Position=2, Mandatory=$false)] [System.String] $AW, [Parameter(Position=3, Mandatory=$false)] [System.String] $SDGS, [Parameter(Position=4, Mandatory=$false)] [System.String] $SDGL, [Parameter(Position=5, Mandatory=$false)] [System.String] $SDGW, [Parameter(Position=6, Mandatory=$false)] [System.String] $saLD_name, [Parameter(Position=7, Mandatory=$false)] [System.String] $sdLD_name, [Parameter(Position=8, Mandatory=$false)] [System.String] $Domain, [Parameter(Position=9, Mandatory=$false)] [System.String] $RAIDType, [Parameter(Position=10, Mandatory=$false)] [System.String] $SSZ, [Parameter(Position=11, Mandatory=$false)] [System.String] $RS, [Parameter(Position=12, Mandatory=$false)] [System.String] $SS, [Parameter(Position=13, Mandatory=$false)] [System.String] $HA, [Parameter(Position=14, Mandatory=$false)] [System.String] $CH, [Parameter(Position=15, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In new-CPG - validating input values" $Debug ##### #check if connection object contents are null/empty if(!$SANConnection) { #check if connection object contents are null/empty $Validate1 = Test-CLIConnection $SANConnection if($Validate1 -eq "Failed") { #check if global connection object contents are null/empty $Validate2 = Test-CLIConnection $global:SANConnection if($Validate2 -eq "Failed") { Write-DebugLog "Connection object is null/empty or the array address (FQDN/IP Address) or user credentials in the connection object are either null or incorrect. Create a valid connection object using New-CLIConnection or New-PoshSshConnection" "ERR:" Write-DebugLog "Stop: Exiting New-CPG since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet New-CPG since no active storage connection session exists. `nUse New-PoshSSHConnection or New-CLIConnection to start a new storage connection session." } } } $plinkresult = Test-PARCli -SANConnection $SANConnection if($plinkresult -match "FAILURE :") { write-debuglog "$plinkresult" "ERR:" return $plinkresult } if(!($cpgName)) { write-debuglog " No CPG name specified - No action required" "INFO:" Get-Help New-CPG return } $CreateCPGCmd =" createcpg -f" if($TemplateName) { $CreateCPGCmd += " -templ $TemplateName " } if($AW) { $CreateCPGCmd += " -aw $AW " } if($SDGS) { $CreateCPGCmd += " -sdgs $SDGS " } if($SDGL) { $CreateCPGCmd += " -sdgl $SDGL " } if($SDGW) { $CreateCPGCmd += " -sdgw $SDGW " } if($saLD_name) { $CreateCPGCmd += " -sa $saLD_name " } if($sdLD_name) { $CreateCPGCmd += " -sd $sdLD_name " } if($Domain) { $CreateCPGCmd += " -domain $Domain " } if($RAIDType) { $CreateCPGCmd += " -t $RAIDType " } if($SSZ) { $CreateCPGCmd += " -ssz $SSZ " } if($RS) { $CreateCPGCmd += " -rs $RS " } if($SS) { $CreateCPGCmd += " -ss $SS " } if($HA) { $a = "port","cage","mag" $l=$HA if($a -eq $l) { $CreateCPGCmd += " -ha $HA " } else { Write-DebugLog "Stop: Exiting New-CPG since -HA $HA in incorrect " Return "FAILURE : -HA :- $HA is an Incorrect HA [ port | cage | mag ] can be used only . " } $CreateCPGCmd += " -ha $HA " } if($CH) { $a = "first","last" $l=$CH if($a -eq $l) { $CreateCPGCmd += " -ch $CH " } else { Write-DebugLog "Stop: Exiting New-CPG since -CH $CH in incorrect " Return "FAILURE : -CH :- $CH is an Incorrect CH [ first | last ] can be used only . " } } $CreateCPGCmd += " $cpgName" $Result1 = Invoke-CLICommand -Connection $SANConnection -cmds $CreateCPGCmd return $Result1 } # End of New-CPG ##################################################################################################################### ## FUNCTION Remove-CPG ##################################################################################################################### Function Remove-CPG { <# .SYNOPSIS Removes a Common Provisioning Group(CPG) .DESCRIPTION Removes a Common Provisioning Group(CPG) .EXAMPLE Remove-CPG -cpgName "MyCPG" -force Removes a Common Provisioning Group(CPG) "MyCPG" .PARAMETER force forcefully execute the command. .PARAMETER saLDname Specifies that the logical disk, as identified with the <LD_name> argument, used for snapshot administration space allocation is removed. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER sdLDname Specifies that the logical disk, as identified with the <LD_name> argument, used for snapshot data space allocation is removed. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER cpgName Specify name of the CPG .PARAMETER Pat The specified patterns are treated as glob-style patterns and that all common provisioning groups matching the specified pattern are removed. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: Remove-CPG LASTEDIT: 17-10-2019 KEYWORDS: Remove-CPG .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [switch] $force, [Parameter(Position=1, Mandatory=$false)] [System.String] $cpgName, [Parameter(Position=2, Mandatory=$false)] [System.String] $sdLDname, [Parameter(Position=3, Mandatory=$false)] [System.String] $saLDname, [Parameter(Position=4, Mandatory=$false)] [switch] $Pat, [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Remove-CPG - validating input values" $Debug #check if connection object contents are null/empty if(!$SANConnection) { #check if connection object contents are null/empty $Validate1 = Test-CLIConnection $SANConnection if($Validate1 -eq "Failed") { #check if global connection object contents are null/empty $Validate2 = Test-CLIConnection $global:SANConnection if($Validate2 -eq "Failed") { Write-DebugLog "Connection object is null/empty or the array address (FQDN/IP Address) or user credentials in the connection object are either null or incorrect. Create a valid connection object using New-CLIConnection or New-PoshSshConnection" "ERR:" Write-DebugLog "Stop: Exiting Remove-CPG since SAN connection object values are null/empty" $Debug return "FAILURE: Exiting Remove-CPG since no active storage connection session exists. `nUse New-PoshSSHConnection or New-CLIConnection to start a new storage connection session." } } } $plinkresult = Test-PARCli -SANConnection $SANConnection if($plinkresult -match "FAILURE :") { write-debuglog "$plinkresult" "ERR:" return $plinkresult } if ($cpgName) { if(!($force)) { write-debuglog "no force option selected to remove CPG, Exiting...." "INFO:" return "FAILURE: No -force option selected to remove cpg $cpgName" } $objType = "cpg" $objMsg = "cpg" $RemoveCPGCmd = "removecpg " ## Check CPG Name ## if ( -not ( Test-CLIObject -objectType $objType -objectName $cpgName -objectMsg $objMsg -SANConnection $SANConnection)) { write-debuglog " CPG $cpgName does not exist. Nothing to remove" "INFO:" return "FAILURE: No cpg $cpgName found" } else { if($force) { $RemoveCPGCmd +=" -f " } if($Pat) { $RemoveCPGCmd +=" -pat " } if ($saLDname) { $RemoveCPGCmd +=" -sa $saLDname " } if ($sdLDname) { $RemoveCPGCmd +=" -sd $sdLDname " } $RemoveCPGCmd += " $cpgName " $Result3 = Invoke-CLICommand -Connection $SANConnection -cmds $RemoveCPGCmd write-debuglog "Removing CPG with the command --> $RemoveCPGCmd" "INFO:" if (Test-CLIObject -objectType $objType -objectName $cpgName -objectMsg $objMsg -SANConnection $SANConnection) { write-debuglog " CPG $cpgName exists. Nothing to remove" "INFO:" return "FAILURE: While removing cpg $cpgName `n $Result3" } else { if ($Result3 -match "Removing CPG") { return "Success : Removed cpg $cpgName" } else { return "FAILURE: While removing cpg $cpgName $Result3" } } } } else { write-debuglog "No CPG name mentioned to remove " "INFO:" Get-help Remove-CPG } } # End of Remove-CPG ########################################################################## ######################### FUNCTION Set-CPG ######################### ########################################################################## Function Set-CPG() { <# .SYNOPSIS Set-CPG - Update a Common Provisioning Group (CPG) .DESCRIPTION The Set-CPG command modifies existing Common Provisioning Groups (CPG). .EXAMPLE .PARAMETER Sa Specifies that existing logical disks are added to the CPG and are used for snapshot admin (SA) space allocation. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER Sd Specifies that existing logical disks are added to the CPG and are used for snapshot data (SD) space allocation. The <LD_name> argument can be repeated to specify multiple logical disks. This option is deprecated and will be removed in a subsequent release. .PARAMETER Aw Specifies the percentage of used snapshot administration or snapshot data space that results in a warning alert. A percent value of 0 disables the warning alert generation. The default is 0. This option is deprecated and will be removed in a subsequent release. .PARAMETER Sdgs Specifies the growth increment, the amount of logical disk storage created on each auto-grow operation. The default growth increment may vary according to the number of controller nodes in the system. If <size> is non-zero it must be 8G or bigger. The size can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 disables the auto-grow feature. The following table displays the default and minimum growth increments per number of nodes: Number of Nodes Default Minimum 1-2 32G 8G 3-4 64G 16G 5-6 96G 24G 7-8 128G 32G .PARAMETER Sdgl Specifies that the auto-grow operation is limited to the specified storage amount. The storage amount can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 (default) means no limit is enforced. To disable auto-grow, set the limit to 1. .PARAMETER Sdgw Specifies that the threshold of used logical disk space, when exceeded, results in a warning alert. The size can be specified in MB (default) or GB (using g or G) or TB (using t or T). A size of 0 (default) means no warning limit is enforced. To set the warning for any used space, set the limit to 1. .PARAMETER T Specifies the RAID type of the logical disk: r1 for RAID-1, or r6 for RAID-6. If no RAID type is specified, then the default is r6. .PARAMETER Ssz Specifies the set size in terms of chunklets. The default depends on the RAID type specified: 3 for RAID-1, and 8 for RAID-6. .PARAMETER Rs Specifies the number of sets in a row. The <size> is a positive integer. If not specified, no row limit is imposed. .PARAMETER Ss Specifies the step size from 32 KiB to 512 KiB. The step size should be a power of 2 and a multiple of 32. The default value depends on raid type and device type used. If no value is entered and FC or NL drives are used, the step size defaults to 256 KiB for RAID-1. If SSD drives are used, the step size defaults to 32 KiB for RAID-1. For RAID-6, the default is a function of the set size. .PARAMETER Ha Specifies that the layout must support the failure of one port pair, one cage, or one drive magazine (mag). The default is cage availability. .PARAMETER Ch Specifies the chunklet location characteristics: either first (attempt to use the lowest numbered available chunklets) or last(attempt to use the highest numbered available chunklets). If no argument is specified, the default characteristic is first. .PARAMETER P Specifies a pattern for candidate disks. Patterns are used to select disks that are used for creating logical disks. If no pattern is specified, the option defaults to Fast Class (FC) disks. If specified multiple times, each instance of the specified pattern adds additional candidate disks that match the pattern. The -devtype pattern cannot be used to mix Nearline (NL), FC, and Solid State Drive (SSD) drives. An item is specified as an integer, a comma-separated list of integers, or a range of integers specified from low to high. The following arguments can be specified as patterns for this option: An item is specified as an integer, a comma-separated list of integers, or a range of integers specified from low to high. .PARAMETER Nd Specifies one or more nodes. Nodes are identified by one or more integers (item). Multiple nodes are separated with a single comma (e.g. 1,2,3). A range of nodes is separated with a hyphen (e.g. 0- 7). The primary path of the disks must be on the specified node(s). .PARAMETER St Specifies one or more PCI slots. Slots are identified by one or more integers (item). Multiple slots are separated with a single comma (e.g. 1,2,3). A range of slots is separated with a hyphen (e.g. 0- 7). The primary path of the disks must be on the specified PCI slot(s). .PARAMETER Pt Specifies one or more ports. Ports are identified by one or more integers (item). Multiple ports are separated with a single comma (e.g. 1,2,3). A range of ports is separated with a hyphen (e.g. 0- 4). The primary path of the disks must be on the specified port(s). .PARAMETER Cg Specifies one or more drive cages. Drive cages are identified by one or more integers (item). Multiple drive cages are separated with a single comma (e.g. 1,2,3). A range of drive cages is separated with a hyphen (e.g. 0-3). The specified drive cage(s) must contain disks. .PARAMETER Mg Specifies one or more drive magazines. The "1." or "0." displayed in the CagePos column of showpd output indicating the side of the cage is omitted when using the -mg option. Drive magazines are identified by one or more integers (item). Multiple drive magazines are separated with a single comma (e.g. 1,2,3). A range of drive magazines is separated with a hyphen(e.g. 0-7). The specified drive magazine(s) must contain disks. .PARAMETER Pn Specifies one or more disk positions within a drive magazine. Disk positions are identified by one or more integers (item). Multiple disk positions are separated with a single comma(e.g. 1,2,3). A range of disk positions is separated with a hyphen(e.g. 0-3). The specified position(s) must contain disks. .PARAMETER Dk Specifies one or more physical disks. Disks are identified by one or more integers(item). Multiple disks are separated with a single comma (e.g. 1,2,3). A range of disks is separated with a hyphen(e.g. 0-3). Disks must match the specified ID(s). .PARAMETER Tc_gt Specifies that physical disks with total chunklets greater than the number specified be selected. .PARAMETER Tc_lt Specifies that physical disks with total chunklets less than the number specified be selected. .PARAMETER Fc_gt Specifies that physical disks with free chunklets greater than the number specified be selected. .PARAMETER Fc_lt Specifies that physical disks with free chunklets less than the number specified be selected. .PARAMETER Devid Specifies that physical disks identified by their models be selected. Models can be specified in a comma-separated list. Models can be displayed by issuing the "showpd -i" command. .PARAMETER Devtype Specifies that physical disks must have the specified device type (FC for Fast Class, NL for Nearline, SSD for Solid State Drive) to be used. Device types can be displayed by issuing the "showpd" command. If it is not specified, the default device type is FC. .PARAMETER Rpm Disks must be of the specified speed. Device speeds are shown in the RPM column of the showpd command. The number does not represent a rotational speed for the drives without spinning media (SSD). It is meant as a rough estimation of the performance difference between the drive and the other drives in the system. For FC and NL drives, the number corresponds to both a performance measure and actual rotational speed. For SSD drive, the number is to be treated as relative performance benchmark that takes into account in I/O per second, bandwidth and the access time. Disks that satisfy all of the specified characteristics are used. For example -p -fc_gt 60 -fc_lt 230 -nd 2 specifies all the disks that have greater than 60 and less than 230 free chunklets and that are connected to node 2 through their primary path. .PARAMETER Sax Specifies that the logical disk, as identified with the <LD_name> argument, used for snapshot administration space allocation be removed. The <LD_name> argument can be repeated to specify multiple logical disks .PARAMETER Sdx Specifies that the logical disk, as identified with the <LD_name> argument, used for snapshot data space allocation be removed. The <LD_name> argument can be repeated to specify multiple logical disks. .PARAMETER NewName Specifies the name of the Common Provisioning Group (CPG) to be modified to. <newname> can be up to 31 characters in length. .Notes NAME: Set-CPG LASTEDIT 17-10-2019 KEYWORDS: Set-CPG .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sa, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sd, [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Aw, [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sdgs, [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sdgl, [Parameter(Position=6, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sdgw, [Parameter(Position=7, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $T, [Parameter(Position=8, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Ssz, [Parameter(Position=9, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Rs, [Parameter(Position=10, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Ss, [Parameter(Position=11, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Ha, [Parameter(Position=12, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Ch, [Parameter(Position=13, Mandatory=$false, ValueFromPipeline=$true)] [switch] $P, [Parameter(Position=14, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Nd, [Parameter(Position=15, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $St, [Parameter(Position=16, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Pt, [Parameter(Position=17, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Cg, [Parameter(Position=18, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Mg, [Parameter(Position=19, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Pn, [Parameter(Position=20, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Dk, [Parameter(Position=21, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Tc_gt, [Parameter(Position=22, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Tc_lt, [Parameter(Position=23, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Fc_gt, [Parameter(Position=24, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Fc_lt, [Parameter(Position=25, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Devid, [Parameter(Position=26, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Devtype, [Parameter(Position=27, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Rpm, [Parameter(Position=28, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sax, [Parameter(Position=29, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Sdx, [Parameter(Position=30, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $NewName, [Parameter(Position=31, Mandatory=$true, ValueFromPipeline=$true)] [System.String] $CPG_name, [Parameter(Position=32, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Set-CPG - validating input values" $Debug #check if connection object contents are null/empty if(!$SANConnection) { #check if connection object contents are null/empty $Validate1 = Test-CLIConnection $SANConnection if($Validate1 -eq "Failed") { #check if global connection object contents are null/empty $Validate2 = Test-CLIConnection $global:SANConnection if($Validate2 -eq "Failed") { Write-DebugLog "Connection object is null/empty or the array address (FQDN/IP Address) or user credentials in the connection object are either null or incorrect. Create a valid connection object using New-CLIConnection or New-PoshSshConnection" " ERR: " Write-DebugLog "Stop: Exiting Set-CPG since SAN connection object values are null/empty" $Debug Return "Unable to execute the cmdlet Set-CPG since no active storage connection session exists. `nUse New-PoshSSHConnection or New-CLIConnection to start a new storage connection session." } } } $plinkresult = Test-PARCli -SANConnection $SANConnection if($plinkresult -match "FAILURE :") { write-debuglog "$plinkresult" Return $plinkresult } $Cmd = " setcpg -f" if($Sa) { $Cmd += " -sa $Sa " } if($Sd) { $Cmd += " -sd $Sd " } if($Aw) { $Cmd += " -aw $Aw " } if($Sdgs) { $Cmd += " -sdgs $Sdgs " } if($Sdgl) { $Cmd += " -sdgl $Sdgl " } if($Sdgw) { $Cmd += " -sdgw $Sdgw " } if($T) { $Cmd += " -t $T " } if($Ssz) { $Cmd += " -ssz $Ssz " } if($Rs) { $Cmd += " -rs $Rs " } if($Ss) { $Cmd += " -ss $Ss " } if($Ha) { $Cmd += " -ha $Ha " } if($Ch) { $Cmd += " -ch $Ch " } if($P) { $Cmd += " -p " } if($Nd) { $Cmd += " -nd $Nd " } if($St) { $Cmd += " -st $St " } if($Pt) { $Cmd += " -pt $Pt " } if($Cg) { $Cmd += " -cg $Cg " } if($Mg) { $Cmd += " -mg $Mg " } if($Pn) { $Cmd += " -pn $Pn " } if($Dk) { $Cmd += " -dk $Dk " } if($Tc_gt) { $Cmd += " -tc_gt $Tc_gt " } if($Tc_lt) { $Cmd += " -tc_lt $Tc_lt " } if($Fc_gt) { $Cmd += " -fc_gt $Fc_gt " } if($Fc_lt) { $Cmd += " -fc_lt $Fc_lt " } if($Devid) { $Cmd += " -devid $Devid " } if($Devtype) { $Cmd += " -devtype $Devtype " } if($Rpm) { $Cmd += " -rpm $Rpm " } if($Sax) { $Cmd += " -sax $Sax " } if($Sdx) { $Cmd += " -sdx $Sdx " } if($NewName) { $Cmd += " -name $NewName " } if($CPG_name) { $Cmd += " $CPG_name " } else { Return "CPG Name is mandatory please enter..." } $Result = Invoke-CLICommand -Connection $SANConnection -cmds $Cmd Write-DebugLog "Executing Function : Set-CPG Command -->" INFO: if ([string]::IsNullOrEmpty($Result)) { Get-CPG -Detailed -cpgName $CPG_name } else { Return $Result } } ## End-of Set-CPG ########################################################################## ######################### FUNCTION Compress-CPG ################# ########################################################################## Function Compress-CPG() { <# .SYNOPSIS Compress-CPG - Consolidate space in common provisioning groups. .DESCRIPTION The Compress-CPG command consolidates logical disk space in Common Provisioning Groups (CPGs) into as few logical disks as possible, allowing unused logical disks to be removed and their space reclaimed. .EXAMPLE Compress-CPG -CPG_name xxx .EXAMPLE Compress-CPG -CPG_name tstCPG .PARAMETER Pat Compacts CPGs that match any of the specified patterns. This option must be used if the pattern specifier is used. .PARAMETER Waittask Waits for any created tasks to complete. .PARAMETER Trimonly Removes unused logical disks after consolidating the space. This option will not perform any region moves. .PARAMETER Nomatch Removes only unused logical disks whose characteristics do not match the growth characteristics of the CPG. Must be used with the -trimonly option. If all logical disks match the CPG growth characteristics, this option has no effect. .PARAMETER Dr Specifies that the operation is a dry run, and the tasks are not actually performed. .Notes NAME: Compress-CPG LASTEDIT 17-10-2019 KEYWORDS: Compress-CPG .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)] [switch] $Pat, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [switch] $Waittask, [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$true)] [switch] $Trimonly, [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)] [switch] $Nomatch, [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)] [switch] $Dr, [Parameter(Position=5, Mandatory=$true, ValueFromPipeline=$true)] [System.String] $CPG_name, [Parameter(Position=6, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Compress-CPG - validating input values" $Debug #check if connection object contents are null/empty if(!$SANConnection) { #check if connection object contents are null/empty $Validate1 = Test-CLIConnection $SANConnection if($Validate1 -eq "Failed") { #check if global connection object contents are null/empty $Validate2 = Test-CLIConnection $global:SANConnection if($Validate2 -eq "Failed") { Write-DebugLog "Connection object is null/empty or the array address (FQDN/IP Address) or user credentials in the connection object are either null or incorrect. Create a valid connection object using New-CLIConnection or New-PoshSshConnection" " ERR: " Write-DebugLog "Stop: Exiting Compress-CPG since SAN connection object values are null/empty" $Debug Return "Unable to execute the cmdlet Compress-CPG since no active storage connection session exists. `nUse New-PoshSSHConnection or New-CLIConnection to start a new storage connection session." } } } $plinkresult = Test-PARCli -SANConnection $SANConnection if($plinkresult -match "FAILURE :") { write-debuglog "$plinkresult" Return $plinkresult } $Cmd = " compactcpg -f " if($Pat) { $Cmd += " -pat " } if($Waittask) { $Cmd += " -waittask " } if($Trimonly) { $Cmd += " -trimonly " } if($Nomatch) { $Cmd += " -nomatch " } if($Dr) { $Cmd += " -dr " } if($CPG_name) { $Cmd += " $CPG_name " } else { Return "CPG Name is mandatory please enter...." } $Result = Invoke-CLICommand -Connection $SANConnection -cmds $Cmd Write-DebugLog "Executing Function : Compress-CPG Command -->" INFO: Return $Result } ## End-of Compress-CPG Export-ModuleMember Get-CPG , New-CPG , Remove-CPG , Set-CPG , Compress-CPG # SIG # Begin signature block # MIIhEQYJKoZIhvcNAQcCoIIhAjCCIP4CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDFGK9q0J2jc6Ko # Z/wJbbmpZNkicqLpkDO1T1S09m18JaCCEKswggUpMIIEEaADAgECAhB4Lu4fcD9z # xUgD+jf1OoqlMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQI # ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT # D1NlY3RpZ28gTGltaXRlZDEkMCIGA1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWdu # aW5nIENBMB4XDTIxMDUyODAwMDAwMFoXDTIyMDUyODIzNTk1OVowgZAxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlQYWxvIEFsdG8x # KzApBgNVBAoMIkhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIENvbXBhbnkxKzAp # BgNVBAMMIkhld2xldHQgUGFja2FyZCBFbnRlcnByaXNlIENvbXBhbnkwggEiMA0G # CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmclZSXJBXA55ijwwFymuq+Y4F/quF # mm2vRdEmjFhzRvTpnGjIYtVcG11ka4JGCROmNVDZGAelnqcXn5DKO710j5SICTBC # 5gXOLwga7usifs21W+lVT0BsZTiUnFu4hEhuFTlahJIEvPGVgO1GBcuItD2QqB4q # 9j15GDI5nGBSzIyJKMctcIalxsTSPG1kiDbLkdfsIivhe9u9m8q6NRqDUaYYQTN+ # /qGCqVNannMapH8tNHqFb6VdzUFI04t7kFtSk00AkdD6qUvA4u8mL2bUXAYz8K5m # nrFs+ckx5Yqdxfx68EO26Bt2qbz/oTHxE6FiVzsDl90bcUAah2l976ebAgMBAAGj # ggGQMIIBjDAfBgNVHSMEGDAWgBQO4TqoUzox1Yq+wbutZxoDha00DjAdBgNVHQ4E # FgQUlC56g+JaYFsl5QWK2WDVOsG+pCEwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB # /wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJYIZIAYb4QgEBBAQDAgQQMEoG # A1UdIARDMEEwNQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8v # c2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEATBDBgNVHR8EPDA6MDigNqA0hjJodHRw # Oi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNybDBz # BggrBgEFBQcBAQRnMGUwPgYIKwYBBQUHMAKGMmh0dHA6Ly9jcnQuc2VjdGlnby5j # b20vU2VjdGlnb1JTQUNvZGVTaWduaW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRw # Oi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAY+1n2UUlQU6Z # VoEVaZKqZf/zrM/d7Kbx+S/t8mR2E+uNXStAnwztElqrm3fSr+5LMRzBhrYiSmea # w9c/0c7qFO9mt8RR2q2uj0Huf+oAMh7TMuMKZU/XbT6tS1e15B8ZhtqOAhmCug6s # DuNvoxbMpokYevpa24pYn18ELGXOUKlqNUY2qOs61GVvhG2+V8Hl/pajE7yQ4diz # iP7QjMySms6BtZV5qmjIFEWKY+UTktUcvN4NVA2J0TV9uunDbHRt4xdY8TF/Clgz # Z/MQHJ/X5yX6kupgDeN2t3o+TrColetBnwk/SkJEsUit0JapAiFUx44j4w61Qanb # Zmi0tr8YGDCCBYEwggRpoAMCAQICEDlyRDr5IrdR19NsEN0xNZUwDQYJKoZIhvcN # AQEMBQAwezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3Rl # cjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQx # ITAfBgNVBAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0xOTAzMTIwMDAw # MDBaFw0yODEyMzEyMzU5NTlaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3 # IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VS # VFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0 # aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIAS # ZRc2DsPbCLPQrFcNdu3NJ9NMrVCDYeKqIE0JLWQJ3M6Jn8w9qez2z8Hc8dOx1ns3 # KBErR9o5xrw6GbRfpr19naNjQrZ28qk7K5H44m/Q7BYgkAk+4uh0yRi0kdRiZNt/ # owbxiBhqkCI8vP4T8IcUe/bkH47U5FHGEWdGCFHLhhRUP7wz/n5snP8WnRi9UY41 # pqdmyHJn2yFmsdSbeAPAUDrozPDcvJ5M/q8FljUfV1q3/875PbcstvZU3cjnEjpN # rkyKt1yatLcgPcp/IjSufjtoZgFE5wFORlObM2D3lL5TN5BzQ/Myw1Pv26r+dE5p # x2uMYJPexMcM3+EyrsyTO1F4lWeL7j1W/gzQaQ8bD/MlJmszbfduR/pzQ+V+DqVm # sSl8MoRjVYnEDcGTVDAZE6zTfTen6106bDVc20HXEtqpSQvf2ICKCZNijrVmzyWI # zYS4sT+kOQ/ZAp7rEkyVfPNrBaleFoPMuGfi6BOdzFuC00yz7Vv/3uVzrCM7LQC/ # NVV0CUnYSVgaf5I25lGSDvMmfRxNF7zJ7EMm0L9BX0CpRET0medXh55QH1dUqD79 # dGMvsVBlCeZYQi5DGky08CVHWfoEHpPUJkZKUIGy3r54t/xnFeHJV4QeD2PW6WK6 # 1l9VLupcxigIBCU5uA4rqfJMlxwHPw1S9e3vL4IPAgMBAAGjgfIwge8wHwYDVR0j # BBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYEFFN5v1qqK0rPVIDh # 2JvAnfKyA2bLMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MBEGA1Ud # IAQKMAgwBgYEVR0gADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLmNvbW9k # b2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDA0BggrBgEFBQcBAQQo # MCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG # 9w0BAQwFAAOCAQEAGIdR3HQhPZyK4Ce3M9AuzOzw5steEd4ib5t1jp5y/uTW/qof # nJYt7wNKfq70jW9yPEM7wD/ruN9cqqnGrvL82O6je0P2hjZ8FODN9Pc//t64tIrw # kZb+/UNkfv3M0gGhfX34GRnJQisTv1iLuqSiZgR2iJFODIkUzqJNyTKzuugUGrxx # 8VvwQQuYAAoiAxDlDLH5zZI3Ge078eQ6tvlFEyZ1r7uq7z97dzvSxAKRPRkA0xdc # Ods/exgNRc2ThZYvXd9ZFk8/Ub3VRRg/7UqO6AZhdCMWtQ1QcydER38QXYkqa4Ux # FMToqWpMgLxqeM+4f452cpkMnf7XkQgWoaNflTCCBfUwggPdoAMCAQICEB2iSDBv # myYY0ILgln0z02owDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMV # VGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENl # cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIzMTIz # NTk1OVowfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3Rl # cjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQw # IgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQCGIo0yhXoYn0nwli9jCB4t3HyfFM/jJrYlZilA # hlRGdDFixRDtsocnppnLlTDAVvWkdcapDlBipVGREGrgS2Ku/fD4GKyn/+4uMyD6 # DBmJqGx7rQDDYaHcaWVtH24nlteXUYam9CflfGqLlR5bYNV+1xaSnAAvaPeX7Wpy # vjg7Y96Pv25MQV0SIAhZ6DnNj9LWzwa0VwW2TqE+V2sfmLzEYtYbC43HZhtKn52B # xHJAteJf7wtF/6POF6YtVbC3sLxUap28jVZTxvC6eVBJLPcDuf4vZTXyIuosB69G # 2flGHNyMfHEo8/6nxhTdVZFuihEN3wYklX0Pp6F8OtqGNWHTAgMBAAGjggFkMIIB # YDAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUDuE6 # qFM6MdWKvsG7rWcaA4WtNA4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYB # Af8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMIMBEGA1UdIAQKMAgw # BgYEVR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5j # b20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYB # BQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20v # VVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9v # Y3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAE1jUO1HNEphpNve # aiqMm/EAAB4dYns61zLC9rPgY7P7YQCImhttEAcET7646ol4IusPRuzzRl5ARokS # 9At3WpwqQTr81vTr5/cVlTPDoYMot94v5JT3hTODLUpASL+awk9KsY8k9LOBN9O3 # ZLCmI2pZaFJCX/8E6+F0ZXkI9amT3mtxQJmWunjxucjiwwgWsatjWsgVgG10Xkp1 # fqW4w2y1z99KeYdcx0BNYzX2MNPPtQoOCwR/oEuuu6Ol0IQAkz5TXTSlADVpbL6f # ICUQDRn7UJBhvjmPeo5N9p8OHv4HURJmgyYZSJXOSsnBf/M6BZv5b9+If8AjntIe # Q3pFMcGcTanwWbJZGehqjSkEAnd8S0vNcL46slVaeD68u28DECV3FTSK+TbMQ5Lk # uk/xYpMoJVcp+1EZx6ElQGqEV8aynbG8HArafGd+fS7pKEwYfsR7MUFxmksp7As9 # V1DSyt39ngVR5UR43QHesXWYDVQk/fBO4+L4g71yuss9Ou7wXheSaG3IYfmm8SoK # C6W59J7umDIFhZ7r+YMp08Ysfb06dy6LN0KgaoLtO0qqlBCk4Q34F8W2WnkzGJLj # tXX4oemOCiUe5B7xn1qHI/+fpFGe+zmAEc3btcSnqIBv5VPU4OOiwtJbGvoyJi1q # V3AcPKRYLqPzW0sH3DJZ84enGm1YMYIPvDCCD7gCAQEwgZAwfDELMAkGA1UEBhMC # R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9y # ZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJT # QSBDb2RlIFNpZ25pbmcgQ0ECEHgu7h9wP3PFSAP6N/U6iqUwDQYJYIZIAWUDBAIB # BQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg # SuH/5vIs5Fxx8VZfD+S8JDnnOvIWxToviq79shednuMwDQYJKoZIhvcNAQEBBQAE # ggEAlRrg9HkZA4UVPDqAVEYxkU77dQOGDrhOmw9JR8RZl+iJbQqzjYxUbSXUNAqJ # F3hm07pNHA+u12+ftlB0i2kO9faoIw3S10sIIXOF8hsrWtKiTnBuVLFdxxG7lqy2 # L6qhTr8JdraFldstIbYvG4h3QtNymdhSJ1JvALK0Wznc8GCKNoHOjAp/7wK650JE # w+0FsrHPev4gOnzJMMX94DiGlXNIwV6PPr1lHriIKpQBRzlVigTkRasXmjdz6Yoi # 8dXVgSmeeKT09WldJ1GbvqjZWJDLvAgMBrgHQmPMYVDBvZC+Ult9p1EOSTpzUsJ/ # XQBqEuvcKKdEw3QQHul0QojL66GCDX4wgg16BgorBgEEAYI3AwMBMYINajCCDWYG # CSqGSIb3DQEHAqCCDVcwgg1TAgEDMQ8wDQYJYIZIAWUDBAIBBQAweAYLKoZIhvcN # AQkQAQSgaQRnMGUCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCBPa1n/ # s7wpyF+szVDwHGHZOO2qF2MXT1QADBapONLkWAIRAMGzuozbikSN9Y1nSl59h58Y # DzIwMjEwNjE5MDQwNDA3WqCCCjcwggT+MIID5qADAgECAhANQkrgvjqI/2BAIc4U # APDdMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp # Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERp # Z2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwHhcNMjEwMTAx # MDAwMDAwWhcNMzEwMTA2MDAwMDAwWjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO # RGlnaUNlcnQsIEluYy4xIDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIx # MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuZhhGfFivUNCKRFymNr # Udc6EUK9CnV1TZS0DFC1JhD+HchvkWsMlucaXEjvROW/m2HNFZFiWrj/ZwucY/02 # aoH6KfjdK3CF3gIY83htvH35x20JPb5qdofpir34hF0edsnkxnZ2OlPR0dNaNo/G # o+EvGzq3YdZz7E5tM4p8XUUtS7FQ5kE6N1aG3JMjjfdQJehk5t3Tjy9XtYcg6w6O # LNUj2vRNeEbjA4MxKUpcDDGKSoyIxfcwWvkUrxVfbENJCf0mI1P2jWPoGqtbsR0w # wptpgrTb/FZUvB+hh6u+elsKIC9LCcmVp42y+tZji06lchzun3oBc/gZ1v4NSYS9 # AQIDAQABo4IBuDCCAbQwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwQQYDVR0gBDowODA2BglghkgBhv1sBwEwKTAn # BggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB8GA1UdIwQY # MBaAFPS24SAd/imu0uRhpbKiJbLIFzVuMB0GA1UdDgQWBBQ2RIaOpLqwZr68KC0d # RDbd42p6vDBxBgNVHR8EajBoMDKgMKAuhixodHRwOi8vY3JsMy5kaWdpY2VydC5j # b20vc2hhMi1hc3N1cmVkLXRzLmNybDAyoDCgLoYsaHR0cDovL2NybDQuZGlnaWNl # cnQuY29tL3NoYTItYXNzdXJlZC10cy5jcmwwgYUGCCsGAQUFBwEBBHkwdzAkBggr # BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME8GCCsGAQUFBzAChkNo # dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElE # VGltZXN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQBIHNy16ZojvOca # 5yAOjmdG/UJyUXQKI0ejq5LSJcRwWb4UoOUngaVNFBUZB3nw0QTDhtk7vf5EAmZN # 7WmkD/a4cM9i6PVRSnh5Nnont/PnUp+Tp+1DnnvntN1BIon7h6JGA0789P63ZHdj # XyNSaYOC+hpT7ZDMjaEXcw3082U5cEvznNZ6e9oMvD0y0BvL9WH8dQgAdryBDvjA # 4VzPxBFy5xtkSdgimnUVQvUtMjiB2vRgorq0Uvtc4GEkJU+y38kpqHNDUdq9Y9Yf # W5v3LhtPEx33Sg1xfpe39D+E68Hjo0mh+s6nv1bPull2YYlffqe0jmd4+TaY4cso # 2luHpoovMIIFMTCCBBmgAwIBAgIQCqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0B # AQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk # IElEIFJvb3QgQ0EwHhcNMTYwMTA3MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQg # VGltZXN0YW1waW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA # vdAy7kvNj3/dqbqCmcU5VChXtiNKxA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQ # mL8TvFfTw+F+CNZqFAA49y4eO+7MpvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODe # Ij8O/36V+/OjuiI+GKwR5PCZA207hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt # 30A6XLdR4aF5FMZNJCMwXbzsPGBqrC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ # /ZQqLKfkdT66mA+Ef58xFNat1fJky3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4Ud # xB08r8/arBD13ays6Vb/kwIDAQABo4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu # 0uRhpbKiJbLIFzVuMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIG # A1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsG # AQUFBwMIMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au # ZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqg # OKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS # b290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRBc3N1cmVkSURSb290Q0EuY3JsMFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAq # MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCG # SAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3 # QITvS4S/ys8DAv3Fp8MOIEIsr3fzKx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP # +LLR2HwZYuhegiUexLoceywh4tZbLBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFN # YkYkh2OMkVIsrymJ5Xgf1gsUpYDXEkdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18 # yAGxuSh1t5ljhSKMYcp5lH5Z/IwP42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8Ql # K0cCCHxJrhO24XxCQijGGFbPQTS2Zl22dHv1VjMiLyI2skuiSpXY9aaOUjGCAoYw # ggKCAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNI # QTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0ECEA1CSuC+Ooj/YEAhzhQA8N0w # DQYJYIZIAWUDBAIBBQCggdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwG # CSqGSIb3DQEJBTEPFw0yMTA2MTkwNDA0MDdaMCsGCyqGSIb3DQEJEAIMMRwwGjAY # MBYEFOHXgqjhkb7va8oWkbWqtJSmJJvzMC8GCSqGSIb3DQEJBDEiBCD+EfwdSpMw # 7UVwh7GBcnXbGn8OJsxQm7FUX9kMNeACDDA3BgsqhkiG9w0BCRACLzEoMCYwJDAi # BCCzEJAGvArZgweRVyngRANBXIPjKSthTyaWTI01cez1qTANBgkqhkiG9w0BAQEF # AASCAQC1mEI9Rw1EYZtJ6wTFkRz/x4U41fFfW9igNsIwEmTwtDk/y/r2BeF1HsZw # bRIEv8sBLT8Zm/DonqrJLrFIv/DDVrjid3M13/YmFXeYK1abJVg4l6GmEQjPzhE3 # u/fy2Uw8kY7k7jHfOub7rOBv7lOTX7TMAEIvLm52sFQJa9Hylq2yXhBRObWgQrv3 # FzYefFNVsxf5JWBXQnO1UdADsAng6b500au0rxP0TQZyf8+Z/9LpHr0swnhnEibV # j23evt7muiltEbz2DxRKWzEtP9lTOB7Tn1/82iU0kog4BaIDM5Vett16IQdg474L # B5xym4M/aDkMGsHBsl/DugWIzm9Y # SIG # End signature block |