Microsoft Virtualization Discussions

Re: NetApp PowerShell Toolkit 4.5P1 released!

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()

Re: NetApp PowerShell Toolkit 4.5P1 released!

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

Re: NetApp PowerShell Toolkit 4.5P1 released!

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.

Re: NetApp PowerShell Toolkit 4.5P1 released!

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

Re: NetApp PowerShell Toolkit 4.5P1 released!

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

Re: NetApp PowerShell Toolkit 4.5P1 released!

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.

Re: NetApp PowerShell Toolkit 4.5P1 released!

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

Highlighted

Re: NetApp PowerShell Toolkit 4.5P1 released!

Is Powershell Core compatibility anywhere on the development roadmap?

Re: NetApp PowerShell Toolkit 4.5P1 released!

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.

Re: NetApp PowerShell Toolkit 4.5P1 released!

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: (Smiley Happy [Invoke-NcSsh], Win32Exception

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

 

Forums