SpectrumConnect-Client.Sample.ps1
############################################################################## # # # Licensed Materials - Property of IBM # # # # IBM Storage Automation Plugin for PowerShell # # # # (C) COPYRIGHT International Business Machines Corp. 2013, 2018 # # All Rights Reserved # # # # US Government Users Restricted Rights: Use, duplication or # # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # # ############################################################################## <# This sample script demostrates how to integrate the SpectrumConnect-Client module in your automation solution to provision volumes for Microsft/HyperV hosts. And the following cmdlets are used in this sample script: * New-SCConnection * Get-SCService * Get-SCHostVolMapping * Get-SCVolume * New-SCVolume * Resize-SCVolume * Remove-SCVolume For other cmdlets which are not covered in this sample, please refer to corresponding Help Text or Examples for more information. #> function Task([object] $information){ Write-Host $information -ForegroundColor Green } function Info([Object] $info){ Write-Host $info -ForegroundColor Yellow } function ASSERT_NOTNULL([Object] $obj){ if($obj -eq $null){ throw "NULL for the object($obj)" }else{ Write-Verbose "ASSERT: Object is not null" } } #Retrieve the FC WWPN or iSCSI initiator ports from Windows host server; Wrapper of Get-InitiatorPort and Get-WmiObject. #Alternatively, you can just issue the Get-SCHost to retrived the initiators information. function Get-HostInitiator{ param( [Alias("ComputerName")] [String] $HostName, [PSCredential] $Credential, [ValidateSet("FibreChannel","iSCSI","SAS")] [String] $ConnectionType ) $CmdletName="Get-HostInitiator" Write-Verbose ("$CmdletName.ENTER: HostName=$HostName, ConnectionType=$ConnectionType") $pcname="" if([String]::IsNullOrEmpty($HostName)){ $pcname="localhost" }else{ $pcname=$HostName } try{ $cmd=Get-Command -Name Get-InitiatorPort Write-Verbose("$CmdletName`: Get-InitiatorPort") if([String]::IsNullOrEmpty($ConnectionType)){ return Get-InitiatorPort -CimSession $pcname|%{if($_.ConnectionType -eq "Fibre Channel"){$_.PortAddress.ToUpper()}else{$_.NodeAddress}} }else{ return Get-InitiatorPort -ConnectionType $ConnectionType -CimSession $pcname|%{if($_.ConnectionType -eq "Fibre Channel"){$_.PortAddress.ToUpper()}else{$_.NodeAddress}} } Write-Verbose("$CmdletName.EXIT") } catch{ Write-Verbose "$CmdletName`: Exception found with information $($_.Exception.Message)" Write-Verbose "$CmdletName`: Fail to find the Cmdlet Get-InitiatorPort. Please ensure Storage Cmdlets are installed. Also, please ensure Windows PowerShell Remoting is enabled" Write-Verbose "$CmdletName`: Try getting the initiator ports via WS-Management." try{ if($credential -ne $null){ $hbas = Get-WmiObject -Namespace root/Microsoft/Windows/Storage -Class MSFT_InitiatorPort -ComputerName $pcname -Credential $credential }else{ $hbas = Get-WmiObject -Namespace root/Microsoft/Windows/Storage -Class MSFT_InitiatorPort -ComputerName $pcname } Write-Verbose("$CmdletName.EXIT") if($hbas -ne $null){ if([String]::IsNullOrEmpty($ConnectionType)){ return $hbas | %{if($_.ConnectionType -eq 1){$_.PortAddress.ToUpper()}else{$_.NodeAddress}} }else{ $conType="Other|FibreChannel|iSCSI|SAS".Split("|").IndexOf($ConnectionType) return ($hbas|?{$_.ConnectionType -eq $conType})%{if($_.ConnectionType -eq 1){$_.PortAddress.ToUpper()}else{$_.NodeAddress}} } }else{ return $null } }catch{ throw $_.Exception } } } Task "[1] Import the PowerShell Client Module for IBM SpectrumConnect" Info "You can get the module from PowerShell Gallery." Info "To get the module from PowerShell Gallery, you can just issue ""Find-Module -Name SpectrumConnect-Client|Install-Module -Force"";" Info "For this sample script, the module is just saved to local folder and is imported directly using Import-Module cmdlet." Import-Module R:\SpectrumConnect-Client\SpectrumConnect-Client.psd1 $module=Get-Module -Name SpectrumConnect-Client if($module.Name -eq "SpectrumConnect-Client"){ Info "The Module SpectrumConnect-Client has been imported." Info "Detailed information about SpectrumConnect-Client module:" $module|Format-List } Info "PREPARATION 1: Define storage pools for allocations, and ensure that all the required hosts are connected to the storage system." $computerName="win2012r2x215" # The Windows Host server with iSCSI(or FC) enabled. $domainAdmin="Domain01\User01" # Specifies a user account that has permission to perform this action on the windows host $computerName. $domainPassword="Passw0rd" Info "PREPARATION 2: On the SC server, Add a PowerShell interface and create the following PowerShell interface user" $scLocation="https://10.0.1.15:8440" # The Uri of the SC server, in the format of https:\\IP:Port $scUsername="powershell" # Credential for the PowerShell interface user. $scPassword="passw0rd" Info "PREPARATION 3: On the SC server, add a new storage space, add storage services, and attach services to the PowerShell interface created in PREPARATION 2." $spaceName="DemoSpace" # Space name. $serviceName="CompressionService" # Service name. For this sample, this service can be used to create Compression volumes. $LunPrefix="SCDemoVol" # The Prefix for the created volumes Task "[2] Connect to the SC Server and Create Volumes via SC Service" ##Note: New-SCConnection supports creating the connection using PowerShell Credential object, and you can also pass a PScredential object here ## Or use the user name/password explicitly: New-SCConnection -ConnectionUri $scLocation -UserName $scUsername -Password $scPassword $ssPsw=ConvertTo-SecureString -AsPlainText -Force $scPassword; $cred=New-Object pscredential $scUsername,$ssPsw; $sc=New-SCConnection -ConnectionUri $scLocation -Credential $cred Info "Successfully Connect to the SC server($scLocation)!" $sc|Format-Table -AutoSize if([String]::IsNullOrEmpty($sc.Token)){ Throw "Fail to build the connection to the SC server." return $False } Task "[2.1] Get the service instance via service name" $service=Get-SCService -SCConnection $sc -ServiceName $serviceName ASSERT_NOTNULL $service Info "Service with name $serviceName found:" $service|Format-Table name,id,total_capacity,space_name -AutoSize Task "[2.2] Get the host initiators from Windows host" $ssDomainPsw=ConvertTo-SecureString -AsPlainText -Force $domainPassword $credential=New-Object PSCredential $domainAdmin,$ssDomainPsw $iSCSIPort=(Get-HostInitiator -HostName $computerName -Credential $credential -ConnectionType iSCSI) Task "[2.3] Add a volume via SC service, and register it to specified iSCSI initiator" $volName= $LunPrefix + [System.DateTime]::Now.ToString("yyMMddHHmmss") $vol=New-SCVolume -SCConnection $sc -Name $volName -Size 40 -SizeUnit GiB -ServiceID $service.ID -Initiators $iSCSIPort if($vol -eq $null){ Info "Fail to create new volume" return $False } Info "The following volume is created:" $vol|Format-Table name,id,array_name,pool_name,service_name,ratio -AutoSize $mapping=Get-SCHostVolMapping -SCConnection $sc -VolumeID $vol.id Info "And its mapping information is listed below:" $mapping|Format-Table -AutoSize Task "[3] Mount the volume on Windows host" Update-HostStorageCache -CimSession $computerName $disk=Get-Disk -CimSession $computerName -UniqueId $vol.id ASSERT_NOTNULL $disk Info "Disk found on Windows host $computerName with following information:" $disk|Format-Table Number,ProvisioningType,OperationalStatus,AllocatedSize,UniqueId,PartitionStyle,IsOffline,IsReadOnly,PSComputerName -AutoSize Task "[3.1] Bring the Disk Online if the disk is Offline" if($disk.OperationalStatus -eq "Offline"){ Info "The disk is offline by default and will bring the disk Online" Set-Disk -CimSession $computerName -UniqueId $disk.UniqueId -IsOffline $False $disk=Get-Disk -CimSession $computerName -UniqueId $disk.UniqueId if($disk.OperationalStatus -eq "Online"){ Info "Succeed to bring the disk Online" $disk|Format-Table Number,ProvisioningType,OperationalStatus,AllocatedSize,UniqueId,PartitionStyle,IsOffline,IsReadOnly,PSComputerName -AutoSize }else{ Info "Fail to bring the disk online" return $false } } Task "[3.2] Initialize the disk" if($disk.PartitionStyle -eq "RAW"){ Info "The partition style of the disk is detected to be RAW, and will initialize this disk to MBR partition style" Initialize-Disk -CimSession $computerName -UniqueId $disk.UniqueId -PartitionStyle MBR -Confirm:$False $disk=Get-Disk -CimSession $computerName -UniqueId $disk.UniqueId if($disk.PartitionStyle -ne "RAW"){ Info "Succeed to initialize the disk to $($disk.PartitionStyle)" $disk|Format-Table Number,ProvisioningType,OperationalStatus,AllocatedSize,UniqueId,PartitionStyle,IsOffline,IsReadOnly,PSComputerName -AutoSize } }else{ Info "Ignored for the partition style of the disk is detected to be $($disk.PartitionStyle)" } Task "[3.3] Format the Disk and Mount with a DriveLetter" $partition=New-Partition -DiskNumber $disk.Number -AssignDriveLetter -UseMaximumSize -CimSession $computerName $partition|Format-Table PartitionNumber,Offset,Size,IsActive,DriveLetter,PSComputerName -AutoSize Format-Volume -DriveLetter $partition.DriveLetter -FileSystem NTFS -NewFileSystemLabel "Compressed" -Force -Confirm:$False -CimSession $computerName Get-Volume -DriveLetter $partition.DriveLetter -CimSession $computerName|Format-Table DriveLetter,DriveType,FileSystem,HealthStatus,Size,SizeRemaining,FileSystemLabel,PSComputerName -AutoSize Task "[4] Resize the volume" Info "Before Resizing the Volume via SC Service" $vol|Format-Table name,id,array_name,pool_name,logical_capacity,ratio -AutoSize Task "[4.1] Resize the volume to 80GiB" $ret=Resize-SCVolume -SCConnection $sc -VolumeID $vol.id -NewSize 80 -SizeUnit GiB if($ret){ Info "Succeed to resize the disk, and the information of the volume is listed below:" $vol=Get-SCVolume -SCConnection $sc -VolumeID $vol.id $vol|Format-Table name,id,array_name,pool_name,logical_capacity,ratio -AutoSize } Info "[4.2] Update the Volume on Windows Host" Update-Disk -CimSession $computerName -UniqueId $disk.UniqueId $disk=Get-Disk -CimSession $computerName -UniqueId $disk.UniqueId Info "Disk information after updating" $disk|Format-Table Number,ProvisioningType,OperationalStatus,AllocatedSize,UniqueId,PartitionStyle,IsOffline,IsReadOnly,PSComputerName -AutoSize Task "[5] Remove the volume $($vol.name)" Pause $ret=Remove-SCVolume -SCConnection $sc -ID $vol.id -Force if($ret){ info "Succeed to remove the volume $($vol.name)!" }else{ info "Fail to remove the volume $($vol.name)!" } # SIG # Begin signature block # MIINMwYJKoZIhvcNAQcCoIINJDCCDSACAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUBc81I3RQwqXceKGlr8G9VTyT # QiygggpoMIIFBzCCA++gAwIBAgIQO50nymBTQHmVgRJdr11LljANBgkqhkiG9w0B # AQsFADB/MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRp # b24xHzAdBgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxMDAuBgNVBAMTJ1N5 # bWFudGVjIENsYXNzIDMgU0hBMjU2IENvZGUgU2lnbmluZyBDQTAeFw0xNzExMTAw # MDAwMDBaFw0yMDEyMDkyMzU5NTlaMIGgMQswCQYDVQQGEwJDTjEQMA4GA1UECAwH # QmVpamluZzEQMA4GA1UEBwwHQmVpamluZzEvMC0GA1UECgwmSUJNIChDaGluYSkg # SW52ZXN0bWVudCBDb21wYW55IExpbWl0ZWQxCzAJBgNVBAsMAklUMS8wLQYDVQQD # DCZJQk0gKENoaW5hKSBJbnZlc3RtZW50IENvbXBhbnkgTGltaXRlZDCCASAwDQYJ # KoZIhvcNAQEBBQADggENADCCAQgCggEBAPLD5ch7kY3fK7NRk6kPkWafTZzGveXm # ZCIqDJs4Et5wt5IhZzWIeMsZ3bu+M++lhEJieQCMnPATx/UVlaKxZNHS2Lhp2AlO # nTiNCoPsmpPMeX93dwgvNPut0Hnd+jQdAmi2SCECboAmC6nOdC6oDrvqUkZ6Dk7Y # n8g+R3GMenDc8ytkEO/Ou8+ySznHD/4JCfHyP0AuaBdejJ7fXcoXG5Z7wptKp5e4 # 0+cmbU0I6bUf8vgC5GD7xtwauN/aA3CqIuOX1u/gk0b5vR51YKYkF6HKJyrn2JlG # 5z17FRMLVGAKYXWpaTD6Ib0GnsbLsTed80VYqxpAkpZ3g2ut+/Tz9AMCAQOjggFd # MIIBWTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDArBgNVHR8EJDAiMCCgHqAc # hhpodHRwOi8vc3Yuc3ltY2IuY29tL3N2LmNybDBhBgNVHSAEWjBYMFYGBmeBDAEE # ATBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Quc3ltY2IuY29tL2NwczAlBggrBgEF # BQcCAjAZDBdodHRwczovL2Quc3ltY2IuY29tL3JwYTATBgNVHSUEDDAKBggrBgEF # BQcDAzBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zdi5zeW1j # ZC5jb20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9zdi5zeW1jYi5jb20vc3YuY3J0MB8G # A1UdIwQYMBaAFJY7U/B5M5evfYPvLivMyreGHnJmMB0GA1UdDgQWBBSCjmKRqxXa # sDjI6emU05joKoNBczANBgkqhkiG9w0BAQsFAAOCAQEAUV14IxCZrkkGCKFpn048 # G7O8OYESMkJPzBUt35Rn2eXtZI0HUgDEZ4iKi8xCrZ6ssz+eATSm4m22Fc+0wRVf # o1Uq4VfGyFPkXLAPhvQUFEsevFK9ps9buaWGTwSixRjpPOwfymcEz/6p7MIiXteL # mIlfPDY4+ie3IWCo2PFEvrVzJObcuuEjEylraxkcVvQte7f4i3QHGQvkLhWA0OGY # WT5YDJD6s229ujueHBkvvDGmWP7dmFWe2j2jpgJKOxZFPQ/+YyrAlRohzDAcYgGj # 6jxuXLUoFgKiRyJ+PDmAYI695AE6QWJBC4EwmTNZNFNnu5JbFCzipRQSD122QsLh # wzCCBVkwggRBoAMCAQICED141/l2SWCyYX308B7KhiowDQYJKoZIhvcNAQELBQAw # gcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UE # CxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDIwMDYgVmVy # aVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8 # VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1 # dGhvcml0eSAtIEc1MB4XDTEzMTIxMDAwMDAwMFoXDTIzMTIwOTIzNTk1OVowfzEL # MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD # VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTAwLgYDVQQDEydTeW1hbnRlYyBD # bGFzcyAzIFNIQTI1NiBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUA # A4IBDwAwggEKAoIBAQCXgx4AFq8ssdIIxNdok1FgHnH24ke021hNI2JqtL9aG1H3 # ow0Yd2i72DarLyFQ2p7z518nTgvCl8gJcJOp2lwNTqQNkaC07BTOkXJULs6j20Tp # Uhs/QTzKSuSqwOg5q1PMIdDMz3+b5sLMWGqCFe49Ns8cxZcHJI7xe74xLT1u3LWZ # Qp9LYZVfHHDuF33bi+VhiXjHaBuvEXgamK7EVUdT2bMy1qEORkDFl5KK0VOnmVuF # NVfT6pNiYSAKxzB3JBFNYoO2untogjHuZcrf+dWNsjXcjCtvanJcYISc8gyUXsBW # UgBIzNP4pX3eL9cT5DiohNVGuBOGwhud6lo43ZvbAgMBAAGjggGDMIIBfzAvBggr # BgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYD # VR0TAQH/BAgwBgEB/wIBADBsBgNVHSAEZTBjMGEGC2CGSAGG+EUBBxcDMFIwJgYI # KwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vY3BzMCgGCCsGAQUFBwIC # MBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMDAGA1UdHwQpMCcwJaAjoCGG # H2h0dHA6Ly9zMS5zeW1jYi5jb20vcGNhMy1nNS5jcmwwHQYDVR0lBBYwFAYIKwYB # BQUHAwIGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIBBjApBgNVHREEIjAgpB4wHDEa # MBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01NjcwHQYDVR0OBBYEFJY7U/B5M5evfYPv # LivMyreGHnJmMB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG # SIb3DQEBCwUAA4IBAQAThRoeaak396C9pK9+HWFT/p2MXgymdR54FyPd/ewaA1U5 # +3GVx2Vap44w0kRaYdtwb9ohBcIuc7pJ8dGT/l3JzV4D4ImeP3Qe1/c4i6nWz7s1 # LzNYqJJW0chNO4LmeYQW/CiwsUfzHaI+7ofZpn+kVqU/rYQuKd58vKiqoz0EAeq6 # k6IOUCIpF0yH5DoRX9akJYmbBWsvtMkBTCd7C6wZBSKgYBU/2sn7TUyP+3Jnd/0n # lMe6NQ6ISf6N/SivShK9DbOXBd5EDBX6NisD3MFQAfGhEV0U5eK9J0tUviuEXg+m # w3QFCu+Xw4kisR93873NQ9TxTKk/tYuEr2Ty0BQhMYICNTCCAjECAQEwgZMwfzEL # MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD # VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTAwLgYDVQQDEydTeW1hbnRlYyBD # bGFzcyAzIFNIQTI1NiBDb2RlIFNpZ25pbmcgQ0ECEDudJ8pgU0B5lYESXa9dS5Yw # CQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcN # AQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUw # IwYJKoZIhvcNAQkEMRYEFIA2MF2YfemZkrT6qh7cK8a87NTLMA0GCSqGSIb3DQEB # AQUABIIBAMmz3ndzx10u4fO4j+dv12pZrVn1oK+8hawp5P04W0GCKxKfIxHWL6UN # 7eatbjERqjDpmlrw+fuBowR/fCPgHKhZZk5mlO+gyTNTzJd7BWwRS5kEzvb5WGlj # DdFNaoLEViNpCwudNUHP2xLzScqgYgrFhe6ugXXBo4MgQKXUs0bqCWIgG5F58++N # n405wMRVLi6w1xJjmwGgGRfjTs5QrjnrjWCP+49g1Ad3yBppFFwaclIdbXwZja0l # T5BM3cbuUTn8MsdIw1Y+bMp4wfJ1NpreHIaWgRNvuqcYfMjXYrorOMQw0/K1d8wZ # rB+y1H6HT1DQa+lmEcgYj9Q+wRJxt1c= # SIG # End signature block |