HPE Storage Tech Insiders
cancel
Showing results for 
Search instead for 
Did you mean: 

Introducing the Nimble PowerShell Toolkit 1.0

jcates98

It’s tough to beat PowerShell for automating administrative tasks, or simply providing an elegant and powerful command line based alternative to the Nimble Web UI. With the introduction of NimbleOS 2.3, we made the Nimble REST API available for those interested in building scripts or software that integrated with our arrays. While it’s possible to use PowerShell to invoke the REST API (I blogged about exactly that HERE), there’s admittedly a learning curve to picking up the nuances of working with REST if all you really want to do is execute some cmdlets to help in administering your Nimble environment.

With that in mind, we are pleased to announce the availability of the Nimble PowerShell Toolkit 1.0.  It is available for immediate download via InfoSight.  You can get it from this page.

The toolkit makes the functionality we’ve exposed through the API easier to consume via native PowerShell cmdlets. Let’s look at the prerequisites, install the toolkit, see what's included, and walk through some examples.

Prerequisites

Host OS

Essentially, the toolkit requires PowerShell version 3 or higher. So basically whether you're running Windows Server 2012, 2012R2, or Windows 7/8/10, just make sure your PowerShell version is 3 or greater. You can check your version by inspecting the $PSVersionTable variable and noting the value for PSVersion:

PS C:\> $PSVersionTable

Name                          Value

----                          -----

PSVersion                      3.0

WSManStackVersion              3.0

SerializationVersion           1.1.0.1

CLRVersion                     4.0.30319.42000ee

BuildVersion                   6.2.9200.16398

PSCompatibleVersions           {1.0, 2.0, 3.0}

PSRemotingProtocolVersion      2.2

NimbleOS

As mentioned earlier, the Nimble PowerShell Toolkit is built on the REST API and as such it requires a NimbleOS version which provides this API.  That means NimbleOS 2.3.x at a minimum.  NimbleOS 3.x is also supported.

Installation

The toolkit is downloaded as a zip file.  Once you have it on your system, installation is a simple matter of unzipping the contents of the file and placing them into the appropriate location.

To install for all users, copy the NimblePowerShellToolkit folder into the C:\Windows\system32\WindowsPowerShell\v1.0\Modules directory.

To install for the current user only, copy the NimblePowerShellToolkit folder into $env:HOMEDRIVE\users\<user>\Documents\WindowsPowerShell\Modules

Cmdlets

The following cmdlets are available as part of the toolkit. The readme file included with the download goes into a bit more detail describing the purpose of each cmdlet, so I won't reproduce that here.  Additionally, most of the cmdlets proivide example usage within the help file.

Connect-NSGroup

Connect-NSGroup

Disconnect-NSGroup

Get-NSAccessControlRecord

Get-NSArray

Get-NSAuditLog

Get-NSChapUser

Get-NSFibreChannelPort

Get-NSGroup

Get-NSInitiator

Get-NSInitiatorGroup

Get-NSJob

Get-NSNetworkConfig

Get-NSNetworkInterface

Get-NSPerformancePolicy

Get-NSPool

Get-NSProtectionSchedule

Get-NSProtectionTemplate

Get-NSReplicationPartner

Get-NSRole

Get-NSSnapshot

Get-NSSnapshotCksum

Get-NSSnapshotCollection

Get-NSSoftwareVersion

Get-NSSubnet

Get-NSToken

Get-NSUser

Get-NSVolume

Get-NSVolumeCollection

Get-NSVolumeFamily

Invoke-NSVolumeCollectionDemote

Invoke-NSVolumeCollectionPromote

Merge-NSPool

New-NSAccessControlRecord

New-NSChapUser

New-NSClone

New-NSDebugLog

New-NSInitiator

New-NSInitiatorGroup

New-NSNetworkConfig

New-NSPerformancePolicy

New-NSPool

New-NSProtectionSchedule

New-NSProtectionTemplate

New-NSReplicationPartner

New-NSSnapshot

New-NSSnapshotCollection

New-NSToken

New-NSUser

New-NSVolume

New-NSVolumeCollection

Remove-NSAccessControlRecord

Remove-NSChapUser

Remove-NSInitiator

Remove-NSInitiatorGroup

Remove-NSNetworkConfig

Remove-NSPerformancePolicy

Remove-NSPool

Remove-NSProtectionSchedule

Remove-NSProtectionTemplate

Remove-NSReplicationPartner

Remove-NSSnapshot

Remove-NSSnapshotCollection

Remove-NSToken

Remove-NSUser

Remove-NSVolume

Remove-NSVolumeCollection

Restore-NSVolume

Set-NSChapUser

Set-NSInitiatorGroup

Set-NSNetworkConfig

Set-NSPerformancePolicy

Set-NSPool

Set-NSProtectionSchedule

Set-NSProtectionTemplate

Set-NSReplicationPartner

Set-NSSnapshot

Set-NSSnapshotCollection

Set-NSUser

Set-NSVolume

Set-NSVolumeCollection

Examples

Connecting to an array/group

First we'll import the NimblePowerShellToolKit module, then connect to an array so that we can run further commands.  The Connect-NSGroup takes a PSCredential object as an argument.  If you forget to provide one, it will prompt you for one:


PS C:\Users\jcates> ipmo NimblePowerShellToolKit

PS C:\Users\jcates> $cred = Get-Credential

PS C:\Users\jcates> Connect-NSGroup -group myarray.nimble.com -credential $cred


Group        : myarray

ManagementIP : 1.2.3.4

User         : admin

Model        : AF7000

SerialNo     : AC-123456

Version      : 3.3.0.0-346604-opt


Create a Volume

Here we'll create a very simple volume.  It's possible to specify many more options to the command, but we'll accept the defaults for now.  Feel free to experiment!


PS C:\Users\jcates> New-NSVolume -name newvol -size 10240

access_control_records        :

agent_type                    : none

app_category                  : Other

app_uuid                      :

base_snap_id                  :

base_snap_name                :

block_size                    : 4096

cache_needed_for_pin          : 10737418240

cache_pinned                  : False

cache_policy                  : normal

caching_enabled               :

clone                         : False

creation_time                 : 4/29/2016 1:55:07 PM

dedupe_enabled                : False

description                   :

dest_pool_id                  :

dest_pool_name                :

encryption_cipher             : none

fc_sessions                   :

folder_id                     :

folder_name                   :

full_name                     :

id                            : 06239f8bea1874ff06000000000000000000000095

iscsi_sessions                :

last_modified                 : 4/29/2016 1:55:07 PM

limit                         : 100

metadata                      :

move_aborting                 : False

move_bytes_migrated           : 0

move_bytes_remaining          : 0

move_est_compl_time           : 0

move_start_time               : 0

multi_initiator               : True

name                          : newvol

num_connections               : 0

num_fc_connections            : 0

num_iscsi_connections         : 0

num_snaps                     : 0

offline_reason                :

online                        : True

online_snaps                  :

owned_by_group                : group-rtp-afa8

owned_by_group_id             : 00239f8bea1874ff06000000000000000000000001

parent_vol_id                 :

parent_vol_name               :

perfpolicy_id                 : 03239f8bea1874ff06000000000000000000000001

perfpolicy_name               : default

pinned_cache_size             : 0

pool_id                       : 0a239f8bea1874ff06000000000000000000000001

pool_name                     : default

previously_deduped            : False

projected_num_snaps           : 0

read_only                     : False

reserve                       : 0

search_name                   : newvol

serial_number                 : 38129d49930fc4d46c9ce900ec74eb3b

size                          : 10240

snap_limit                    : 9223372036854775807

snap_reserve                  : 0

snap_usage_compressed_bytes   : 0

snap_usage_populated_bytes    : 0

snap_usage_uncompressed_bytes : 0

snap_warn_level               : 0

target_name                   :

thinly_provisioned            : True

upstream_cache_pinned         : False

usage_valid                   : True

vol_state                     : online

vol_usage_compressed_bytes    : 0

vol_usage_uncompressed_bytes  : 0

volcoll_id                    :

volcoll_name                  :

vpd_ieee0                     : 38129d49930fc4d4

vpd_ieee1                     : 6c9ce900ec74eb3b

vpd_t10                       : Nimble  38129d49930fc4d46c9ce900ec74eb3b

warn_level                    : 80


Wow, volumes sure do have a lot of attributes!  It sure would be nice to focus on only the most important attributes, but still have access to all of the attributes if and when we need them.  The Nimble PS toolkit has been designed to be configurable in this regard.  You may have noticed an included JSON file when you installed the toolkit.  This file determines which fields will be displayed by default and which fields will be hidden (but still part of the  resulting PS object. You can edit this JSON file to customize the output for your environment, and the changes will take effect once the module has been unloaded/reloaded.  Let's take a look at an example of these in action.

Viewing Volumes


PS C:\Users\jcates> $myvols = Get-NSVolume -name newvol


PS C:\Users\jcates> $myvols

name            : newvol

size            : 10240

perfpolicy_name : default

vol_state       : online

iscsi_sessions  :

num_connections : 0

pool_name       : default

volcoll_name    :

target_name     : iqn.2007-11.com.nimblestorage:newvol-v18609ac9edd6a7e6.00000932.f5b63d2f

agent_type      : none

PS C:\Users\jcates> $myvols | select *

access_control_records        :

agent_type                    : none

app_uuid                      :

base_snap_id                  :

base_snap_name                :

block_size                    : 4096

cache_needed_for_pin          : 10737418240

cache_pinned                  : False

cache_policy                  : normal

caching_enabled               : True

clone                         : False

creation_time                 : 4/29/2016 2:03:22 PM

description                   :

dest_pool_id                  :

dest_pool_name                :

encryption_cipher             : none

fc_sessions                   :

full_name                     :

id                            : 0618609ac9edd6a7e6000000000000000000000932

iscsi_sessions                :

last_modified                 : 4/29/2016 2:03:22 PM

limit                         : 100

metadata                      :

move_aborting                 : False

move_bytes_migrated           : 0

move_bytes_remaining          : 0

move_start_time               : 0

multi_initiator               : False

name                          : newvol

num_connections               : 0

num_fc_connections            : 0

num_iscsi_connections         : 0

num_snaps                     : 0

offline_reason                :

online                        : True

online_snaps                  :

owned_by_group                : mktg-cs02

parent_vol_id                 :

parent_vol_name               :

perfpolicy_id                 : 0318609ac9edd6a7e6000000000000000000000001

perfpolicy_name               : default

pinned_cache_size             : 0

pool_id                       : 0a18609ac9edd6a7e6000000000000000000000001

pool_name                     : default

projected_num_snaps           : 0

read_only                     : False

reserve                       : 0

search_name                   : newvol

serial_number                 : 1b3023950c91c8056c9ce9002f3db6f5

size                          : 10240

snap_limit                    : 9223372036854775807

snap_reserve                  : 0

snap_usage_compressed_bytes   : 0

snap_usage_populated_bytes    : 0

snap_usage_uncompressed_bytes : 0

snap_warn_level               : 0

target_name                   : iqn.2007-11.com.nimblestorage:newvol-v18609ac9edd6a7e6.00000932.f5b63d2f

thinly_provisioned            : True

upstream_cache_pinned         : False

usage_valid                   : True

vol_state                     : online

vol_usage_compressed_bytes    : 0

vol_usage_uncompressed_bytes  : 0

volcoll_id                    :

volcoll_name                  :

warn_level                    : 80

Alright, as you can see the object still has all of the fields, but will only display the hidden fields if you tell it to. Cool!

Create a Snapshot

This one is a little more nuanced. The underlying API requires a volume id, so we need to provide that to the Get-NSsnapshot cmdlet instead of a volume name.  No problem, though.  We can grab the volume id from Get-NSVolume.


PS C:\Users\jcates> New-NSSnapshot -name mysnapshot -vol_id $(Get-NSVolume -name newvol).id

access_control_records      :

app_uuid                    :

creation_time               : 4/29/2016 3:04:06 PM

description                 :

id                          : 0418609ac9edd6a7e60000000000000a000005211c

is_replica                  : False

is_unmanaged                : True

last_modified               : 4/29/2016 3:04:06 PM

metadata                    :

name                        : mysnapshot

new_data_compressed_bytes   : 0

new_data_uncompressed_bytes : 0

new_data_valid              : False

offline_reason              : user

online                      : False

origin_name                 : myarray

replication_status          :

schedule_name               :

serial_number               : 581dea4c5692478a6c9ce9002f3db6f5

size                        : 10737418240

snap_collection_id          : 0518609ac9edd6a7e600000000000000000005211c

snap_collection_name        : 113671168983149651921554878598198852288510378691027866640113

target_name                 : iqn.2007-11.com.nimblestorage:newvol-mysnapshot-v18609ac9edd6a7e6.00000932.f5b63d2f.s18609ac9edd6a7e6.00000a00.0005211c

vol_id                      : 0618609ac9edd6a7e6000000000000000000000932

vol_name                    : newvol

writable                    : False

Get a List of Snapshots

The one thing you need to be aware of with Get-NSsnapshot is that, like the API, it requires a volume to be specified.  (If you really need ALL of the snapshots on the array, a foreach loop through each of the volumes should do the trick.)  Here we can specify the volume by name.


PS C:\Users\jcates> Get-NSSnapshot -vol_name newvol

name                                                                                                id

----                                                                                                --

mysnapshot                                                                                          0418609ac9edd6a7e60000000000000a000005211c

If we want to dig into the details of each snapshot, we can query by snapshot id and select all of the hidden fields.


PS C:\Users\jcates> Get-NSSnapshot -id 0418609ac9edd6a7e60000000000000a000005211c | select *

access_control_records      :

app_uuid                    :

creation_time               : 4/29/2016 3:04:06 PM

description                 :

id                          : 0418609ac9edd6a7e60000000000000a000005211c

is_replica                  : False

is_unmanaged                : True

last_modified               : 4/29/2016 3:10:22 PM

metadata                    :

name                        : mysnapshot

new_data_compressed_bytes   : 0

new_data_uncompressed_bytes : 0

new_data_valid              : True

offline_reason              : user

online                      : False

origin_name                 : mktg-cs02

replication_status          :

schedule_name               :

serial_number               : 581dea4c5692478a6c9ce9002f3db6f5

size                        : 10737418240

snap_collection_id          : 0518609ac9edd6a7e600000000000000000005211c

snap_collection_name        : 113671168983149651921554878598198852288510378691027866640113

target_name                 : iqn.2007-11.com.nimblestorage:newvol-mysnapshot-v18609ac9edd6a7e6.00000932.f5b63d2f.s18609ac9edd6a7e6.00000a00.0005211c

vol_id                      : 0618609ac9edd6a7e6000000000000000000000932

vol_name                    : newvol

writable                    : False

Clone a Volume

Now that we have a snapshot in place, we could create a Nimble Zero-Copy Clone volume from it.


PS C:\Users\jcates> New-NSClone -name myclone -base_snap_id 0418609ac9edd6a7e60000000000000a000005211c -clone $true

access_control_records        :

agent_type                    : none

app_uuid                      :

base_snap_id                  : 0418609ac9edd6a7e60000000000000a000005211c

base_snap_name                : mysnapshot

block_size                    : 4096

cache_needed_for_pin          : 21474836480

cache_pinned                  : False

cache_policy                  : normal

caching_enabled               : True

clone                         : True

creation_time                 : 4/29/2016 3:24:42 PM

description                   :

dest_pool_id                  :

dest_pool_name                :

encryption_cipher             : none

fc_sessions                   :

full_name                     :

id                            : 0618609ac9edd6a7e6000000000000000000000933

iscsi_sessions                :

last_modified                 : 4/29/2016 3:24:42 PM

limit                         : 100

metadata                      :

move_aborting                 : False

move_bytes_migrated           : 0

move_bytes_remaining          : 0

move_start_time               : 0

multi_initiator               : False

name                          : myclone

num_connections               : 0

num_fc_connections            : 0

num_iscsi_connections         : 0

num_snaps                     : 0

offline_reason                : user

online                        : False

online_snaps                  :

owned_by_group                : myarray

parent_vol_id                 : 0618609ac9edd6a7e6000000000000000000000932

parent_vol_name               : newvol

perfpolicy_id                 : 0318609ac9edd6a7e6000000000000000000000001

perfpolicy_name               : default

pinned_cache_size             : 0

pool_id                       : 0a18609ac9edd6a7e6000000000000000000000001

pool_name                     : default

projected_num_snaps           : 0

read_only                     : False

reserve                       : 0

search_name                   : myclone

serial_number                 : 7e527c1b273f93ee6c9ce9002f3db6f5

size                          : 10240

snap_limit                    : 9223372036854775807

snap_reserve                  : 0

snap_usage_compressed_bytes   : 0

snap_usage_populated_bytes    : 0

snap_usage_uncompressed_bytes : 0

snap_warn_level               : 0

target_name                   : iqn.2007-11.com.nimblestorage:myclone-v18609ac9edd6a7e6.00000933.f5b63d2f

thinly_provisioned            : True

upstream_cache_pinned         : False

usage_valid                   : True

vol_state                     : offline

vol_usage_compressed_bytes    : 0

vol_usage_uncompressed_bytes  : 0

volcoll_id                    :

volcoll_name                  :

warn_level                    : 80

Delete a Volume

Once a volume has served its purpose, we can delete it. We need to first set it offline with the Set-NSvolume cmdlet, then we can delete it from the array with Remove-NSVolume.

PS C:\Users\jcates> Set-NSVolume -name myclone -online $false

PS C:\Users\jcates> Remove-NSVolume -name myclone

Once again, we have merely scratched the surface of what's possible through PowerShell.  I encourage you to download the toolkit and give it a spin.  As always, we'd love to see the cool things you create with it.  Feel free to share them here on Nimble Connect!

About the Author

jcates98

Comments
stooie2950

Hello,

Do you have any examples on creating and adding volumes to volume collections as I am struggling a bit.

Thanks

jcates98

Sure thing, Stuart. In this case, you can't specify the volume collection when initially creating the volume, but can modify the volcoll_id parameter on the volume after you've created it in order to add it to the desired collection.  So it would go something like this:

$volcoll = Get-NSVolumeCollection -name TechMarketing

New-NSVolume -name test1234 -size 1024

Set-NSVolume -name test1234 -volcoll_id $volcoll.id

PS C:\Users\jcates> Get-NSVolume -name test1234 | select name,size,volcoll_id

name      : test1234

size      : 1024

volcoll_id : 0718609ac9edd6a7e6000000000000000000000082

Cheers!

Julian

stooie2950

Thanks Julian that helps a lot. Is it a similar process for creating a volume collection from scratch it seems to infer that a template and a schedule are needed first before creating the collection itself?

Thanks Again

Stu

jcates98

Just like in the NimbleOS UI, when you create a new volume collection there is an option to start with a template, but this is not mandatory. It's perfectly acceptable to start with a blank schedule:

newvolcoll.png

If you don't have a template you plan to use, the whole workflow would look something like:

  • Create a volume collection
  • Create a schedule (specifying which volcoll the schedule is for)
  • Create volume(s)
  • Add volume(s) to the volume collection

So let's look at this in PowerShell again, this time creating a new volcoll instead of specifying an existing one:

$volcoll = New-NSVolumeCollection -name mynewvolcoll

New-NSProtectionSchedule -name "mynewschedule" -volcoll_or_prottmpl_type "volume_collection" -period 1 -period_unit "days" -num_retain 16 -volcoll_or_prottmpl_id $volcoll.id

New-NSVolume -name "mynewvolume" -size 1024

Set-NSVolume -name "mynewvolume" -volcoll_id $volcoll.id

Get-NSVolume -name "mynewvolume" | select name,size,volcoll_id

Of course, you can specify much more when creating the volcoll than I've done here, such as snapshot synchronization with vCenter or VSS, replication to a downstream array, etc. 

Cheers!

Julian

stooie2950

Awesome thanks for taking the time to explain.

Stuart

jcates98

Happy to do so! Let me know if you come across anything else that requires a more detailed explanation.

jzygmunt70

I think your list of cmdlets at the beginning of the article got cut off after New-NSPerformancePolicy.  I was really disappointed when I didn't see a cmdlet to create a new volume in the list, but then saw your first example had New-NSVolume.

jcates98

Good catch!  My apologies for the error, and my thanks to you for pointing it out.  I've corrected the original post.  Cheers!

dkhillman41

So I am running into an issue where I need to retain the a snapshot for 12 months and needs to be taken on the last day of every month.  Doesn't seem to be that huge of a problem; however, since Nimble only specifies in days, months, weeks it seems to be an issue.  Normally I would run just a ((get-date -day 1).adddays(-1)).ToShortDateString() to get the last day of the month, but I am unsure how I would translate to Nimble.  Any advice on setting a volume collection to do this?  Thanks

jcates98

Well there's good news and bad news.  The bad news first.  For Nimble schedule objects, the period_unit can be set in minutes, hours, days, or weeks. So the closest we could come with built-in scheduling is every four weeks and well... that's just not what you want in this case.

The good news is that once you've defined a volume collection, you can take unscheduled snapshots of the volume collection using the New-NSSnapshotCollection cmdlet. So, perhaps write a small script that deletes the snapshot collection from a year ago and creates a new one.  You can then run it as a Windows scheduled task that kicks off on the last day of every month.  Perhaps not the ideal solution, but that's one way to go about it.

mahdi_eslami

Hi Julian,

In PowerShell Module published by Justin, we had  Add-NSInitiatorGroupToVolume function.

With Nimble PowerShell Toolkit 1.0 , can you help with Add or remove initiator group to the cloned volume.

Thanks,

jcates98

Hi Mahdi Eslami

The cmdlets you would use in the Nimble PowerShell Toolkit are New-NSAccessControlRecord and Remove-NSAccessControlRecord.  These cmdlets will allow you to map and unmap volumes (including clones) to initiator groups. Example usage is:

-------------------------- EXAMPLE 1 --------------------------

PS C:\>New-NSAccessControlRecord -vol_id 06477237f04e33a565000000000000000000000143 -initiator_group_id 02477237f04e33a56500000000000000000000000e

access_protocol      : iscsi

apply_to             : both

chap_user_id         :

chap_user_name       : *

creation_time        : 4/26/2016 2:53:28 AM

id                   : 0d477237f04e33a565000000000000000000000111

initiator_group_id   : 02477237f04e33a56500000000000000000000000e

initiator_group_name : IG1

last_modified        : 4/26/2016 2:53:28 AM

lun                  : 0

pe_id                :

pe_lun               :

pe_name              :

snap_id              :

snap_name            :

snapluns             :

vol_id               : 06477237f04e33a565000000000000000000000143

vol_name             : siva-vss

Creates a new access control record for voume id 06477237f04e33a565000000000000000000000143 with initiator_group_id 02477237f04e33a56500000000000000000000000e

mahdi_eslami

Appreciate your help!

billfinch131

Hi Julian,

I currently use wildcards in the older powershell cmdlets to retrieve a specific snapshot in this manner:

Get-NSVolume -Name "$ReplVolNameData" | Get-NSSnapShot -SnapName "*$SnapName*" | Select -First 1 | New-NSClone -Name $VolNameData -Verbose

Where $ReplVolNameData is my replicated volume and $SnapName is a search pattern based on the snapshot type and date, eg. "Daily-2016-09-16".  I am trying to port my scripting to the NPT cmdlets and getting errors when attempting to use the new Get-NSSnapShot in this way:

Get-NSSnapShot -vol_name "<MY VOLUME NAME>" -name "*daily-2016-09-14*"

Here is the error returned:

The request could not be understood by the server.Invalid value '*daily-2016-09-14*' specified for the parameter 'name'.

Invoke-RestMethod : The remote server returned an error: (400) Bad Request.

At C:\WINDOWS\System32\WindowsPowerShell\v1.0\Modules\Nimble_PowerShell_ToolKit_1.0.0\NimblePowerShellToolKit.psm1:427 char:20

+         $restOut = Invoke-RestMethod -Uri $uri -Method $action -Headers $header

+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException

    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Since we store 30 days worth of snapshots, we need to be able to filter inline down to the daily snapshot for the volume we wish to clone.  How can we do this in the new NPT setup?

Thanks!

Bill

billfinch131

OK, I figured out how to get what I needed with a "Where" clause like this:

Get-NSSnapShot -vol_name $ReplVolNameDATA | Where {$_.name -like "*$SnapName*"} | New-NSClone -Name $VolNameData -Verbose

Now my issue is with the New-NSClone command.  I get the following error, which seems to indicate that it will not accept pipeline input?

New-NSClone : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

At line:1 char:83

+ ... $SnapName*"} | New-NSClone -Name $VolNameData -Verbose

+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (@{id=0447acd0ea...::22:00:00.000}:PSObject) [New-NSClone], ParameterBindingException

    + FullyQualifiedErrorId : InputObjectNotBound,New-NSClone

Is there a more detailed command line reference that could assist with this?  There seem to be a lot of differences between the original SOAP based cmdlets and this new version, requiring some significant rework to port scripts over.

Thanks!

billfinch131

It seems that in the interim I have answered my own question.  For the record here is the change:

OLD VERSION (Create new clone and add it to the target initiator group, new clone is brought online by default as part of the New-NSClone command)

      #CLONE NEW VOLUME

      Get-NSVolume -Name "$ReplVolNameData" | Get-NSSnapShot -SnapName "*$SnapName*" | Select -First 1 | New-NSClone -Name $VolNameData -Verbose

      #ADD Initiator Group to New VOLUME

      Add-NSInitiatorGroupToVolume -InitiatorGroup $igroup -Volume $VolNameData -Access Volume -Verbose

NEW VERSION (New clone is offline by default and must be brought online)

     #GET Source Snapshot ID

$SnapIDData = Get-NSSnapShot -vol_name $ReplVolNameData | Where {$_.name -like "*$SnapName*"} | Select -ExpandProperty id

     #CREATE New Clone

New-NSClone -base_snap_id $SnapIDData -Name $VolNameData -clone $true

     #GET New Clone ID

$NewCloneIDData = Get-NSVolume -name $VolNameData | SELECT -ExpandProperty id

#GET Initiator Group ID

     $igroupID = Get-NSInitiatorGroup -name $igroup | Select -ExpandProperty id   

     #ADD Initiator Group to New Clone

New-NSAccessControlRecord -vol_id $NewCloneIDData -initiator_group_id $igroupID

#SET New Clone ONLINE

Set-NSvolume -name $VolNameData -online $true -force $true

As you can see, there a quite a few more steps required due to the apparent lack of pipeline support in the new versions of the cmdlets.  Can we add that as a suggestion for future revisions of the tools? :-)

Any thoughts as to easier ways to do this would be very much welcomed!

Thanks!

Bill

pmiller7

Thank you for the ToolKit!  If you follow the instructions as stated, unzipping the file and placing the "Nimble_PowerShell_ToolKit_1.0.0" folder in the WindowsPowerShell\v1.0\Modules folder, it causes the "import-module NimblePowerShellToolkit" command to fail with not found condition.  If you rename the folder from "Nimble_PowerShell_ToolKit_1.0.0" to the same name as the .psm1 file name "NimblePowerShellToolkit" then the command will work without having to specify the full path.  For ease of use, please consider making the distributed folder and file name agree when creating the next update.

kusakr7

Very glad to have PowerShell support, thank you! I've noticed an undesirable behavior with the module when writing scripts that utilize error handling. The module has internal helper functions called "PrintError" and "ExecuteRest" which output exception messages via Write-Host. The use of Write-Host for this causes a frustrating experience when trying to catch errors. Although Write-Host allows the changing of text color, its output goes to a stream which makes it very difficult to capture in a try/catch clause. It's much better to output exceptions to the error stream so errors can be handled by standard PowerShell coding methods. I ended up commenting out the lines in the functions for Write-Host and added a line under each using Write-Error instead. Now error handling works as expected.

kusakr7

Hi Bill,

Not counting the variable declarations, here's one way to accomplish the same in 2 lines.

$replVolName = 'foobar'

$snapName = '20161011'

$newCloneName = 'foobarClone'

$initGroup = 'GroupName'

$newClone = Get-NSSnapShot -vol_name $replVolName | Where {$_.name -like "*$snapName*"} | ForEach-Object {New-NSClone -base_snap_id $_.id -Name $newCloneName -clone $true -online $true}

New-NSAccessControlRecord -vol_id $newClone.id -initiator_group_id (Get-NSInitiatorGroup -name $initGroup).id

setareh1

The toolkit is awesome. It made our life so much easier.

Just I have an issue setting a volume offline using "Set-NSVolume". It gives me an error " The request could not be completed due to a conflict". Here is the whole error that I am getting:

PS> Set-NSVolume -name $extraVolume.name -online $false

The request could not be completed due to a conflict.

Invoke-RestMethod : The remote server returned an error: (409) Conflict.

At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\NimblePowerShellToolkit\NimblePowerShellToolKit.psm1:421 char:20

+         $restOut = Invoke-RestMethod -Uri $uri -Method $action -Body $body -Head ...

+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc

   eption

    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Note: I do not have an issue connecting to the Nsgroup through powershell or setting a volume online but when I want to set it offline it gives me that error!

Would you please help me on this?

Thanks in advance.

chris24

Hello,

Use a defined boolean constraint of 0 should work instead of false. -online 0

Cheers,

Chris

chris24

Hello Julian

Could you provide an example for exporting and then importing the initiator group from one array to another?

Cheers,

Chris

setareh1

Hi Chris,

Thank you for your reply. I have already tried that but with boolean value also the result is the same... same error!

Cheers,

setareh1

Solved 

It is working with "-force 1" : Set-NSVolume -name $extraVolume.name -online $false -force 1

mblumberg16

Hi Chris, looking at the question from a coding point of view is interesting, in the below solution I've decided to approach it with the following method:

Powershell + Rest API.

     With Rest API you need to create the initiator group and add initiators to it later on.

So:

Read each initiator group from array A, create initiator group on array B.

Read each initiator in the above initiator group (Array A), create the initiator into the initiator group on Array B.

This example will work for FC, for ISCSI some values will have to be changed.

###########################

# Enable HTTPS

###########################

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

####################################################################

#Check PowerShell version is greater than 5.8 for convertto JSON

####################################################################

$Pshellversion = $PSVersionTable.PSVersion.Major

if ($Pshellversion -lt 3)

    {

    Write-Host "`nPowerShell version $Pshellversion is not supported, version 3 and above is needed.`n"

    Exit

    }

        else

        {

            Write-Host "`nFound PowerShell version $Pshellversion which is supported, continuing.`n"

        }

###########################

#Convert time

###########################

Function Convert-FromUnixdate ($UnixDate) {

   [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').`

   AddSeconds($UnixDate))

}

#################################

# Connect to Array and Get Token

#################################

$array    = "IP of Array"

$username = "admin"

$password =  "password"

$arrayapiport = ":5392"

try {

         $data = @{

             username = $username

             password = $password

         }

        

         $body = convertto-json (@{ data = $data })

         $uri = "https://" + $array + $arrayapiport + "/v1/tokens"

         $token = Invoke-RestMethod -Uri $uri -Method Post -Body $body

         $token = $token.data.session_token

    }

      catch

        {

          Write-Host "`nCan't connect to $array, check user name and password.`n"

          exit

        }

#################################

# Connect to second Array and Get Token

#################################

$array2    = "IP of Array"

$username2 = "admin"

$password2 =  "password"

$arrayapiport2 = ":5392"

try {

         $data = @{

             username = $username2

             password = $password2

         }

        

         $body2 = convertto-json (@{ data = $data })

         $uri2 = "https://" + $array2 + $arrayapiport2 + "/v1/tokens"

         $token2 = Invoke-RestMethod -Uri $uri2 -Method Post -Body $body2

         $token2 = $token.data.session_token

    }

      catch

        {

          Write-Host "`nCan't connect to $array2, check user name and password.`n"

          exit

        }

#################################

# Start ACL read/copy

#################################

$header = @{ "X-Auth-Token" = $token }

$uri = "https://" + $array + $arrayapiport + "/v1/initiator_groups"

$list = Invoke-RestMethod -Uri $uri -Method Get -Header $header 

$ids = $list.data.id

$ids

foreach ($id in $ids) {

  $header = @{ "X-Auth-Token" = $token }

  $uri = "https://" + $array + $arrayapiport + "/v1/initiator_groups/" + $id

  $uri

  $initiator_groups_details = Invoke-RestMethod -Uri $uri -Method Get -Header $header 

  $initiator_groups_details.data | fl

  Write-Host "Using the following values to create new initiator group"

          $initiator_groups_details.data.name

          $initiator_groups_details.data.access_protocol

          $initiator_groups_details.data.description     

# write new initiator_group - keep ID for future creation.

                $header = @{ "X-Auth-Token" = $token2 }

                $uri = "https://" + $array2 + $arrayapiport2 + "/v1/initiator_groups/"

                $data = @{

                        name = $initiator_groups_details.data.name

                        access_protocol = $initiator_groups_details.data.access_protocol

                        description = "$initiator_groups_details.data.description"

                        }  

                $body = convertto-json (@{ data = $data })

                $result = Invoke-RestMethod -Uri $uri -Method Post -Body $body -Header $header

                $initiator_group_new = $result.data

                $initiator_group_new

# end of write new initiator_group

    $initiator_id = $initiator_groups_details.data.fc_initiators.id

    foreach ($line in $initiator_id) {

    $header = @{ "X-Auth-Token" = $token }

    $uri = "https://" + $array + $arrayapiport + "/v1/initiators/" + $line

    $uri

    $init_details = Invoke-RestMethod -Uri $uri -Method Get -Header $header 

    $init_details.data | fl

        # write new initiator to initiator_group

        $header = @{ "X-Auth-Token" = $token2 }

        $uri = "https://" + $array2 + $arrayapiport2 + "/v1/initiators/"

        $data = @{

                access_protocol = $init_details.data.access_protocol

                initiator_group_id = $iinitiator_group_new.id

                alias =  "$init_details.data.alias"

                wwpn = $init_details.data.wwpn

                }

        $body = convertto-json (@{ data = $data })

        $result = Invoke-RestMethod -Uri $uri -Method Post -Body $body -Header $header

        $initiator_new = $result.data

        $initiator_new

        # finished write new initiator to initiator_group

    }}

Events
See posts for dates
See posts for locations
HPE at 2018 Technology Events
Learn about the technology events where Hewlett Packard Enterprise will have a presence in 2018.
Read more
See posts for dates
Online
HPE Webinars - 2018
Find out about this year's live broadcasts and on-demand webinars.
Read more
View all