Microsoft Virtualization Discussions

NetApp PowerShell Toolkit 4.5P1 released!

Kartik_Gupta

Dear PowerShell community,


We are glad to announce the release of  NetApp PowerShell Toolkit version 4.5P1 This unified release has enhancements for Data ONTAP module. In this release we have made fixes for following two DataONTAP PowerShell toolkit cmdlets.

1) Invoke-NcSsh   2) Invoke-NaSsh

Prerequisites:- The user needs to install Putty of version "putty-64bit-0.70-installer" on the system from where this cmdlet is being executed.
 

ONTAP PowerShell Module:
The latest release adds upto 2170 cmdlets and provides maximum API coverage for ONTAP 9.3 and is backward compatible with previous ONTAP releases.

SANtricity PowerShell Toolkit
The SANtricity PowerShell module supports more than 300 cmdlets, enabling the storage administration of NetApp E-Series storage systems and EF-Series all-flash arrays.

 

Download the PowerShell Toolkit 4.5P1 from here


Regards,
NetApp PowerShell Toolkit Team

26 REPLIES 26

Tas

That's great, but my question is why are you using Putty and not the Windows OpenSSH?  This would be extremely usefull in closed environments, requiring FIPS-140-2 certificated OS's.

DevoidB

Hello,

 

Could you elaborate on "Prerequisites:- The user needs to install Putty of version "putty-64bit-0.70-installer" on the system from where this cmdlet is being executed."

 

Assuming a default install path for the module "C:\Program Files (x86)\NetApp\NetApp PowerShell Toolkit\Modules\DataONTAP" where would I need to point my putty-64bit-0.70-installer.msi towards in order for the invoke-ncssh command to actually be able to use it?

 

I am receiving the following error after attempting to install putty in both default location as well as under the above default module location.

 

Invoke-NcSsh : The system cannot find the file specified

 

At line:1 char:1

+ Invoke-NcSsh "set adv -c off; statistics show-periodic -iterations 1"

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

+ CategoryInfo : NotSpecified: (:) [Invoke-NcSsh], Win32Exception

+ FullyQualifiedErrorId : System.ComponentModel.Win32Exception,DataONTAP.C.PowerShell.SDK.Cmdlets.Toolkit.Ssh.InvokeNcSsh

 

DevoidB

Just and update to this post. I was able to complete the invoke-ncssh command by making sure that I was running powershell as administrator as well as copying plink.exe was copied into my module install path (C:\Program Files (x86)\Netapp\NetApp PowerShell Toolkit\Modules\DataONTAP). This returned the output that I was looking for!

Girton

One issue I encountered on W2K12R2, even after installing Putty 64-bit V0.70, was that PowerShell kept saying:

     Please install putty (version putty-64bit-0.70) on your machine to use this cmdlet.

 

I used SysInternal's 'Procmon.exe' utility to monitor PowerShell's access to the registry, and I saw that it was looking for this registry key:
   HKCU\SOFTWARE\SimonTatham\PuTTY64

 

It turned out that my W2K12R2 server didn't have a registry key called 'PuTTY64', it had 'PuTTY'.  I added '64' to the registry key, so it looked like 'PuTTY64', and then the InovkeNcSsh cmdlet worked like it was supposed to.

 

I suspect that I had a 32-bit version of PuTTY installed prior to installing the 64-bit version, and the registry key didn't get updated to 'PuTTY64', since it already existed.

 

I made sure that the permission were as described elsewhere in the thread:

   All application packages: Full Control
   Users (of the local machine your on): Full Control

 

I hope that this information helps others who are trying to get the InovkeNcSsh cmdlet to work.

 

twitchyarby

Is Powershell Core compatibility anywhere on the development roadmap?

asulliva

Hello @twitchyarby,

 

If having the PSTK work with PowerShell Core is something you're interested in, please reach out to me directly (my communities username at netapp.com) so that we can track the request.

 

Thank you!

 

Andrew

If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

garyfritz

I tried to reply to asulliva@netapp.com to register interest in Core, but his address doesn't work.  NetApp folks, is there someone else who is monitoring this now?

jim_ctr_merrell

I am in the same boat.   Worked in 9.1p15.  Broken in 9.5p2.  Running Putty 0.71 64-bit.   Running powershell "as administrator" and setting the reg keys don't work.   I'm getting:

 

invoke-ncssh : An established connection was aborted by the software in your host machine.

Here is a complete list of steps I have documented in order to get invoke-ncssh to work:

 

1) Run Powershell v5.x or higher
2) Install only the newest Powershell tools from Netapp (=> 9.x)

3) Install putty release 0.72 or newer

4) Add reg keys for (copy from valid source):
     [HKEY_CURRENT_USER\Software\SimonTatham]
     [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY]
     [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY64]
5) Add the user to "full" control of the Putty reg keys
6) Launch PS "As Administrator" ( start-process powershell -verb RunAs )
7) Connect to the Netapp with a local account, not an Active Directory Account

 

Tas

Can I beseech someone at NetApp to please ask the developers consider using MS OpenSSH instead of Putty?  Not only will it then not require non-Windows utilities, but it will also be FIPS-140 compliant.

Please?

himal123

It worked after installing putty 64 bit, 

 

But,  while executing that version command for one host,  the black-screen cmd command promt window opened and - may be it ran from there and closed and I got output, 

 

Now, what if , if I have 50 controllers - clusters,  which I run in for each host loop,  does it needs to open that black cmd window 50 times or it will remain open till all those 50s are executed  ?

 

 

PS C:\Windows\system32> Get-Module

 

ModuleType Version Name ExportedCommands

---------- ------- ---- ----------------

Script 1.0.0.0 ISE {Get-IseSnippet, Import-IseSnippet, New-IseSnippet}

Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...}

Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...}

 

 

PS C:\Windows\system32> import-module dataontap

PS C:\Windows\system32> Connect-NcController 192.168.163.135

Name Address Vserver Version

---- ------- ------- -------

192.168.163.135 192.168.163.135 NetApp Release 9.3RC1: Wed Nov 01 07:34:37 UTC 2017

 

 

PS C:\Windows\system32> Invoke-NcSsh version

NetApp Release 9.3RC1: Wed Nov 01 07:34:37 UTC 2017

 

PS C:\Windows\system32>

 

asulliva

Hello @himal123,

 

The window that opens is Plink running to connect to the ONTAP system and execute the command.  It will disappear when the command is finished.  Unless you're executing multiple Invoke-NcSsh commands in parallel, then there will only be one at a time.

 

One thing to note, the new Invoke-NcSsh is much slower than previously.  You can regain much of that speed by manually executing Plink in your PowerShell script (this also doesn't require the PowerShell script to be elevated), however doing so means that you need to have the credentials in clear text which is not ideal for many.

 

Andrew

If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

DonnaLou

Hello,

I am getting that "established connection was aborted by software in your host machine" too.  Interestingly enough, I ONLY GET THAT ERROR when trying to run invoke-ncssh within a WFA workflow.  Using the same command(s) via powershell manually, it works ok.

 

I've confirmed that the WFA server has the registry settings for SimonTatham changed, .NET 4.5.2+, WindowsPowerShell 3.0+, Powershell Toolkit 4.5P1, and Putty 0.70.

 

Please help!

 

-Donna

mbeattie

Hi Donna,

 

You can use Invoke-NcSystemApi as an alternative to Invoke-NcSsh to ensure you connect via HTTPS instead of SSH. Here is a WFA code example. Modify the command to meet your requirements.

 

Param(
   [Parameter(Mandatory=$True, HelpMessage="Source Cluster")]
   [String]$SourceCluster,
   [Parameter(Mandatory=$True, HelpMessage="Destination Cluster")]
   [String]$DestinationCluster,
   [Parameter(Mandatory=$True, HelpMessage="Source Vserver")]
   [String]$SourceVserver,
   [Parameter(Mandatory=$True, HelpMessage="Destination Vserver")]
   [String]$DestinationVserver
) 
#'------------------------------------------------------------------------------
#'Connect to the cluster.
#'------------------------------------------------------------------------------
Connect-WfaCluster $SourceCluster
[String]$command = "Get-NcSnapmirror -DestinationCluster $DestinationCluster -SourceVserver $SourceVserver -DestinationVserver $DestinationVserver -ErrorAction Stop"
Try{
   $vsm =  Invoke-Expression -Command $command -ErrorAction Stop
   Get-WFALogger -Info -Message "Executed Command`: $command"
   Get-WFALogger -Info -Message "Enumerated SnapMirror Relationships for vserver ""$DestinationVserver"" on cluster ""$DestinationCluster"""
}Catch{
   Get-WFALogger -Error -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message)
   Throw "Failed enumerating SnapMirror Relationships for vserver ""$DestinationVserver"" on cluster ""$DestinationCluster"""
}
If($vsm -and $vsm.Status -eq "transferring"){
   Throw "Cannot create relationship as there is some volumes currently transferring"
}
#'------------------------------------------------------------------------------
#'Create SnapMirror and preserve identity for onbox SVMDR.
#'------------------------------------------------------------------------------
$command = @("snapmirror", "create", "-source-path", "$DestinationVserver`:", "-destination-path", "$SourceVserver`:", "-identity-preserve true")
Try{
   $api = $("<system-cli><args><arg>"+($command -join "</arg><arg>")+"</arg></args></system-cli>")
   Get-WFALogger -Info -Message "Command: $api"
   $output = Invoke-NcSystemApi -Request $api -ErrorAction Stop
   Get-WFALogger -Info -Message  $("Command output: '" + $res.results."cli-output" + "'. Result value: " + $res.results."cli-result-value")
   If($output.results."cli-result-value" -ne 1){
      Throw $("snapmirror create failed: "+ $output.results."cli-output")
   }
}Catch{
   Get-WFALogger -Error -Message $("Failed Executing Command`: $command. Error " + $_.Exception.Message)
   Throw "Failed invoking the snapmirror create command for destinationPath ""$DestinationVserver`:"""
}
#'------------------------------------------------------------------------------ 

Just an example but you get the idea. Hope that helps

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

DonnaLou

Hi Matt,

I can get the sample code using ncsystem-api  to work from powershell.  From WFA, I get the message "data at the root level is invalid".  Any ideas?  

 

I really appreciate your help,

Donna

mbeattie

Hi Donna,

 

Rather than troubleshoot the issue with the previous example code (which i hadn't tested), here is another code example using Invoke-NcSystemApi as an alternative to using Invoke-NcSsh

The code below enables you to show or modify the ontapi limits for a cluster. EG

 

 

 

cluster1::*> set diag;system ontapi limits show

Monitor Mode   Max Run   Max Reply
                Time        Size
------------- ---------- ---------
silent         120000     20

cluster1::*> set diag;system ontapi limits modify -max-reply-size 50

If you wanted to automate the above process (WITHOUT relying on "Invoke-NcSsh") then the following WFA command code enables you to do that using "Invoke-NcSystemApi"

 

 

 

 

Param(
   [Parameter(Mandatory=$True, HelpMessage="The cluster name or IP Address")]
   [String]$Cluster,
   [Parameter(Mandatory=$False, HelpMessage="The ontapi monitor mode. Valid values are 'off', 'silent' or 'log'")]
   [ValidateSet("off","silent","log","")]
   [String]$MonitorMode,
   [Parameter(Mandatory=$False, HelpMessage="The maximum ontapi runtime")]
   [ValidateRange(0,1000000)]
   [Int]$MaxRunTime,
   [Parameter(Mandatory=$False, HelpMessage="The maximum ontapi reply size")]
   [ValidateRange(0,1000)]
   [Int]$MaxReplySize
) 
#'------------------------------------------------------------------------------
Function Invoke-OntapiLimits{
   Param(
      [Parameter(Mandatory=$True, HelpMessage="The cluster name or IP Address")]
      [String]$Cluster,
      [Parameter(Mandatory=$True, HelpMessage="The CLI command")]
      [Array]$Command,
      [Parameter(Mandatory=$True, HelpMessage="Specifies if the ontapi limits are added as WFA return paramaters")]
      [Bool]$AddReturnParamaters
   )
   Try{
      $api = $("<system-cli><args><arg>" + ($command -join "</arg><arg>") + "</arg></args></system-cli>")
      Get-WFALogger -Info -Message $("Executed Command`: " + $([String]::Join(" ", $command)))
      $output = Invoke-NcSystemApi -Request $api -ErrorAction Stop
      #'------------------------------------------------------------------------
      #'Format the command output if the command result was sucessful.
      #'------------------------------------------------------------------------
      If($output.results."cli-result-value" -eq 1){
         [Array]$lines    = $output.results."cli-output".Trim().Split("`n")
         [String]$result  = $lines[$lines.GetUpperBound(0)]
         [String]$result  = $($result -Replace("\s+", " ")).Trim();
         [Array]$elements = $result.Split(" ")
         If($elements.Count -ne 3){
            Throw "Invalid command output"
         }Else{
            [String]$ontapiMonitorMode = $elements[0]
            [Int]$ontapiMaxRunTime     = $elements[1]
            [Int]$ontapiMaxReplySize   = $elements[2]
         } 
         Get-WFALogger -Info -Message "ontapi monitor-mode`: $ontapiMonitorMode"
         Get-WFALogger -Info -Message "ontapi max-run-time`: $ontapiMaxRunTime"
         Get-WFALogger -Info -Message "ontapi max-reply-size`: $ontapiMaxReplySize"
      }
   }Catch{
      #'------------------------------------------------------------------------
      #'Format the command output if the command result was unsucessful.
      #'------------------------------------------------------------------------
      If($output.results."cli-result-value" -ne 1){
         [Array]$lines    = $output.results."cli-output".Trim().Split("`n")
         [String]$result  = $lines[$lines.GetUpperBound(0)]
         [String]$result  = $($result -Replace("\s+", " ")).Trim();
         [Array]$elements = $result.Split(" ")
         Get-WFALogger -Error -Message  "Command error output`:"
         ForEach($element In $elements){
            Get-WFALogger -Error -Message $element
         }
         Get-WFALogger -Error -Message $("Failed Executing Command`: " + $([String]::Join(" ", $command)))
         Return $False;
      }
   }
   #'---------------------------------------------------------------------------
   #'Set the ontapi limits as return parameters if required.
   #'---------------------------------------------------------------------------
   If($AddReturnParamaters){
      If($ontapiMonitorMode){
         Add-WfaWorkflowParameter -Name "monitor_mode" -Value $ontapiMonitorMode -AddAsReturnParameter $True
         Get-WFALogger -Info -Message "Added value for WFA return parameter name ""monitor_mode"" as ""$ontapiMonitorMode"""
      }
      If($ontapiMaxRunTime){
         Add-WfaWorkflowParameter -Name "max_run_time" -Value $ontapiMaxRunTime -AddAsReturnParameter $True
         Get-WFALogger -Info -Message "Added value for WFA return parameter name ""max_run_time"" as ""$ontapiMaxRunTime"""
      }
      If($ontapiMaxReplySize){
         Add-WfaWorkflowParameter -Name "max_reply_size" -Value $ontapiMaxReplySize -AddAsReturnParameter $True
         Get-WFALogger -Info -Message "Added value for WFA return parameter name ""max_reply_size"" as ""$ontapiMaxReplySize"""
      }
   }
   Return $True;
}#End Function
#'------------------------------------------------------------------------------
#'Validate input paramaters to determine if the command should modify or enumerate the ontapi limits.
#'------------------------------------------------------------------------------
[Bool]$modify = $False
If((-Not([String]::IsNullOrEmpty($MonitorMode))) -Or ($MaxRunTime -ne 0) -Or ($MaxReplySize -ne 0)){
   [Bool]$modify = $True
}
#'------------------------------------------------------------------------------
#'Connect to the cluster.
#'------------------------------------------------------------------------------
Connect-WfaCluster $Cluster
#'------------------------------------------------------------------------------
#'Modify the ontapi limits and add the results as return parameters.
#'------------------------------------------------------------------------------
If($modify){
   [Array]$command = @("set diag;system", "ontapi", "limits", "modify")
   If($MonitorMode){
      [Array]$command += @("-monitor-mode", $MonitorMode)
   }
   If($MaxRunTime){
      [Array]$command += @("-max-run-time", $MaxRunTime)
   }
   If($MaxReplySize){
      [Array]$command += @("-max-reply-size", $MaxReplySize)
   }
   [Bool]$result = Invoke-OntapiLimits -Cluster $Cluster -Command $command -AddReturnParamaters $False
   #'---------------------------------------------------------------------------
   #'Enumerate the ontapi limits to ensure they were modified and add them as return parameters.
   #'---------------------------------------------------------------------------
   If($result){
      [Array]$command = @("set diag;system", "ontapi", "limits", "show")
      [Bool]$result   = Invoke-OntapiLimits -Cluster $Cluster -Command $command -AddReturnParamaters $True
      If((-Not($result))){
         Throw "Failed enumerating ontap limites for cluster ""$Cluster"""  
      }
   }Else{
      Throw "Failed modifying ontapi limits for cluster ""$Cluster"""
   }
}Else{
   #'---------------------------------------------------------------------------
   #'Enumerate the ontapi limits and add them as return parameters.
   #'---------------------------------------------------------------------------
   [Array]$command = @("set diag;system", "ontapi", "limits", "show")
   [Bool]$result   = Invoke-OntapiLimits -Cluster $Cluster -Command $command -AddReturnParamaters $True
   If((-Not($result))){
      Throw "Failed enumerating ontap limites for cluster ""$Cluster"""  
   }
}
#'------------------------------------------------------------------------------

If you are not using WFA and just want a native powershell example then replace:

 

  • "Get-WFALogger -Info -Message" with "Write-Host"
  • "Get-WFALogger -Error -Message" with "Write-Warning -Message"
  • Comment out "#Add-WfaWorkflowParameter"
  • "Connect-WfaCluster $Cluster" with "Connect-NcController -Name $Cluster -HTTPS -Credential $(Get-Credential -Credential admin)"
  • Add "Import-Module DataONTAP" to your script

Here is an example output from WFA:

 

wfa.png

 

return.png

 

Hope that's a more useful example that you should be able to test without issue and use the code as the basis for modifying it to meet your requirements.

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

DonnaLou

Thank you Matt!  I REALLY appreciate your help!  I will try this on Monday 🙂

DonnaLou

Thank you Matt!  I really appreciate the code example!!

M_Ferber

When it comes to execute ssh command within powershell I'd rather prefer using the posh-ssh module from the powershell galery (https://www.powershellgallery.com/packages/Posh-SSH/) than having to invoke an external executable like plink. You can also install that module directly within powershell using the install-module posh-ssh.

 

In the mean time this module allow you to stream commands which is nice.

 

I'm using it that way:

 

if (Get-Module -ListAvailable -Name posh-ssh)
    {
        if (!(Get-Module -Name posh-ssh))
        {
            import-module posh-ssh
            Get-WFALogger -Info -message $("     [>] posh-ssh Module loaded successfully..")
        } else
        {
            Get-WFALogger -Info -message $("     [>] posh-ssh Module already loaded..")
        }
    } else
    {
        Throw "Posh-ssh module not found. Please install the posh-ssh module"
    }

 

$response=@()

    $session=New-SSHSession -ComputerName $MgmtIP -Credential $Credential -KeepAliveInterval 60 -AcceptKey -Force
    $stream = $session.Session.CreateShellStream("",0,0,0,0,10000)
    sleep 2

$stream.Write("$Command`r")

$response+=$stream.Read()

NHANAS_RS

Same issues, access error - requires "Run As Administrator" (Server 2008\2012) 

Announcements
NetApp on Discord Image

We're on Discord, are you?

Live Chat, Watch Parties, and More!

Explore Banner

Meet Explore, NetApp’s digital sales platform

Engage digitally throughout the sales process, from product discovery to configuration, and handle all your post-purchase needs.

NetApp Insights to Action
I2A Banner
Public