CLI/vLunManagement.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: vLunManagement.psm1 ## Description: vLUN Management cmdlets ## ## Created: January 2020 ## 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-vLun ############################################################################################################################################ Function Get-vLun { <# .SYNOPSIS Get list of LUNs that are exported/ presented to hosts .DESCRIPTION Get list of LUNs that are exported/ presented to hosts .EXAMPLE Get-vLun List all exported volumes .EXAMPLE Get-vLun -vvName PassThru-Disk List LUN number and hosts/host sets of LUN PassThru-Disk .PARAMETER vvName Specify name of the volume to be exported. If prefixed with 'set:', the name is a volume set name. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: Get-vLun LASTEDIT: January 2020 KEYWORDS: Get-vLun .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [System.String] $vvName, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $PresentTo, [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Get-vLun - 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-vLun since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet Get-vLun 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 } $ListofvLUNs = @() $GetvLUNCmd = "showvlun -t -showcols VVName,Lun,HostName,VV_WWN " if ($vvName) { $GetvLUNCmd += " -v $vvName" } $Result = Invoke-CLICommand -Connection $SANConnection -cmds $GetvLUNCmd write-debuglog "Get list of vLUN" "INFO:" if($Result -match "Invalid vv name:") { return "FAILURE : No vv $vvName found" } $Result = $Result | where { ($_ -notlike '*total*') -and ($_ -notlike '*------*')} ## Eliminate summary lines if ($Result.Count -gt 1) { foreach ($s in $Result[1..$Result.Count] ) { $s= $s.Trim() $s= [regex]::Replace($s," +",",") # Replace one or more spaces with comma to build CSV line $sTemp = $s.Split(',') $vLUN = New-Object -TypeName _vLUN $vLUN.Name = $sTemp[0] $vLUN.LunID = $sTemp[1] $vLUN.PresentTo = $sTemp[2] $vLUN.vvWWN = $sTemp[3] $ListofvLUNs += $vLUN } } else { write-debuglog "LUN $vvName does not exist. Simply return" "INFO:" return "FAILURE : No vLUN $vvName found Error : $Result" } if ($PresentTo) { $ListofVLUNs | where {$_.PresentTo -like $PresentTo} } else { $ListofVLUNs } } # End Get-vLun ############################################################################## ########################### FUNCTION Show-vLun ############################### ############################################################################## Function Show-vLun { <# .SYNOPSIS Get list of LUNs that are exported/ presented to hosts .DESCRIPTION Get list of LUNs that are exported/ presented to hosts .EXAMPLE Show-vLun List all exported volumes .EXAMPLE Show-vLun -vvName XYZ List LUN number and hosts/host sets of LUN XYZ .EXAMPLE Show-vLun -Listcols .EXAMPLE Show-vLun -Nodelist 1 .EXAMPLE Show-vLun -DomainName Aslam_D .PARAMETER vvName Specify name of the volume to be exported. If prefixed with 'set:', the name is a volume set name. .PARAMETER Listcols List the columns available to be shown in the -showcols option described below (see 'clihelp -col showvlun' for help on each column). .PARAMETER Showcols <column>[,<column>...] Explicitly select the columns to be shown using a comma-separated list of column names. For this option the full column names are shown in the header. Run 'showvlun -listcols' to list the available columns. Run 'clihelp -col showvlun' for a description of each column. .PARAMETER ShowWWN Shows the WWN of the virtual volume associated with the VLUN. .PARAMETER ShowsPathSummary Shows path summary information for active VLUNs .PARAMETER Hostsum Shows mount point, Bytes per cluster, capacity information from Host Explorer and user reserved space, VV size from showvv. .PARAMETER ShowsActiveVLUNs Shows only active VLUNs. .PARAMETER ShowsVLUNTemplates Shows only VLUN templates. .PARAMETER Hostname {<hostname>|<pattern>|<hostset>}... Displays only VLUNs exported to hosts that match <hostname> or glob-style patterns, or to the host sets that match <hostset> or glob-style patterns(see help on sub,globpat). The host set name must start with "set:". Multiple host names, host sets or patterns can be repeated using a comma-separated list. .PARAMETER VV_name {<VV_name>|<pattern>|<VV_set>}... Displays only VLUNs of virtual volumes that match <VV_name> or glob-style patterns, or to the vv sets that match <VV-set> or glob-style patterns (see help on sub,globpat). The VV set name must start with "set:". Multiple volume names, vv sets or patterns can be repeated using a comma-separated list (for example -v <VV_name>, <VV_name>...). .PARAMETER LUN Specifies that only exports to the specified LUN are displayed. This specifier can be repeated to display information for multiple LUNs. .PARAMETER Nodelist Requests that only VLUNs for specific nodes are displayed. The node list is specified as a series of integers separated by commas (for example 0,1,2). The list can also consist of a single integer (for example 1). .PARAMETER Slotlist Requests that only VLUNs for specific slots are displayed. The slot list is specified as a series of integers separated by commas (for example 0,1,2). The list can also consist of a single integer (for example 1). .PARAMETER Portlist Requests that only VLUNs for specific ports are displayed. The port list is specified as a series of integers separated by commas ((for example 1,2). The list can also consist of a single integer (for example 1). .PARAMETER Domain_name Shows only the VLUNs whose virtual volumes are in domains with names that match one or more of the <domainname_or_pattern> options. This option does not allow listing objects within a domain of which the user is not a member. Multiple domain names or patterns can be repeated using a comma-separated list. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: Show-vLun LASTEDIT: January 2020 KEYWORDS: Show-vLun .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [switch] $Listcols, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Showcols, [Parameter(Position=2, Mandatory=$false)] [switch] $ShowsWWN, [Parameter(Position=3, Mandatory=$false)] [switch] $ShowsPathSummary, [Parameter(Position=4, Mandatory=$false)] [switch] $Hostsum, [Parameter(Position=5, Mandatory=$false)] [switch] $ShowsActiveVLUNs, [Parameter(Position=6, Mandatory=$false)] [switch] $ShowsVLUNTemplates, [Parameter(Position=7, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Hostname, [Parameter(Position=8, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $VV_name, [Parameter(Position=9, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $LUN, [Parameter(Position=10, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Nodelist, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Slotlist, [Parameter(Position=11, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $Portlist, [Parameter(Position=12, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $DomainName, [Parameter(Position=13, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Show-vLun - 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 Show-vLun since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet Show-vLun 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 } $cmd = "showvlun " if($Listcols) { $cmd += " -listcols " } if($Showcols) { $cmd += " -showcols $Showcols" } if($ShowsWWN) { $cmd += " -lvw " } if($ShowsPathSummary) { $cmd += " -pathsum " } if($Hostsum) { $cmd += " -hostsum " } if($ShowsActiveVLUNs) { $cmd += " -a " } if($ShowsVLUNTemplates) { $cmd += " -t " } if($Hostname) { $cmd += " -host $Hostname" } if($VV_name) { $cmd += " -v $VV_name" } if($LUN) { $cmd += " -l $LUN" } if($Nodelist) { $cmd += " -nodes $Nodelist" } if($Slotlist) { $cmd += " -slots $Slotlist" } if($Portlist) { $cmd += " -ports $Portlist" } if($DomainName) { $cmd += " -domain $DomainName" } $Result = Invoke-CLICommand -Connection $SANConnection -cmds $cmd write-debuglog "Get list of vLUN" "INFO:" write-host "" return $Result } # End Show-vLun ################################################################################ ########################### FUNCTION New-vLun ################################## ################################################################################ Function New-vLun { <# .SYNOPSIS The New-vLun command creates a VLUN template that enables export of a Virtual Volume as a SCSI VLUN to a host or hosts. A SCSI VLUN is created when the current system state matches the rule established by the VLUN template .DESCRIPTION The New-vLun command creates a VLUN template that enables export of a Virtual Volume as a SCSI VLUN to a host or hosts. A SCSI VLUN is created when the current system state matches the rule established by the VLUN template. There are four types of VLUN templates: Port presents - created when only the node:slot:port are specified. The VLUN is visible to any initiator on the specified port. Host set - created when a host set is specified. The VLUN is visible to the initiators of any host that is a member of the set. Host sees - created when the hostname is specified. The VLUN is visible to the initiators with any of the host's WWNs. Matched set - created when both hostname and node:slot:port are specified. The VLUN is visible to initiators with the host's WWNs only on the specified port. Conflicts between overlapping VLUN templates are resolved using prioritization, with port presents templates having the lowest priority and matched set templates having the highest. .EXAMPLE New-vLun -vvName xyz -LUN 1 -HostName xyz .EXAMPLE New-vLun -vvSet set:xyz -NoVcn -LUN 2 -HostSet set:xyz .PARAMETER vvName Specifies the virtual volume or virtual volume set name, using up to 31 characters in length. The volume name is provided in the syntax of basename.int. The VV set name must start with "set:". .PARAMETER vvSet Specifies the virtual volume or virtual volume set name, using up to 31 characters in length. The volume name is provided in the syntax of basename.int. The VV set name must start with "set:". .PARAMETER LUN Specifies the LUN as an integer from 0 through 16383. Alternatively n+ can be used to indicate a LUN should be auto assigned, but be a minimum of n, or m-n to indicate that a LUN should be chosen in the range m to n. In addition the keyword auto may be used and is treated as 0+. .PARAMETER HostName Specifies the host where the LUN is exported, using up to 31 characters. .PARAMETER HostSet Specifies the host set where the LUN is exported, using up to 31 characters in length. The set name must start with "set:". .PARAMETER NSP Specifies the system port of the virtual LUN export. node Specifies the system node, where the node is a number from 0 through 7. slot Specifies the PCI bus slot in the node, where the slot is a number from 0 through 5. port Specifies the port number on the FC card, where the port number is 1 through 4. .PARAMETER Cnt Specifies that a sequence of VLUNs, as specified by the num argument, are exported to the same system port and host that is created. The num argument can be specified as any integer. For each VLUN created, the .int suffix of the VV_name specifier and LUN are incremented by one. .PARAMETER NoVcn Specifies that a VLUN Change Notification (VCN) not be issued after export. For direct connect or loop configurations, a VCN consists of a Fibre Channel Loop Initialization Primitive (LIP). For fabric configurations, a VCN consists of a Registered State Change Notification (RSCN) that is sent to the fabric controller. .PARAMETER Ovrd Specifies that existing lower priority VLUNs will be overridden, if necessary. Can only be used when exporting to a specific host. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: New-vLun LASTEDIT: January 2020 KEYWORDS: New-vLun .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false)] [System.String] $vvName, [Parameter(Position=1, Mandatory=$false)] [System.String] $vvSet, [Parameter(Position=2, Mandatory=$false)] [System.String] $LUN, [Parameter(Position=3, Mandatory=$false)] [System.String] $NSP, [Parameter(Position=4, Mandatory=$false)] [System.String] $HostSet, [Parameter(Position=5, Mandatory=$false)] [System.String] $HostName, [Parameter(Position=6, Mandatory=$false)] [System.String] $Cnt, [Parameter(Position=7, Mandatory=$false)] [switch] $NoVcn, [Parameter(Position=8, Mandatory=$false)] [switch] $Ovrd, [Parameter(Position=9, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In New-vLun - 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-vLun since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet New-vLun 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 } $cmdVlun = " createvlun -f" if($Cnt) { $cmdVlun += " -cnt $Cnt " } if($NoVcn) { $cmdVlun += " -novcn " } if($Ovrd) { $cmdVlun += " -ovrd " } ###Added v2.1 : checking the parameter values if vvName or present to empty simply return if ($vvName -Or $vvSet) { if($vvName) { $cmdVlun += " $vvName " } else { if ($vvSet -match "^set:") { $cmdVlun += " $vvSet " } else { return "Please make sure The VV set name must start with set: Ex:- set:xyz" } } } else { Write-DebugLog "No values specified for the parameters vvname. so simply exiting " "INFO:" Get-help New-vLun return } if($LUN) { $cmdVlun += " $LUN " } else { return " Specifies the LUN as an integer from 0 through 16383." } if($NSP) { $cmdVlun += " $NSP " } elseif($HostSet) { if ($HostSet -match "^set:") { $cmdVlun += " $HostSet " } else { return "Please make sure The set name must start with set: Ex:- set:xyz" } } elseif($HostName) { $cmdVlun += " $HostName " } else { return "Please select atlist any one from NSP | HostSet | HostName" } $Result1 = Invoke-CLICommand -Connection $SANConnection -cmds $cmdVlun write-debuglog "Presenting $vvName to server $item with the command --> $cmdVlun" "INFO:" if($Result1 -match "no active paths") { $successmsg += $Result1 } elseif([string]::IsNullOrEmpty($Result1)) { $successmsg += "Success : $vvName exported to host $objName`n" } else { $successmsg += "FAILURE : While exporting vv $vvName to host $objName Error : $Result1`n" } return $successmsg } # End New-vLun ############################################################################ ########################### FUNCTION Remove-vLun ########################### ############################################################################ Function Remove-vLun { <# .SYNOPSIS Unpresent virtual volumes .DESCRIPTION Unpresent virtual volumes .EXAMPLE Remove-vLun -vvName PassThru-Disk -force Unpresent the virtual volume PassThru-Disk to all hosts .EXAMPLE Remove-vLun -vvName PassThru-Disk -whatif Dry-run of deleted operation on vVolume named PassThru-Disk .EXAMPLE Remove-vLun -vvName PassThru-Disk -PresentTo INF01 -force Unpresent the virtual volume PassThru-Disk only to host INF01. all other presentations of PassThru-Disk remain intact. .EXAMPLE Remove-vLun -PresentTo INF01 -force Remove all LUNS presented to host INF01 .EXAMPLE Remove-vLun -vvName CSV* -PresentTo INF01 -force Remove all LUNS started with CSV* and presented to host INF01 .EXAMPLE Remove-vLun -vvName vol2 -force -Novcn .EXAMPLE Remove-vLun -vvName vol2 -force -Pat .EXAMPLE Remove-vLun -vvName vol2 -force -Remove_All It removes all vluns associated with a VVOL Container. .PARAMETER whatif If present, perform a dry run of the operation and no VLUN is removed .PARAMETER force If present, perform forcible delete operation .PARAMETER vvName Specify name of the volume to be exported. .PARAMETER PresentTo Specify name of the hosts where vLUns are presented to. .PARAMETER Novcn Specifies that a VLUN Change Notification (VCN) not be issued after removal of the VLUN. .PARAMETER Pat Specifies that the <VV_name>, <LUN>, <node:slot:port>, and <host_name> specifiers are treated as glob-style patterns and that all VLUNs matching the specified pattern are removed. .PARAMETER Remove_All It removes all vluns associated with a VVOL Container. .PARAMETER SANConnection Specify the SAN Connection object created with New-CLIConnection or New-PoshSshConnection .Notes NAME: Remove-vLun LASTEDIT: January 2020 KEYWORDS: Remove-vLun .Link http://www.hpe.com #Requires PS -Version 3.0 #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)] [Switch] $force, [Parameter(Position=1, Mandatory=$false, ValueFromPipeline=$true)] [Switch] $whatif, [Parameter(Position=2, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $vvName, [Parameter(Position=3, Mandatory=$false, ValueFromPipeline=$true)] [System.String] $PresentTo, [Parameter(Position=4, Mandatory=$false, ValueFromPipeline=$true)] [Switch] $Novcn, [Parameter(Position=5, Mandatory=$false, ValueFromPipeline=$true)] [Switch] $Pat, [Parameter(Position=6, Mandatory=$false, ValueFromPipeline=$true)] [Switch] $Remove_All, [Parameter(Position=7, Mandatory=$false, ValueFromPipeline=$true)] $SANConnection = $global:SANConnection ) Write-DebugLog "Start: In Remove-vLun - validating input values" $Debug if (!(($vvName) -or ($PresentTo))) { Write-DebugLog "Action required: no vv or no host mentioned - simply exiting " $Debug Get-help Remove-vLun return } if(!(($force) -or ($whatif))) { write-debuglog "no -force or -whatif option selected to remove/dry run of VLUN, Exiting...." "INFO:" Get-help Remove-vLun return "FAILURE : no -force or -whatif option selected to remove/dry run of VLUN" } #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-vLun since SAN connection object values are null/empty" $Debug return "Unable to execute the cmdlet Remove-vLun 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($PresentTo) { $ListofvLuns = Get-vLun -vvName $vvName -PresentTo $PresentTo -SANConnection $SANConnection } else { $ListofvLuns = Get-vLun -vvName $vvName -SANConnection $SANConnection } if($ListofvLuns -match "FAILURE") { return "FAILURE : No vLUN $vvName found" } $ActionCmd = "removevlun " if ($whatif) { $ActionCmd += "-dr " } else { if($force) { $ActionCmd += "-f " } } if ($Novcn) { $ActionCmd += "-novcn " } if ($Pat) { $ActionCmd += "-pat " } if($Remove_All) { $ActionCmd += " -set " } if ($ListofvLuns) { foreach ($vLUN in $ListofvLuns) { $vName = $vLUN.Name if ($vName) { $RemoveCmds = $ActionCmd + " $vName $($vLun.LunID) $($vLun.PresentTo)" $Result1 = Invoke-CLICommand -Connection $SANConnection -cmds $RemoveCmds write-debuglog "Removing Virtual LUN's with command $RemoveCmds" "INFO:" if ($Result1 -match "Issuing removevlun") { $successmsg += "Success: Unexported vLUN $vName from $($vLun.PresentTo)" } elseif($Result1 -match "Dry run:") { $successmsg += $Result1 } else { $successmsg += "FAILURE : While unexporting vLUN $vName from $($vLun.PresentTo) " } } } return $successmsg } else { Write-DebugLog "no vLUN found for $vvName presented to host $PresentTo." $Info return "FAILURE : no vLUN found for $vvName presented to host $PresentTo" } } # END Remove-vLun Export-ModuleMember Get-vLun , Show-vLun , New-vLun , Remove-vLun # SIG # Begin signature block # MIIhEAYJKoZIhvcNAQcCoIIhATCCIP0CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCHlAIz0eJyi219 # SdU8m6ClvLNUC25c3w2eb61bLNVgUqCCEKswggUpMIIEEaADAgECAhB4Lu4fcD9z # 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 # V3AcPKRYLqPzW0sH3DJZ84enGm1YMYIPuzCCD7cCAQEwgZAwfDELMAkGA1UEBhMC # R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9y # ZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJT # QSBDb2RlIFNpZ25pbmcgQ0ECEHgu7h9wP3PFSAP6N/U6iqUwDQYJYIZIAWUDBAIB # BQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIB # BDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg # YSXa7u2E/CUTa2l7w0ST5dITivmkHES2tkdOzPjfFVgwDQYJKoZIhvcNAQEBBQAE # ggEACWwBi1diXElMWhzO5nHEVKGg2IV+UBfcYfcBPBLteat1f09S9Y5fR5ST0RqF # O3t7+gczVW/T++30sz109kB8WvZTyEqCs4dfTIo+P43aGGy0le13+9SXzYBBkw4l # uutHR+ceYwL9g2/R5aRq3LmA47Vr5/kkBxY1WqvN1RiDsLn6LEJK5J5jFdrq+q9f # 8D/MJhffy6GvaNYuhG0BzHntLSMQhoJZ5SfGXJn9NLpIIx7DnUZLkbhg5/4+weLK # VmEhbx4vIGWv0FP+gkQq4cXQUT7Q91at3xpD/QPt9trCsGBjNJboA7CknuD8O4pj # WPHfoInOhc/U7xLKGR7UYF8sUKGCDX0wgg15BgorBgEEAYI3AwMBMYINaTCCDWUG # CSqGSIb3DQEHAqCCDVYwgg1SAgEDMQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcN # AQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0GCWCGSAFlAwQCAQUABCA+YBep # 3gK9P2yi7NHSUx3+5vAt1pKbRPSPdL+RITp2yQIQeSw8nnG7nOaF0z+RtNvHoxgP # MjAyMTA2MTkwNDM3MzRaoIIKNzCCBP4wggPmoAMCAQICEA1CSuC+Ooj/YEAhzhQA # 8N0wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD # ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln # aUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQTAeFw0yMTAxMDEw # MDAwMDBaFw0zMTAxMDYwMDAwMDBaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E # aWdpQ2VydCwgSW5jLjEgMB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjEw # ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC5mGEZ8WK9Q0IpEXKY2tR # 1zoRQr0KdXVNlLQMULUmEP4dyG+RawyW5xpcSO9E5b+bYc0VkWJauP9nC5xj/TZq # gfop+N0rcIXeAhjzeG28ffnHbQk9vmp2h+mKvfiEXR52yeTGdnY6U9HR01o2j8aj # 4S8bOrdh1nPsTm0zinxdRS1LsVDmQTo3VobckyON91Al6GTm3dOPL1e1hyDrDo4s # 1SPa9E14RuMDgzEpSlwMMYpKjIjF9zBa+RSvFV9sQ0kJ/SYjU/aNY+gaq1uxHTDC # m2mCtNv8VlS8H6GHq756WwogL0sJyZWnjbL61mOLTqVyHO6fegFz+BnW/g1JhL0B # AgMBAAGjggG4MIIBtDAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV # HSUBAf8EDDAKBggrBgEFBQcDCDBBBgNVHSAEOjA4MDYGCWCGSAGG/WwHATApMCcG # CCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHwYDVR0jBBgw # FoAU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHQYDVR0OBBYEFDZEho6kurBmvrwoLR1E # Nt3janq8MHEGA1UdHwRqMGgwMqAwoC6GLGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv # bS9zaGEyLWFzc3VyZWQtdHMuY3JsMDKgMKAuhixodHRwOi8vY3JsNC5kaWdpY2Vy # dC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDCBhQYIKwYBBQUHAQEEeTB3MCQGCCsG # AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTwYIKwYBBQUHMAKGQ2h0 # dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURU # aW1lc3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggEBAEgc3LXpmiO85xrn # IA6OZ0b9QnJRdAojR6OrktIlxHBZvhSg5SeBpU0UFRkHefDRBMOG2Tu9/kQCZk3t # aaQP9rhwz2Lo9VFKeHk2eie38+dSn5On7UOee+e03UEiifuHokYDTvz0/rdkd2Nf # I1Jpg4L6GlPtkMyNoRdzDfTzZTlwS/Oc1np72gy8PTLQG8v1Yfx1CAB2vIEO+MDh # XM/EEXLnG2RJ2CKadRVC9S0yOIHa9GCiurRS+1zgYSQlT7LfySmoc0NR2r1j1h9b # m/cuG08THfdKDXF+l7f0P4TrweOjSaH6zqe/Vs+6WXZhiV9+p7SOZ3j5Npjhyyja # W4emii8wggUxMIIEGaADAgECAhAKoSXW1jIbfkHkBdo2l8IVMA0GCSqGSIb3DQEB # CwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV # BAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQg # SUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0zMTAxMDcxMjAwMDBaMHIxCzAJ # BgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k # aWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBU # aW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9 # 0DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5fU1ofue2oPSNs4jkl79jIZCY # vxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb6+NGRwYaVX4LJ37AovWg4N4i # Pw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU46gJcWvgzyIQD3XPcXJOCq3f # QDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mIUF79Zm5WYScpiYRR5oLnRlD9 # lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfxFwbvPc3WTe8GQv2iUypPhR3E # HTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAdBgNVHQ4EFgQU9LbhIB3+Ka7S # 5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wEgYD # VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYB # BQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k # aWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4 # oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJv # b3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy # dEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkwRzA4BgpghkgBhv1sAAIEMCow # KAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCwYJYIZI # AYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLpUYdWac3v3dp8qmN6s3jPBjdA # hO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQdaq6Z+CeiZr8JqmDfdqQ6kw/4 # stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC4HLHmNY8ZOUfSBAYX4k4YU1i # RiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+tpJn+1Nhiaj1a5bA9FhpDXzI # AbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6HUSHkWGCbugwtK22ixH67xCUr # RwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIvIjayS6JKldj1po5SMYIChjCC # AoICAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hB # MiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TAN # BglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJ # KoZIhvcNAQkFMQ8XDTIxMDYxOTA0MzczNFowKwYLKoZIhvcNAQkQAgwxHDAaMBgw # FgQU4deCqOGRvu9ryhaRtaq0lKYkm/MwLwYJKoZIhvcNAQkEMSIEICp6+iSc3tuA # thu6+fSzKmDSPIOZARb0QXyFEyq3unDCMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIE # ILMQkAa8CtmDB5FXKeBEA0Fcg+MpK2FPJpZMjTVx7PWpMA0GCSqGSIb3DQEBAQUA # BIIBABVIP9WkFSScQkZsRm5W0Z9YOd+pTxjpntI/fV9amJFpu+VoLm9dODg0iZx8 # 2Hv2ZfFacI0A5YqxxbpS0KD2wqcAJTB+D78x8ItpfSl4z42GQi54qswAlREKWrid # uhc5pLGY4HYtJr7dV0TJgR4ge36mBMb+Oxv4aMPh3ZSdf6yhPp8CZcbz4eG0TZ45 # 8/mZBSSFGmfC013KPlTZFjLFhiN+m1O8/BbICMAGVrlZ6pZQoC4MRSAYk503jGV2 # v7dw+RjZPG8E6KKOBVRwPW/lq/dCExxq5dVtWEG5FbpwzcZ7y6GTDf4HcP/4szQq # 4BQPlsy3M03+uufcHnbnXumghjY= # SIG # End signature block |