SpectrumControlBase-Client.Sample.ps1

##############################################################################
# #
# Licensed Materials - Property of IBM #
# #
# IBM Storage Automation Plugin for PowerShell #
# #
# (C) COPYRIGHT International Business Machines Corp. 2013, 2016 #
# 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 SpectrumControlBase-Client module in your automation solution to provision volumes for Microsft/HyperV hosts. And the following cmdlets are used in this sample script:
 
* New-SCBConnection
* Get-SCBService
* Get-SCBHostVolMapping
* Get-SCBVolume
* New-SCBVolume
* Resize-SCBVolume
* Remove-SCBVolume
 
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-SCBHost 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 SpectrumControlBase"
Info "You can get the module from PowerShell Gallery."
Info "To get the module from PowerShell Gallery, you can just issue ""Find-Module -Name SpectrumControlBase-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:\SpectrumControlBase-Client\SpectrumControlBase-Client.psd1
$module=Get-Module -Name SpectrumControlBase-Client 
if($module.Name -eq "SpectrumControlBase-Client"){
    Info "The Module SpectrumControlBase-Client has been imported."
    Info "Detailed information about SpectrumControlBase-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 SCB server, Add a PowerShell interface and create the following PowerShell interface user"
$scbLocation="https://10.0.1.15:8440"    # The Uri of the SCB server, in the format of https:\\IP:Port
$scbUsername="powershell"                    # Credential for the PowerShell interface user.
$scbPassword="passw0rd"

Info "PREPARATION 3: On the SCB 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="SCBDemoVol"    # The Prefix for the created volumes

Task "[2] Connect to the SCB Server and Create Volumes via SCB Service"
##Note: New-SCBConnection 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-SCBConnection -ConnectionUri $scbLocation -UserName $scbUsername -Password $scbPassword
$ssPsw=ConvertTo-SecureString -AsPlainText -Force $scbPassword; 
$cred=New-Object pscredential $scbUsername,$ssPsw; 
$sc=New-SCBConnection -ConnectionUri $scbLocation -Credential $cred
Info "Successfully Connect to the SCB server($scbLocation)!"
$sc|Format-Table -AutoSize

if([String]::IsNullOrEmpty($sc.Token)){
    Throw "Fail to build the connection to the SCB server."
    return $False
}

Task "[2.1] Get the service instance via service name"
$service=Get-SCBService -SCBConnection $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 SCB service, and register it to specified iSCSI initiator"
$volName= $LunPrefix + [System.DateTime]::Now.ToString("yyMMddHHmmss")
$vol=New-SCBVolume -SCBConnection $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-SCBHostVolMapping -SCBConnection $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 SCB Service"
$vol|Format-Table name,id,array_name,pool_name,logical_capacity,ratio -AutoSize

Task "[4.1] Resize the volume to 80GiB"
$ret=Resize-SCBVolume -SCBConnection $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-SCBVolume -SCBConnection $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-SCBVolume -SCBConnection $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
# MIIOnAYJKoZIhvcNAQcCoIIOjTCCDokCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUMIs8pnOJkXSiSqvP9k9xaih+
# YpCgggubMIIFiTCCBHGgAwIBAgIQHxxF6QW+gydxgPm+BZaoKjANBgkqhkiG9w0B
# AQsFADCBtDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8w
# HQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBv
# ZiB1c2UgYXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEuMCwG
# A1UEAxMlVmVyaVNpZ24gQ2xhc3MgMyBDb2RlIFNpZ25pbmcgMjAxMCBDQTAeFw0x
# NDExMTQwMDAwMDBaFw0xNzExMTMyMzU5NTlaMIG8MQswCQYDVQQGEwJDTjEQMA4G
# A1UECBMHYmVpamluZzEQMA4GA1UEBxMHYmVpamluZzEvMC0GA1UEChQmSUJNIChD
# aGluYSkgSW52ZXN0bWVudCBDb21wYW55IExpbWl0ZWQxJzAlBgNVBAsUHklCTSBT
# eXN0ZW1zICYgVGVjaG5vbG9neSBHcm91cDEvMC0GA1UEAxQmSUJNIChDaGluYSkg
# SW52ZXN0bWVudCBDb21wYW55IExpbWl0ZWQwggEgMA0GCSqGSIb3DQEBAQUAA4IB
# DQAwggEIAoIBAQDVE1mFkn6R6GERYBpu2tVQkknIrFqTHPOHAPXDN5LUGVaPA+sN
# 6yYS9ZXFcOTj2iQH1EtFOr0ndC7ZnimHOsYxmM2SA5IYPGW3NMNFcm27u7oeF7q6
# yLkjEJjQr1dbvIS/usKi3XtunsLM2aPiDB1yovttSv6AK3RRA6SghxSos93I+pFp
# L/jYsRwgzvu257jH9RE1Gb3IUAiyVu5dTsPapagb2Ip6nsGrXmB0XdHS2dxugmrL
# 49iqnaFQ7Cp6RQwlKVQA5QHK0eehX0NwU8pIBSZeyG5o8npiBJGa4yk66W9kGivC
# BPD4csocbjzLaksUf3xEz0hiBOc+501c2rJDAgEDo4IBjTCCAYkwCQYDVR0TBAIw
# ADAOBgNVHQ8BAf8EBAMCB4AwKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3NmLnN5
# bWNiLmNvbS9zZi5jcmwwZgYDVR0gBF8wXTBbBgtghkgBhvhFAQcXAzBMMCMGCCsG
# AQUFBwIBFhdodHRwczovL2Quc3ltY2IuY29tL2NwczAlBggrBgEFBQcCAjAZDBdo
# dHRwczovL2Quc3ltY2IuY29tL3JwYTATBgNVHSUEDDAKBggrBgEFBQcDAzBXBggr
# BgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zZi5zeW1jZC5jb20wJgYI
# KwYBBQUHMAKGGmh0dHA6Ly9zZi5zeW1jYi5jb20vc2YuY3J0MB8GA1UdIwQYMBaA
# FM+Zqep7JvRLyY6P1/AFJu/j0qedMB0GA1UdDgQWBBTiB9YFmAEtsIP3KnC7JMkA
# FnwHdTARBglghkgBhvhCAQEEBAMCBBAwFgYKKwYBBAGCNwIBGwQIMAYBAQABAf8w
# DQYJKoZIhvcNAQELBQADggEBAI54+6DaAS5D5li/evS2jlKXT/aa6KPK/KTkaOOy
# C0mdlnsECj2qPi0IapNYvtOL0DNYVl0r3h0GM554ZZCHyNtJRftxNsRKdcmF5bh4
# 2Q0VNGsJN+yD3FBGxS7aCr1cgxqkgmCAIJQUgm6mPu0kctFAP/cQLoUG7wrVU95l
# 8HzxNVinPGrbgW1S6dGkxWIKi32j9Esb7E6r5VS6VzdrEg9abfX3IULypdJ/6Ib5
# O5lLOaV7n+kvgLmrtq1cvXbFfFV+aODlZ8QGckqfJvjHdLSvh7eMy3Ez4mfl8wm/
# lLZCmimOmvWayX5DVGOrCpTlcPGnITCzWUqp51OdSXbiGj0wggYKMIIE8qADAgEC
# AhBSAOWqJVb8GobtlsnUSzPHMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
# UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
# dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0g
# Rm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNz
# IDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNTAe
# Fw0xMDAyMDgwMDAwMDBaFw0yMDAyMDcyMzU5NTlaMIG0MQswCQYDVQQGEwJVUzEX
# MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
# IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52
# ZXJpc2lnbi5jb20vcnBhIChjKTEwMS4wLAYDVQQDEyVWZXJpU2lnbiBDbGFzcyAz
# IENvZGUgU2lnbmluZyAyMDEwIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
# CgKCAQEA9SNLXqXXirsy6dRX9+/kxyZ+rRmY/qidfZT2NmsQ13WBMH8EaH/LK3Ue
# zR0IjN9plKc3o5x7gOCZ4e43TV/OOxTuhtTQ9Sc1vCULOKeMY50Xowilq7D7zWpi
# gkzVIdob2fHjhDuKKk+FW5ABT8mndhB/JwN8vq5+fcHd+QW8G0icaefApDw8QQA+
# 35blxeSUcdZVAccAJkpAPLWhJqkMp22AjpAle8+/PxzrL5b65Yd3xrVWsno7VDBT
# G99iNP8e0fRakyiF5UwXTn5b/aSTmX/fze+kde/vFfZH5/gZctguNBqmtKdMfr27
# Tww9V/Ew1qY2jtaAdtcZLqXNfjQtiQIDAQABo4IB/jCCAfowEgYDVR0TAQH/BAgw
# BgEB/wIBADBwBgNVHSAEaTBnMGUGC2CGSAGG+EUBBxcDMFYwKAYIKwYBBQUHAgEW
# HGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9jcHMwKgYIKwYBBQUHAgIwHhocaHR0
# cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYB
# BQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XT
# GoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3Zz
# bG9nby5naWYwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL2NybC52ZXJpc2lnbi5j
# b20vcGNhMy1nNS5jcmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRw
# Oi8vb2NzcC52ZXJpc2lnbi5jb20wHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF
# BwMDMCgGA1UdEQQhMB+kHTAbMRkwFwYDVQQDExBWZXJpU2lnbk1QS0ktMi04MB0G
# A1UdDgQWBBTPmanqeyb0S8mOj9fwBSbv49KnnTAfBgNVHSMEGDAWgBR/02Wnwt3s
# u/AwCfNDOfoCrzMxMzANBgkqhkiG9w0BAQUFAAOCAQEAViLmNKTEYctIuQGtVqhk
# D9mMkcS7zAzlrXqgIn/fRzhKLWzRf3EafOxwqbHwT+QPDFP6FV7+dJhJJIWBJhyR
# FEewTGOMu6E01MZF6A2FJnMD0KmMZG3ccZLmRQVgFVlROfxYFGv+1KTteWsIDEFy
# 5zciBgm+I+k/RJoe6WGdzLGQXPw90o2sQj1lNtS0PUAoj5sQzyMmzEsgy5AfXYxM
# NMo82OU31m+lIL006ybZrg3nxZr3obQhkTNvhuhYuyV8dA5Y/nUbYz/OMXybjxuW
# nsVTdoRbnK2R+qztk7pdyCFTwoJTY68SDVCHERs9VFKWiiycPZIaCJoFLseTpUiR
# 0zGCAmswggJnAgEBMIHJMIG0MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNp
# Z24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNV
# BAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBh
# IChjKTEwMS4wLAYDVQQDEyVWZXJpU2lnbiBDbGFzcyAzIENvZGUgU2lnbmluZyAy
# MDEwIENBAhAfHEXpBb6DJ3GA+b4FlqgqMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3
# AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG
# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBQIWwkcXxtz
# mQkXzniWF2qgY+p0UTANBgkqhkiG9w0BAQEFAASCAQAPQmV5EsEYIgP8ATgJfHXs
# +E72nauJ43/zScSaSDXflf5aNbZ0T8kRVIbSsUj6OYgZTEweN1UBB10xEIpGBBat
# 7t1hcGe/HYzOsdkaV5cVSW9QQ9lUO4OKK0oKLJD8Yc/rG2gFCDeND2zbiXfDK8mp
# X2/MG3lRoY5rcxo6aU8lvl45DYd6MT1maHQhNYGETaIQk54v6DWXQp8V96zMM297
# OmBcye8eL81jRJEYq6E5M5ZNe+85bd9EqqPvUJiUTAKmXxf9RtInDYL5VADeg0CB
# 8Idtn6O1fYvhXlvSvojLSaRcQ1yE9mOkp8/TIKpZo75xMArYQhFfiItnWMR/S8zk
# SIG # End signature block