Thursday, 4 October 2018

SSH Plus for Windows (SSH.exe with Password Functionality)

Carrying on from How to Pass a Password (and Enter press) to a Prompt in Powershell, I wrote this little module that I call ‘SSH Plus for Windows’. Copy and paste the script below into a text editor, and save as say SSH_PLUS.psm1. Then to use it, follow the example below:

PS> import-module C:\SCRIPTS\SSH_PLUS.psm1
PS> SSHplus-pass
Password: *********
PS> ssh+ admin@10.9.1.0 node show local

The function SSHplus-pass supplies a password (which is stored in a global variable for as long as the PowerShell window stays open). There are also functions SSHplus-path which allows setting a path for the temporary PS1 file we create, and SSHplus-timeout which allows you to tune the timeout from the default 4 seconds. Instead of Windows SSH.exe (or SSH), run SSH+ - simples!

Note 1: If you’ve never connected to the host before, you will need to cache the SSL key. Use ssh.exe for this.
Note 2: If nothing’s happening, could be that ssh.exe / rssh.exe is still running in the background, kill that and all should be good again.

Image: SSH+ in action (ignore the warning about verbs)

The Script / Module


#############
## SSHplus ##
#############

Function SSHplus-pass{
  Param([String]$Password)
  If(!$Password){$Global:SecPW = Read-Host "Password" -AsSecureString}
  Else{$Global:SecPW = $Password | ConvertTo-SecureString -AsPlainText -Force}
}

Function SSHplus-path{
  Param([String]$TempFolderPath)
  If(!$TempFolderPath){$TempFolderPath = Read-Host "Path for SSHplus Temp File"}
  If(!(Test-Path ($TempFolderPath))){"Invalid path!";RETURN}
  $Global:TmpFolderPath = $TempFolderPath
}

Function SSHplus-timeout{Param([Int]$Global:SSHtimeout = 4)}

Function SSH+{
  ## CHECK: PW / TEMP FILE PATH / TIMEOUT ##
  If(!$Global:SecPW){"Use SSHplus-pass to enter password.";RETURN}
  If(!$Global:TmpFolderPath){$Global:TmpFolderPath = $Pwd}
  [String]$TempFilePath = Join-Path $Global:TmpFolderPath "SSH+_Temp.ps1"
  "TEST" | Set-Content $TempFilePath
  If(!(Test-Path $TempFilePath)){
    [String]("Cannot write to " + $Global:TmpFolderPath + ". Use SSHplus-path to enter path of SSH+ Temp File.")
    RETURN
  }
  If(!$Global:SSHtimeout){$Global:SSHtimeout = 4}
 
  ## OBTAIN VARIABLES FROM ARGS ##
  # ARGs are expected as: ssh+ user@host command ...
  [String]$UserAtDest = $Args[0]
  [String]$Dest = ($Args[0].Split("@"))[0]
  $Args[0] = ""
  [String]$Command = ""
  $Args | Foreach{ $Command += ($_ + " ") }
  $Command = $Command.Trim(" ")
 
  ## MAX THE SHELL BUFFERS AND SET THE TITLE ##
  $Window = (Get-Host).UI.RawUI
  $resize = $Window.BufferSize
  $resize.Height = 9999
  $resize.Width = 9999
  $Window.BufferSize = $resize
  $host.ui.RawUI.WindowTitle = "Windows PowerShell w SSH+"
 
  ## PAINTEXT THE PASSWORD ##
  $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Global:SecPW)
  [String]$CTPW = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
 
  ## CREATE THE TEMP PS FILE (this PS1 activates after the SSH command) ##
  If(Test-Path $TempFilePath){Remove-Item -Path $TempFilePath}
  [System.Array]$Temp = @()
  $Temp += ('Sleep ' + "$Global:SSHtimeout")
  $Temp += ('$wshell = New-Object -ComObject wscript.shell')
  $Temp += ('$wshell.AppActivate("Windows PowerShell w SSH+")')
  $Temp += ('$wshell.SendKeys("' + $CTPW + '")')
  $Temp += ('$wshell.SendKeys("~")')
  $Temp += ('Remove-Item -path "' + $TempFilePath + '"')
  $Temp | Set-Content $TempFilePath
 
  ## ACTIVATE SSH+_Temp.ps1 ##
  start powershell.exe '.\SSH+_Temp.ps1' -WorkingDirectory $Global:TmpFolderPath
  ssh.exe $UserAtDest $Command
}

Sunday, 23 September 2018

Tech Roundup - 23rd September 2018

Stuff collated since Tech Roundup - 31st August 2018. With headings:
AWS, IBM, Industry Commentary, Lenovo, Microsoft, NetApp, Tech ONTAP Podcast, NetApp TRs, Security, Virtualization

AWS

Elevate Your Cloud Skills Ebook

IBM

NetApp ONTAP Select on IBM Cloud

IBM Cloud and NetApp Deliver ONTAP Select Monthly

Industry Commentary

In multi-cloud muddle, vendors must partner for greater good:

Lenovo

Lenovo and NetApp Form Global Strategic Partnership to Accelerate Customers’ Digital Transformation

Lenovo and NetApp Form Global Strategic Partnership to Accelerate Customers’ Digital Transformation

Microsoft

A few Excel hints and tips:

Creating Worksheets with a Macro

Import-Xls

Reading ZIP file contents without extraction using PowerShell

How to Protect/Unprotect all Worksheets with VBA in Microsoft Excel 2010

How to reduce a huge excel file

NetApp

A New Take on Scale-Out Storage Expansion for NetApp HCI and SolidFire

Image: NetApp H610S

NetApp wants to make hybrid HCI Amazon-easy

What the Heck is VMware Private Cloud with NetApp HCI, Anyway?

Accelerate Your Journey to AI with Data

NetApp and NVIDIA Supercharge Deep Learning with New AI Architecture
Accelerate Your Journey to AI with NetApp and NVIDIA
Jim McHugh, NVIDIA and Octavian Tanase, NetApp | Accelerate Your Journey to AI

How Machine Learning Can Improve Quality Test Engineering

Snapshots Deep Dive: AWS Snapshots and Azure Snapshots

NetApp Cloud WORM: Enhancing Data Protection with Locking Features

Element Software Simulator: Try Before You Buy, Use Your Test APIs

NetApp Tech ONTAP Podcast


Episode 157: Performance Analysis Using OnCommand Unified Manager

Episode 156: SnapCenter 4.1

Episode 155: Trident 18.07 and… Goodbye Sully?

NetApp TRs

TR-4716: NetApp Solutions for Hadoop: Reference Architecture: Hortonworks

TR-4715: NetApp In-Place Analytics Module: Joint Reference Architecture

TR-4714: Best Practice Guide for SQL Server Using NetApp SnapCenter

Security


Virtualization

ESXi on Arm? Yes, ESXi on Arm. VMware teases bare-metal hypervisor for 64-bit Arm servers

Thursday, 20 September 2018

How to Pass a Password (and Enter press) to a Prompt in Powershell

Where I’m working at-the-moment, I don’t have access to plink.exe, nor some other tools I’d normally use, but I can get to PowerShell, and the desktop environment has ssh.exe. The problem with ssh.exe is that there’s no command line switch to allow for a password. So, here’s how I can make PowerShell automatically answer ssh.exe’s password rompt.

1) Set the PowerShell Window Title to something specific:

$host.ui.RawUI.WindowTitle = "Your Title"

2) Save a script called say “SendPassword.ps1” with the below content to somewhere accessible (I’ll use 'C:\MY TOOLS' in this post):

$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('Your Title)
Sleep 4
$wshell.SendKeys('YourPassword')
$wshell.SendKeys('~')

Note: You will need to tune the sleep timer so that it finishes after the ‘Password’ prompt appears. 4 seconds worked for me in the example below.

3) Run your SSH command from PowerShell like below:

start powershell.exe '.\SendPassword.ps1' -WorkingDirectory 'C:\MY TOOLS'; ssh.exe admin@10.0.0.200 node show local -fields serialnumber

Image: Screenshot of the setup

Tuesday, 18 September 2018

XDP SnapMirror 9.4 to 9.2 and 9.2 to 9.4 Does Work Just Not Supported

I took exception to something in Justin Parisi’s blog post:

In it he wrote -
“...If you are running ONTAP 9.4, XDP SnapMirror will work across all prior ONTAP 9.x releases except for ONTAP 9.2...”
That tripped my fake news detector. If you think about it, it makes zero sense that 9.4 to 9.1 works, but 9.4 to 9.2 doesn’t, and then 9.4 to 9.3 does - XDP SnapMirror is such an awesome and powerful technology, why would it just decide to stop working for 9.2!?

Image: The exception I took exception to

This is what he should have written:
“...If you are running ONTAP 9.4, XDP SnapMirror will be supported across all prior ONTAP 9.x releases except for ONTAP 9.2...”

In the screenshots below is proof of sorts to show it does indeed work for 9.2 to 9.4 and vice versa.

Image: XDP SnapMirror from 9.2 to 9.4 works (just not supported)

Image: XDP SnapMirror from 9.4 to 9.2 works (just not supported)

In the official table below, I think the language is wrong; instead of “Will work with these previous releases” it should be “is guaranteed to work and supported with these previous releases”. Pernickety me?

Image: SnapMirror XDP Release Interoperability

APPENDIX: CLI

In case my proof images go missing, I have put the CLI output below:


clu1::> version
NetApp Release 9.2P4: Tue May 01 19:23:51 UTC 2018

clu1::> snapmirror show
                                                                       Progress
Source            Destination Mirror  Relationship   Total             Last
Path        Type  Path        State   Status         Progress  Healthy Updated
----------- ---- ------------ ------- -------------- --------- ------- --------
clu2v1:vol2 XDP  clu1v1:vol2_DR Snapmirrored Idle    -         true    -

clu1::> snapmirror list-destinations
                                                  Progress
Source             Destination         Transfer   Last         Relationship
Path         Type  Path         Status Progress   Updated      Id
----------- ----- ------------ ------- --------- ------------ ---------------
clu1v1:vol1 XDP   clu2v1:vol1_DR Idle  -         -            678c478c-b9f2-11e8-ba81-000c299131c0

clu1::> qtree show -qtree !""
Vserver    Volume        Qtree        Style        Oplocks   Status
---------- ------------- ------------ ------------ --------- --------
clu1v1     vol1          qtree1       unix         enable    normal
clu1v1     vol2_DR       qtree2       unix         enable    readonly
2 entries were displayed.



clu2::> version
NetApp Release 9.4: Fri Jun 08 22:50:12 UTC 2018

clu2::> snapmirror show
                                                                       Progress
Source            Destination Mirror  Relationship   Total             Last
Path        Type  Path        State   Status         Progress  Healthy Updated
----------- ---- ------------ ------- -------------- --------- ------- --------
clu1v1:vol1 XDP  clu2v1:vol1_DR Snapmirrored Idle    -         true    -

clu2::> snapmirror list-destinations
                                                  Progress
Source             Destination         Transfer   Last         Relationship
Path         Type  Path         Status Progress   Updated      Id
----------- ----- ------------ ------- --------- ------------ ---------------
clu2v1:vol2 XDP   clu1v1:vol2_DR Idle  -         -            3ea380b6-b9f3-11e8-b19e-000c293eecae

clu2::> qtree show -qtree !""
Vserver    Volume        Qtree        Style        Oplocks   Status
---------- ------------- ------------ ------------ --------- --------
clu2v1     vol1_DR       qtree1       unix         enable    readonly
clu2v1     vol2          qtree2       unix         enable    normal
2 entries were displayed.


Friday, 14 September 2018

PowerShell to Update Clusters with Multiple Cluster Peers in Multiple IPSpaces

Not something I’m likely to use where I am at-the-moment seeing as there are certain restrictions. Still, I thought I’d show how easy it would be to use the DataONTAP PowerShell Toolkit to connect to a cluster, find all the cluster peers, peer IPSpaces, and intercluster LIFs in each of those IPSpaces, and then connect to all the peer clusters and update the cluster peer's peer addresses. This is something you’d only really be interested in doing if expanding/contracting a cluster/clusters, or checking that existing clusters have their ‘Remote Intercluster Addresses’ configured correctly (‘Active IP Addresses’ manage themselves to a degree.)

Image: Update Cluster Peers in action

Note i: The script was tested with ONTAP 9.0RC1 and the DataONTAP PowerShell ToolKit 4.0.0.231 (I’m not sure why I had to put a dummy passphrase in the script, perhaps this “bug” is fixed in later versions.)
Note ii: Assumptions are that the same credentials can login to all the involved clusters, IPSpace names are consistent...

The Script


## SOURCE CLUSTER ##

Import-Module DataONTAP
$cluster  = Read-Host "Enter Cluster Name"
$username = Read-Host "Enter Admin User  "
$password = Read-Host "Enter Password    " -AsSecureString
$credential = New-Object System.Management.Automation.PsCredential($username,$password)
Connect-NcController $cluster -Credential $credential

$Peers = Get-NcClusterPeer
$Query = Get-NcNetInterface -Template
$Query.role = "intercluster"
$IcInts = Get-NcNetInterface -Query $Query

## INTERCLUSTER LIFS to IPSPACES (I2I) ##

[System.Object]$I2I = @{}
[System.Array]$I2I.IPSs = @()

$IcInts | Foreach{
  [Int]$Unique = ($I2I.IPSs).count
  [System.Array]$I2I.IPSs = ($I2I.IPSs += $_.ipspace) | Select-Object -Unique
  If($Unique -ne ($I2I.IPSs).count){[System.Array]$I2I.($_.Ipspace) = @()}
  $I2I.($_.Ipspace) += ($_.Address)
}

## PEER CLUSTERS ##

$Peers | Foreach{
  Connect-NcController $_.ClusterName -Credential $credential
  [String]$IPspace = (Get-NcClusterPeer -ClusterName $cluster).IpspaceName
  [Void](Get-NcClusterPeer -ClusterName $cluster | Set-NcClusterPeer -Address ($I2I.$IPspace) -Passphrase "anything")
}