Weekend Scripter: Use the PowerShell Pipeline with Data ONTAP PowerShell Toolkit

  Summary: The Data ONTAP Windows PowerShell toolkit uses the pipeline to simplify data storage management.   Microsoft Scripting Guy Ed Wilson here. Today we have a guest blogger, Dr. Clinton Knight, from NetApp and the Author of Data ONTAP PowerShell Toolkit. I know not everyone has a NETAPP device and this will not be helpful to all readers but then again I blog a lot about Active Directory and other things that not everyone uses.  The really cooI thing about Windows PowerShell as a management foundation, is that it enables you to perform management tasks without having to learn new tools. Therefore, if you know Windows PowerShell and you understand how to configure a NetApp device, you already know how to use the toolkit. The command discovery techniques are the same: Get-Help, Get-Command and Get-Member. I hope that you will benefit from Dr. Knights information (it is worth a skim even if you do not have such a device on your network). Without further delay, I will turn the keyboard to Dr. Knight. With a Windows PowerShell module like NetApp’s Data ONTAP PowerShell Toolkit, it is natural to ask how its cmdlets can best utilize the Windows PowerShell pipeline. But with over 400 cmdlets in that module, it is difficult to know where to begin chaining things together. This post should help understand how to get started. Many Windows PowerShell cmdlets accept input via the pipeline, so let us begin by examining how pipeline objects are mapped to cmdlet parameters using a Toolkit example:

PS C:> Get-Help Set-NaLunSpaceReserved –Full



    -Path <String>

        Path to the LUN for which the space reservations need to be set.


        Required?                    true

        Position?                    1

        Default value

        Accept pipeline input?       true (ByValue, ByPropertyName)

        Accept wildcard characters?  false

  Note here that the -Path parameter to Set-NaLunSpaceReserved may be set using pipeline input, either by value or by property name. ByValue means that if a string is piped into this cmdlet, it will be assigned directly to -Path. ByPropertyName means that if any nonstring object is piped in which has a property named Path. The value of that property will be assigned to -Path. We know that Get-NaLun returns LUN objects that have a Path property. Therefore, we can pipe those objects into Set-NaLunSpaceReserved with confidence that each LUN will be identified by its Path property:

PS C:> Get-NaLun | Set-NaLunSpaceReserved -Off   Of course, unrelated object types could also have a Path property. This example works for Windows PowerShell but makes no sense to Data ONTAP:

PS C:> Get-NaSis | Set-NaLunSpaceReserved –Off   So is there any logical organization in the Toolkit that lets us make assumptions about how to best leverage the pipeline? Absolutely! The Toolkit defines a number of principal data types that represent Data ONTAP constructs, such as aggregates, volumes, qtrees, or LUNs. Each of these has a get cmdlet, such as Get-NaAggr or Get-NaVol , that writes those objects to the pipeline. So it is reasonable (and correct!) to expect that any set cmdlets that manipulate those objects should accept pipeline input from the corresponding getter:

PS C:> Get-NaVol *clone | Set-NaVol -Offline   Additionally, the setter cmdlets that accept pipeline input typically perform their function, re-query Data ONTAP, and write the updated representation of those same objects back out to the pipeline. This enables chaining of multiple cmdlets, such as in this example that configures and starts deduplication on every volume on a controller:

PS C:> Get-NaVol | Enable-NaSis | Set-NaSis -Schedule auto | Start-NaSis   Similarly, get cmdlets that retrieve various attributes of the principal objects can also accept those as pipeline input:

PS C:> Get-NaLun | Get-NaLunMap   And filtering pipeline objects by using Where-Object works with all the above:

PS C:> Get-NaAggr | Where-Object {$_.PlexCount -EQ 2} | Start-NaAggrVerify   There are a few cases in the Toolkit where it is not obvious, even by inspection of Get-Help output, that pipeline input should work.  For example, Set-NaIgroup has a -Name parameter but Get-NaIgroup returns objects that have the names in a property named InitiatorGroupName.  Yet this example still works, enabling ALUA on all iSCSI igroups:

PS C:> Get-NaIgroup | ? {$_.InitiatorGroupType -EQ “iscsi”} | Set-NaIgroup -Key alua -Value true   The unsung heroes here are parameter aliases on many Toolkit cmdlets, which enable shorthand notation or help with “impedance matching” within the pipeline. Windows PowerShell’s Get-Help cmdlet does not display parameter aliases, but something such as this will reveal them:

PS C:> (gcm Set-NaIgroup).Parameters | % { $_.Values | ? { $_.Aliases.Count -GT 0 } | select Name, Aliases } | ft –Autosize

Name            Aliases

—-            ——-

Name            {Igroup, InitiatorGroupName}

Key             {Attribute}

Controller      {Filer, Server}

  The Toolkit’s cmdlet help contains real usage examples for almost every cmdlet. This includes many that demonstrate use within the pipeline. Just use Get-Help -Examples or Show-NaHelp to see those. Here are some other examples to get you thinking about how to use the pipeline. Disable quotas on volume ‘vol0’ and show the new status:

Disable-NaVolQuota vol0 | Get-NaVolQuotaStatus   Get all valid licenses and store in an XML file:

Get-NaLicense | ? {$_.Code -ne $null} | Export-Clixml c:OntapLicenses.xml   Add all licenses that were previously written to an XML file:

Import-Clixml C:OntapLicenses.xml | Add-NaLicense   For a given LUN, get the initiator(s) it is mapped to and then list all other LUNs that are mapped to the same initiators:

Get-NaLun /vol/vol2/lun2 | Get-NaLunMap | ForEach-Object {$_.Initiators} | Get-NaLunMapByInitiator   List the priority schedule for volumes from the pipeline:

Get-NaVol vol0 vol1 | Get-NaPriorityVolume   Get environmental information for all disk shelves:

Get-NaShelf | Get-NaShelfEnvironment   Abort all Snapmirror transfers:

Get-NaSnapmirror | Invoke-NaSnapmirrorAbort   Set the specified Snapmirror to synchronous mode:

Get-NaSnapmirror benson:dunn_vol2_mirror | Set-NaSnapmirrorSyncSchedule   Set the snapshot reserve on volume ‘vol0’ to 10% and print the result:

Set-NaSnapshotReserve vol0 10 | Get-NaSnapshotReserve   Copy the snapshot schedule from volume ‘vol2’ to all volumes:

Get-NaVol | Set-NaSnapshotSchedule -Schedule ( Get-NaSnapshotSchedule vol2 ) | Get-NaSnapshotSchedule   Begin updating firmware on all disks in shelf 1:

Get-NaDisk | where {$_.Shelf -eq 1} | Start-NaDiskUpdate   All potentially destructive cmdlets in the Toolkit support Windows PowerShell’s -WhatIf mechanism, and more will over time. So, do not hesitate to experiment with piping Toolkit objects between cmdlets. The object-oriented pipeline is part of what sets Windows PowerShell apart from other command shells, and the Data ONTAP PowerShell Toolkit was designed from the start to support it.   I want to thank Dr. Knight for sharing with us today. Come back tomorrow when Sean Kearney will be the guest blogger on XML. The post is way cool, and you will really enjoy it. I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.   Ed Wilson, Microsoft Scripting Guy


Comments are closed. Login to edit/delete your existing comments