{"id":15971,"date":"2011-01-08T00:01:00","date_gmt":"2011-01-08T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/01\/08\/weekend-scripter-use-the-powershell-pipeline-with-data-ontap-powershell-toolkit\/"},"modified":"2011-01-08T00:01:00","modified_gmt":"2011-01-08T00:01:00","slug":"weekend-scripter-use-the-powershell-pipeline-with-data-ontap-powershell-toolkit","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-use-the-powershell-pipeline-with-data-ontap-powershell-toolkit\/","title":{"rendered":"Weekend Scripter: Use the PowerShell Pipeline with Data ONTAP PowerShell Toolkit"},"content":{"rendered":"<p><span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Summary:<\/span><\/b><span style=\"font-size: 10pt\"> The Data ONTAP Windows PowerShell toolkit uses the pipeline to simplify data storage management.<\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">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.<span>&nbsp; <\/span>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: <b>Get-Help<\/b>, <b>Get-Command<\/b> and <b>Get-Member<\/b>. 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.<\/span>\n<span style=\"font-size: 10pt\">With a Windows PowerShell module like NetApp&rsquo;s <a href=\"http:\/\/communities.netapp.com\/community\/interfaces_and_tools\/data_ontap_powershell_toolkit\"><span style=\"color: #0000ff\">Data ONTAP PowerShell Toolkit<\/span><\/a>, 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.<\/span>\n<span style=\"font-size: 10pt\">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:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-Help Set-NaLunSpaceReserved &ndash;Full<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&nbsp;<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&hellip;<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PARAMETERS<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp; <\/span>-Path &lt;String&gt;<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Path to the LUN for which the space reservations need to be set.<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&nbsp;<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Required?<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>true<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Position?<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>1<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Default value<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><b>Accept pipeline input?<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>true (ByValue, ByPropertyName)<\/b><\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Accept wildcard characters?<span>&nbsp; <\/span>false<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&hellip;<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">Note here that the <b>-Path<\/b> parameter to <b>Set-NaLunSpaceReserved<\/b> may be set using pipeline input, either by value or by property name. <b>ByValue<\/b> means that if a string is piped into this cmdlet, it will be assigned directly to <b>-Path<\/b>. <b>ByPropertyName<\/b> means that if any nonstring object is piped in which has a property named <b>Path<\/b>. The value of that property will be assigned to <b>-Path<\/b>.<\/span>\n<span style=\"font-size: 10pt\">We know that <b>Get-NaLun<\/b> returns LUN objects that have a <b>Path<\/b> property. Therefore, we can pipe those objects into <b>Set-NaLunSpaceReserved<\/b> with confidence that each LUN will be identified by its <b>Path<\/b> property:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaLun | Set-NaLunSpaceReserved -Off<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">Of course, unrelated object types could also have a <b>Path<\/b> property. This example works for Windows PowerShell but makes no sense to Data ONTAP:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaSis | Set-NaLunSpaceReserved &ndash;Off<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">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 <b>Get-NaAggr<\/b> or <b>Get-NaVol<\/b> , 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:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaVol *clone | Set-NaVol -Offline<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">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:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaVol | Enable-NaSis | Set-NaSis -Schedule auto | Start-NaSis<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">Similarly, get cmdlets that retrieve various attributes of the principal objects can also accept those as pipeline input:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaLun | Get-NaLunMap<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">And filtering pipeline objects by using <b>Where-Object<\/b> works with all the above:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaAggr | Where-Object {$_.PlexCount -EQ 2} | Start-NaAggrVerify<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">There are a few cases in the Toolkit where it is not obvious, even by inspection of <b>Get-Help<\/b> output, that pipeline input should work.<span>&nbsp; <\/span>For example, <b>Set-NaIgroup<\/b> has a <b>-Name<\/b> parameter but <b>Get-NaIgroup<\/b> returns objects that have the names in a property named <b>InitiatorGroupName<\/b>.<span>&nbsp; <\/span>Yet this example still works, enabling ALUA on all iSCSI igroups:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; Get-NaIgroup | ? {$_.InitiatorGroupType -EQ &#8220;iscsi&#8221;} | Set-NaIgroup -Key alua -Value true<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">The unsung heroes here are parameter aliases on many Toolkit cmdlets, which enable shorthand notation or help with &ldquo;impedance matching&rdquo; within the pipeline. Windows PowerShell&rsquo;s <b>Get-Help<\/b> cmdlet does not display parameter aliases, but something such as this will reveal them:<\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:&gt; (gcm Set-NaIgroup).Parameters | % { $_.Values | ? { $_.Aliases.Count -GT 0 } | select Name, Aliases } | ft &ndash;Autosize<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Aliases<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;-<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Igroup, InitiatorGroupName}<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Key<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Attribute}<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Controller<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Filer, Server}<\/span><\/span><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">&hellip;<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">The Toolkit&rsquo;s cmdlet help contains real usage examples for almost every cmdlet. This includes many that demonstrate use within the pipeline. Just use <b>Get-Help<\/b> <b>-Examples<\/b> or <b>Show-NaHelp<\/b> to see those.<\/span>\n<span style=\"font-size: 10pt\">Here are some other examples to get you thinking about how to use the pipeline.<\/span>\n<b><span style=\"font-size: 10pt\">Disable quotas on volume &#8216;vol0&#8217; and show the new status:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Disable-NaVolQuota vol0 | Get-NaVolQuotaStatus<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Get all valid licenses and store in an XML file:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaLicense | ? {$_.Code -ne $null} | Export-Clixml c:OntapLicenses.xml<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Add all licenses that were previously written to an XML file:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Import-Clixml C:OntapLicenses.xml | Add-NaLicense<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">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:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaLun \/vol\/vol2\/lun2 | Get-NaLunMap | ForEach-Object {$_.Initiators} | Get-NaLunMapByInitiator<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">List the priority schedule for volumes from the pipeline:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaVol vol0 vol1 | Get-NaPriorityVolume<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Get environmental information for all disk shelves:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaShelf | Get-NaShelfEnvironment<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Abort all Snapmirror transfers:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaSnapmirror | Invoke-NaSnapmirrorAbort<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Set the specified Snapmirror to synchronous mode:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaSnapmirror benson:dunn_vol2_mirror | Set-NaSnapmirrorSyncSchedule<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Set the snapshot reserve on volume &#8216;vol0&#8217; to 10% and print the result:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Set-NaSnapshotReserve vol0 10 | Get-NaSnapshotReserve<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Copy the snapshot schedule from volume &#8216;vol2&#8217; to all volumes:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaVol | Set-NaSnapshotSchedule -Schedule ( Get-NaSnapshotSchedule vol2 ) | Get-NaSnapshotSchedule<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Begin updating firmware on all disks in shelf 1:<\/span><\/b><\/p>\n<p class=\"CodeBlock\" style=\"margin: 4pt 0in 7pt 0.5in\"><span style=\"font-size: 10pt\"><span style=\"font-family: Lucida Sans Typewriter\">Get-NaDisk | where {$_.Shelf -eq 1} | Start-NaDiskUpdate<\/span><\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">All potentially destructive cmdlets in the Toolkit support Windows PowerShell&rsquo;s <b>-WhatIf<\/b> 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.<\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<span style=\"font-size: 10pt\">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.<\/span>\n<span style=\"font-size: 10pt\">I invite you to follow me on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\"><span style=\"color: #0000ff\">Twitter<\/span><\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\"><span style=\"color: #0000ff\">Facebook<\/span><\/a>. If you have any questions, send email to me at <a target=\"_blank\" href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><span style=\"color: #0000ff\">scripter@microsoft.com<\/span><\/a> or post them on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\"><span style=\"color: #0000ff\">Official Scripting Guys Forum<\/span><\/a>. See you tomorrow. Until then, peace.<\/span>\n<span style=\"font-size: 10pt\">&nbsp;<\/span>\n<b><span style=\"font-size: 10pt\">Ed Wilson, Microsoft Scripting Guy<\/span><\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Summary: The Data ONTAP Windows PowerShell toolkit uses the pipeline to simplify data storage management. &nbsp; 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 [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[213,56,3,12,61,45],"class_list":["post-15971","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-clinton-knight","tag-guest-blogger","tag-scripting-guy","tag-storage","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Summary: The Data ONTAP Windows PowerShell toolkit uses the pipeline to simplify data storage management. &nbsp; 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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/15971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=15971"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/15971\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=15971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=15971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=15971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}