Microsoft Virtualization Discussions

Netapp Powershell Report Script for Systeminfo

sudoline
8,946 Views

Hi All,

 

I need some help for a powershell script. I like to do a report for some Netapp Clusters to receive Information about Name,Ip,Location, Nodes, Nodes IP mgmt ip , aso. and all helpfull stuff

How can I extract this data, and the best way would be to do this in a biger foreach loop with multible clusters..

 

$myCol = @()

Connect-NaController $clusters -Credential $ControllerCredential


[System.Array]$Nodes = Get-NcNode
Foreach($Node in $Nodes){

$x = "" | Select Node,Model,NodeSerialNumber,NodeSystemId,Version,IP

$x.Node = $Node.Node
$x.model = $Node.NodeModel
$x.NodeSerialNumber = $Node.NodeSerialNumber
$x.NodeSystemId = $Node.NodeSystemId
$x.Version = $Node.ProductVersion.Split(":")[0]
$x.IP = $Node | Get-NcNetInterface -Role node_mgmt | select Address


$mycol += $x

}

 

$mycol

1 ACCEPTED SOLUTION

donny_lang
8,934 Views

Yep, that is basically how I would do it for multiple clusters (just another foreach loop that will loop through all nodes in all clusters). If you have huge clusters with a lot of nodes, you may want to look into the -Query parameter for Get-NcNode, which can help limit the amount of properties that you collect (since you are filtering it with Select-Object later in the code anyways) and should help your code run faster. 

 

When I ran your code in my lab, the line that returns the node management interface returned the IPs of all the node's node-mgmt IPs for each entry in the output, so I rewrote it - other than that, everything looks like it worked as expected! 

 

$myCol = @()
Connect-NcController $clusters -Credential $ControllerCredential
[System.Array]$Nodes = Get-NcNode

Foreach($Node in $Nodes){
$x = "" | Select Node,Model,NodeSerialNumber,NodeSystemId,Version,IP

$x.Node = $Node.Node
$x.model = $Node.NodeModel
$x.NodeSerialNumber = $Node.NodeSerialNumber
$x.NodeSystemId = $Node.NodeSystemId
$x.Version = $Node.ProductVersion.Split(":")[0]
$x.IP = Get-NcNetInterface -Role node_mgmt | ? HomeNode -eq $node.Node | select Address
$mycol += $x
}

$mycol

 

As to how to extract it, you could export the data to a CSV with Export-Csv, format the output as a table (or HTML, or an email attachment) and send it with Send-MailMessage. Lots of options there. 

View solution in original post

8 REPLIES 8

donny_lang
8,935 Views

Yep, that is basically how I would do it for multiple clusters (just another foreach loop that will loop through all nodes in all clusters). If you have huge clusters with a lot of nodes, you may want to look into the -Query parameter for Get-NcNode, which can help limit the amount of properties that you collect (since you are filtering it with Select-Object later in the code anyways) and should help your code run faster. 

 

When I ran your code in my lab, the line that returns the node management interface returned the IPs of all the node's node-mgmt IPs for each entry in the output, so I rewrote it - other than that, everything looks like it worked as expected! 

 

$myCol = @()
Connect-NcController $clusters -Credential $ControllerCredential
[System.Array]$Nodes = Get-NcNode

Foreach($Node in $Nodes){
$x = "" | Select Node,Model,NodeSerialNumber,NodeSystemId,Version,IP

$x.Node = $Node.Node
$x.model = $Node.NodeModel
$x.NodeSerialNumber = $Node.NodeSerialNumber
$x.NodeSystemId = $Node.NodeSystemId
$x.Version = $Node.ProductVersion.Split(":")[0]
$x.IP = Get-NcNetInterface -Role node_mgmt | ? HomeNode -eq $node.Node | select Address
$mycol += $x
}

$mycol

 

As to how to extract it, you could export the data to a CSV with Export-Csv, format the output as a table (or HTML, or an email attachment) and send it with Send-MailMessage. Lots of options there. 

sudoline
8,925 Views

hey thanks

that helps!

 

i'm struggling now with the 2én  loop

 

$clusters = "cl01" ,"cl02"

foreach($cluster in $clusters)
{

Connect-NcController $cluster -Credential $ControllerCredential
[System.Array]$Nodes = Get-NcNode

$myCol = @()
Foreach($Node in $Nodes){
$x = "" | Select Cluster,ClusterIP,Node,NodeIP,Location, NodeSerialNumber,NodeSystemId,Model,Version

$x.Cluster = $Node.ncController.Name
$x.ClusterIP = $Node.ncController.Address
$x.Node = $Node.Node
$x.NodeIP = Get-NcNetInterface -Role node_mgmt | ? HomeNode -eq $node.Node | select -ExpandProperty address
$x.model = $Node.NodeModel
$x.Location = $Node.NodeLocation
$x.NodeSerialNumber = $Node.NodeSerialNumber
$x.NodeSystemId = $Node.NodeSystemId
$x.Version = $Node.ProductVersion.Split(":")[0]

}
$mycol += $x


}
$mycol

donny_lang
8,917 Views

You have the creation of the empty array inside the foreach loop so it is re-creating it each time it loops:

$myCol = @()

If you move it outside of the loop (to the 2nd line of your code, for example) the output will look better. 

sudoline
8,911 Views

yeh you right.

 

do you know how to pimp the script and get more information for each node like

dns settings

gateway

lifs

aggregates

 

donny_lang
8,905 Views

DNS settings:

This is per-SVM - Use "Get-NcNetDns"

Gateway:

Use "Get-NcNetRoute" 

LIFs:

"Get-NcNetInterface" will return lots of LIF information

Aggregates:

"Get-NcAggr" 

 

You may already know this, but just in case someone else takes a look at this thread, here are two commands/tricks that are super useful when looking for new cmdlets or trying to get very specific data from them: 

 

1. Get-Member 

You can pipe a command to Get-Member to see all of the available properties that are returned by the cmdlet. This helps if you want to set up a query or a select statement to only return relevant data.

2. Get-Command 

If I'm searching through a giant module (like the PSTK with 2300+ cmdlets) to see if I can get a particular piece of data from it, I will use something like "Get-Command -Module DataONTAP -Name *route*" to get an idea if there are commands that might be a good fit for what I'm looking for and at least help me narrow the search. 

James_BGRS
7,233 Views

I have modified the script a little bit and make it working!!!

#Get-NetAppSystemInfo2.ps1
$ControllerCredential = Get-Credential
$clusters = 'cluster01',''cluster02',''cluster03',''cluster04'

 

$myCol = @()
foreach($cluster in $clusters)
{

Connect-NcController $cluster -Credential $ControllerCredential
[System.Array]$Nodes = Get-NcNode

 

Foreach($Node in $Nodes){

$x = "" | Select Cluster,ClusterIP,Node,NodeIP,Location, NodeSerialNumber,NodeSystemId,Model,Version

$x.Cluster = $Node.ncController.Name
$x.ClusterIP = $Node.ncController.Address
$x.Node = $Node.Node
$x.NodeIP = Get-NcNetInterface -Role node_mgmt | ? HomeNode -eq $node.Node | select -ExpandProperty address
$x.model = $Node.NodeModel
$x.Location = $Node.NodeLocation
$x.NodeSerialNumber = $Node.NodeSerialNumber
$x.NodeSystemId = $Node.NodeSystemId
$x.Version = $Node.ProductVersion.Split(":")[0]
$mycol += $x
}

}
$mycol

James@Toronto

James, the script error at 

} | Select-Object Name, Volume, Created, "Total "
Get-NcSnapshot : The remote server returned an error: (400) Bad Request.
At line:2 char:14
+ $snapshots = Get-NcSnapshot | Select-Object Name, Volume, Created, To ...
+ ~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-NcSnapshot], WebException
+ FullyQualifiedErrorId : System.Net.WebException,DataONTAP.C.PowerShell.SDK.Cmdlets.Snapshot.GetNcSnapshot

Add-Member : Cannot bind argument to parameter 'InputObject' because it is null.
At line:27 char:6
+ $_ | Add-Member -MemberType NoteProperty -Name "Total " -Value (Conve ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Add-Member], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddMemberCommand

GidonMarcus
8,905 Views

Hi.

 

First notice that you are using both the NA and NC cmdlets, is you using ONTAP 9/Cluster mode, use NC only.

 

Now to fully enjoy the power of PowerShell I would try to avoid recreating new objects, and avoid loops where I can, this allows PowerShell to do it's magic, and use parallelism when issuing a command (depend on the developer of the cmdlet).

 

The way I did the same script:

$ControllerCredential = Get-Credential
$clustersNames = 'cluster1','cluster2' 
$clustersObj = connect-NcController $clustersNames -Credential $ControllerCredential
$MgmtLifObj = Get-NcNetInterface -Controller $clustersObj -Role node_mgmt
$NodesObj = Get-NcNode -Controller $clustersObj
$NodesObj | select Node,Model,NodeSerialNumber,NodeSystemId,Version,@{Label="IP";expression={($MgmtLifObj | ? CurrentNode -eq $_.Node).Address}} | ft 

 

Just for fun I run both scripts for one cluster in Measure-command {....} | ft TotalMilliseconds . The version above did it in 620 Mill, and the one you provided in 733. Not a big difference and I don't know what exactly took there longer (running Get-NcNetInterface twice, building new arrays etc) - but was interesting to check before I commented here.

 

To be honest, I might have taken two different approaches altogether.

1. try to use ONTAP rest API instead of the PS Module, I didn't see NetApp saying it yet - but I think that will be the standard way going forward, and learning how to fiddle with raw rest API's (in any scripting language) will do very good for your general non-vendor-specific skillset, and technically allow you to use more standardized tools and deployment environments where the ONTAP PS Module cannot be installed (Containers, PS for Linux, CI/CD tools).

 

2. if you have OCUM/AIUM - use that rest API for faster results (as it's already stores all the clusters data), and a bit more safe as you reading read-only source rather a production cluster .

https://docs.netapp.com/ocum-97/index.jsp?topic=%2Fcom.netapp.doc.onc-um-api-dev%2FGUID-6C4A78C2-9F22-4723-B190-FA227CD067FD.html&cp=2_4_2_0

Gidi Marcus (Linkedin) - Storage and Microsoft technologies consultant - Hydro IT LTD - UK
Public