# testSftpConnect.ps1
# Quick script to test SFTP connectivity
$username='FTPUSER'
$password='PASSWORD'
$sftpServer='x.x.x.x'
$sftpPort=22
function testSftpConnect($sftpServer,$username,$password,$sftpPort){
function includePowerShellWrapper($appName){
# Ensure that PowerShell is using TLS 1.2 in this session
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Uncomment these lines to make TLS1.2 defaults on next reboot
#Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
#Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
# Deterministic verification on whether module commands are able to load
Import-Module $appName -ea SilentlyContinue
# Sanity check: validate module name before proceeding
$moduleVersion=.{$y=find-module $appName -ea SilentlyContinue;if($y){return $y.Version.ToString()}}
if(!$moduleVersion){write-warning "'$($appName.ToUpper())' doesn't match PowerShell module";return $false}
elseif(!$moduleIsLoaded){
# Part A) Compare the installed module with its online counter-part; install if necessary
# Select Major, Minor, and Build - omitting Revision.
# This is because PowerShell wrapper will deem an installed binary as compatible as long as those values match
$installedVersion=.{$x=Get-Module $appName -ea SilentlyContinue;if($x){return $x.Version.ToString()}}
$targetVersion=.{try{[void]($moduleVersion -match '^(\d+\.\d+\.{0,1}\d+)');$matches[1]}catch{}}
if($matches){Clear-Variable -name matches}
write-host "$($appName.ToUpper()) PowerShell wrapper`: Installed $installedVersion v.s Updated version $moduleVersion"
if($installedVersion -ne $moduleVersion){
write-host "Attempting to install the module $appName $moduleVersion"
Remove-Module $appName -ea SilentlyContinue
try{
Install-Module -Name $appName -Force -Confirm:$false;
Import-Module $appName;
write-host "$appName PowerShell wrapper module has been installed."
return $true
}
catch{
if(!('NuGet' -in (get-packageprovider).Name)){
try{
Install-PackageProvider -Name NuGet -MinimumVersion '2.8.5.201' -Force -Confirm:$false -ErrorAction Stop;
Install-Module -Name $appName -Force -Confirm:$false;
Import-Module $appName;
write-host "$appName PowerShell wrapper module has been installed."
}
catch{
write-host "$error"
write-warning "Unable to install $appName module"
return $false
}
}
}
}
# Part B) Check Installed applications and upgrade/downgrade as necessary
$installedApps=Get-CimInstance -ClassName win32_InstalledWin32Program -ErrorAction SilentlyContinue|select Name,Version
$appwizAppExists=.{try{$matchApp=$installedApps|?{$_.Name -like "*$appName*"|select -First 1 }
if($matchApp){$matchApp}else{$false}}catch{}}
$appwizVersion=.{try{[void]($(if($appwizAppExists){$appwizAppExists.Version}else{$false}) -match '^(\d+\.\d+\.{0,1}\d+)');$matches[1]}catch{}}
if($matches){Clear-Variable -name matches}
write-host "Application Wizard version being detected: $appwizAppExists"
$isAppwizSameVersion=$targetVersion -eq $appwizVersion
$chocoInstalledApps=choco list -l
$chocoAppExists=$chocoInstalledApps|?{$_ -like "*$appName*"}|select -First 1
$chocoVersion=.{try{[void]($(.{[void]($chocoAppExists -match ' ([\d+\.]+)');return $matches[1]}) -match '^(\d+\.\d+\.{0,1}\d+)');$matches[1]}catch{}}
if($matches){Clear-Variable -name matches}
write-host "Choco version being detected: $chocoAppExists"
$isChocoSameVersion=$targetVersion -eq $chocoVersion
write-host "Target version: $targetVersion, Appwiz version: $appwizVersion, Choco version: $chocoVersion"
if (!($isAppwizSameVersion -or $isChocoSameVersion)){
write-host "Now trying to install $appname..."
if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))}
try{
if(!$chocoAppExists -and !$appwizAppExists){choco install $appName --version=$targetVersion -y}
elseif (!$isChocoSameVersion -and !$isAppwizSameVersion){choco install $appName --version=$targetVersion --force -y}
write-host "Application $appName $targetVersion is now installed"
if($matches){Clear-Variable -name matches}
return $true
}
catch{
write-warning "Unable to install the app name $appName $targetVersion using Chocolatey."
if($matches){Clear-Variable -name matches}
return $false
}
}
else{
write-host "$appName is already installed.";
if($matches){Clear-Variable -name matches}
return $true}
}
else{write-host "$($appName.ToUpper()) module has loaded successfully.";return $true}
}
function connectWinScp{
param (
$remoteHost,
$username,
$password,
$port=22,
$hostKey,
$privateKey
)
Import-Module WinScp -ea SilentlyContinue
# Possible error:
# Import-Module : The specified module 'WinScp' was not loaded because no valid module file was found in any module
# directory.
# At line:102 char:15
# + $null=Import-Module WinScp
# + ~~~~~~~~~~~~~~~~~~~~
# + CategoryInfo : ResourceUnavailable: (WinScp:String) [Import-Module], FileNotFoundException
# + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
# $moduleIsLoaded=Get-Command -Module $appName -ea SilentlyContinue
if(!(get-module Winscp)){
includePowerShellWrapper Winscp
Import-Module WinScp
}
# if ($scpSession){ # deal with case that the global variable $scpSession has already been assigned
# try{
# Close-WinSCPSession -WinSCPSession $scpSession -ea SilentlyContinue
# $scpSession.Dispose()
# }catch{
# Clear-Variable scpSession
# }
# }
$optionValues="
`$options = New-Object WinSCP.SessionOptions -Property @{
# source: https://winscp.net/eng/docs/library_sessionoptions
Protocol = [WinSCP.Protocol]::Sftp
HostName = '$remoteHost'
username = '$username'
portnumber = '$port'
$(if($hostKey){"SshHostKeyFingerprint = '$hostKey'"}else{"GiveUpSecurityAndAcceptAnySshHostKey = `$True"})
$(if($privateKey){"SshPrivateKeyPath = '$privateKey'"}else{"password = '$password'"})
}"
try{
write-host $optionValues
Invoke-Expression $optionValues
$scpSession = Open-WinSCPSession -SessionOption $options -ea Stop
write-host "WinSCP has successfully connected to $remoteHost" -ForegroundColor Green
return $scpSession
}
catch{
write-waring $_
write-host "unable to connnect to $remoteHost" -ForegroundColor Yellow
return $false
}
}
$scpSession=connectWinScp $sftpServer $username $password $sftpPort
if($scpSession){
write-host "Now closing test WinScp session"
Close-WinSCPSession -WinSCPSession $scpSession
# $scpSession.dispose() # alternate cleanup routine
return $true
}else{
return $false
}
}
testSftpConnect $sftpServer $username $password $sftpPort
Categories: