PSCredentialStore/src/Connection/Connect-To.ps1

391 lines
15 KiB
PowerShell

function Connect-To {
<#
.SYNOPSIS
Connects to the given host using the stored CredentialStoreItem.
.DESCRIPTION
Establish a connection to the selected host using a stored CredentialStoreItem.
.PARAMETER RemoteHost
Specify the host, for which you would like to change the credentials.
.PARAMETER Identifier
Defaults to ''. Specify a string, which separates two CredentialStoreItems for the
same hostname.
.PARAMETER Type
Specify the host type of the target. Currently implemented targets are: Possible connection values are:
- CiscoUcs
- CiscoUcsCentral
- ExchangeHTTP
- ExchangeHTTPS
- FTP
- NetAppFAS
- NetAppStorageGRID
- SCP
- VMware
- VMwareCisServer
.PARAMETER Credentials
Use this parameter to bypass the stored credentials. Without this parameter Connect-To tries to read the
needed credentials from the CredentialStore. If you provide this parameter you skip this lookup behavior.
So you can use it to enable credentials without preparing any user interaction.
.PARAMETER Path
Define a custom path to a shared CredentialStore.
.PARAMETER Shared
Switch to shared mode with this param. This enforces the command to work with a shared CredentialStore which
can be decrypted across systems.
.PARAMETER PassThru
Returns the value from the underlying connection type function.
.INPUTS
[None]
.OUTPUTS
[None]
.EXAMPLE
Connect-To -RemoteHost 'vc.domain.local' -Type CisServer
.EXAMPLE
Connect-To -RemoteHost 'ucs.domain.local' -Type CiscoUcs
.EXAMPLE
Connect-To -RemoteHost 'ucs-central.domain.local' -Type 'CiscoUcsCentral'
.EXAMPLE
Connect-To -RemoteHost 'exchange01.domain.local' -Type ExchangeHTTP
.EXAMPLE
Connect-To -RemoteHost 'exchange01.domain.local' -Type ExchangeHTTPS
.EXAMPLE
Connect-To -RemoteHost 'ftp.domain.local' -Type FTP
.EXAMPLE
Connect-To -RemoteHost 'fas.domain.local' -Type NetAppFAS
.EXAMPLE
Connect-To -RemoteHost 'grid.domain.local' -Type NetAppStorageGRID
.EXAMPLE
Connect-To -RemoteHost 'esx01.domain.local' -Type VMware
#>
[CmdletBinding(DefaultParameterSetName = 'Private')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSAvoidGlobalVars',
'',
Justification = 'Wrapping existing var from WinSCP module.'
)]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[string] $RemoteHost,
[Parameter(Mandatory = $false, ParameterSetName = 'Shared')]
[Parameter(Mandatory = $false, ParameterSetName = 'Private')]
[string] $Identifier,
[Parameter(Mandatory = $true, ParameterSetName = 'Shared')]
[Parameter(Mandatory = $true, ParameterSetName = 'Private')]
[ValidateSet(
'CiscoUcs',
'CiscoUcsCentral',
'ExchangeHTTP',
'ExchangeHTTPS',
'FTP',
'NetAppFAS',
'NetAppStorageGRID',
'SCP',
'VMware',
'VMwareCisServer'
)]
[string] $Type,
[Parameter(Mandatory = $False, ParameterSetName = 'Shared')]
[Parameter(Mandatory = $False, ParameterSetName = 'Private')]
[PSCredential] $Credentials,
[Parameter(Mandatory = $true, ParameterSetNAme = 'Shared')]
[switch] $Shared,
[Parameter(Mandatory = $False, ParameterSetName = 'Shared')]
[ValidateNotNullOrEmpty()]
[string] $Path,
[Parameter(Mandatory = $False, ParameterSetName = 'Private')]
[Parameter(Mandatory = $False, ParameterSetName = 'Shared')]
[switch] $PassThru
)
begin {
# Set the CredentialStore for private, shared or custom mode.
Write-Debug ('ParameterSetName: {0}' -f $PSCmdlet.ParameterSetName)
if ($PSCmdlet.ParameterSetName -eq 'Private') {
$Path = Get-DefaultCredentialStorePath
}
elseif ($PSCmdlet.ParameterSetName -eq 'Shared') {
if (!($PSBoundParameters.ContainsKey('Path'))) {
$Path = Get-DefaultCredentialStorePath -Shared
}
}
switch ($Type) {
'VMware' {
# Disable the yellow certificate warning, since we haven't replaced the SSL certs for vCenter/ESXi
$null = Set-PowerCLIConfiguration -Scope Session -InvalidCertificateAction Ignore -Confirm:$false
# Disable connecting through proxy, since vCenter isn't somewhere we need a proxy for.
$null = Set-PowerCLIConfiguration -Scope Session -ProxyPolicy NoProxy -Confirm:$false
}
}
# Set sane defaults for Progress, ErrorAction and InformationPreference
$ProgressPreference = 'SilentlyContinue'
$ErrorActionPreference = 'Stop'
$InformationPreference = 'Continue'
}
process {
if (-not ($Credentials)) {
# Load the credential from the CredentialStore. If the credential doesn't exist, we need to
# return 1, so a calling if statement can handle the failure detection.
# Check if $Identifier has been defined, in which case we need to use different name for
# the lookup of the CredentialStoreItem.
try {
if ($Identifier -ne '') {
$RemoteHostIdentifier = '{0}/{1}' -f $Identifier, $RemoteHost
$creds = Get-CredentialStoreItem -Shared -RemoteHost $RemoteHostIdentifier -Path $Path
}
else {
$creds = Get-CredentialStoreItem -Shared -RemoteHost $RemoteHost -Path $Path
}
}
catch {
$MessageParams = @{
Message = (
'Unable to look up credential store item for RemoteHost ' +
('{0}/Identifier {1}!' -f $RemoteHost, $Identifier)
)
ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
}
else {
$creds = $Credentials
}
if ($creds.UserName -eq '' -or $creds.Password.GetType().Name -ne 'SecureString') {
$MessageParams = @{
Message = 'Please provide valid credentials for RemoteHost {0}!' -f $RemoteHost
ErrorAction = 'Stop'
}
Write-Error @MessageParams
}
else {
switch ($Type) {
'CiscoUcs' {
try {
$handle = Connect-Ucs -Name $RemoteHost -Credential $creds -NotDefault
$ExecutionContext.SessionState.PSVariable.Set('DefaultUcs', $handle)
}
catch {
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
}
'CiscoUcsCentral' {
try {
$handle = Connect-UcsCentral -Name $RemoteHost -Credential $creds -NotDefault
$ExecutionContext.SessionState.PSVariable.Set('DefaultUcsCentral', $handle)
}
catch {
Write-Error -Message ('Unable to connect to {0} using {1}' -f $RemoteHost, $Type)
}
}
'ExchangeHTTP' {
try {
$ConnectionParams = @{
ConnectionURI = 'http://{0}/powershell' -f $RemoteHost
ConfigurationName = 'Microsoft.Exchange'
Credential = $creds
}
$global:PSExchangeRemote = New-PSSession @ConnectionParams
# ScriptAnalyzer issue (unused var) workaround.
$null = $global:PSExchangeRemote
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
}
'ExchangeHTTPS' {
try {
$ConnectionParams = @{
ConnectionURI = 'https://{0}/powershell' -f $RemoteHost
ConfigurationName = 'Microsoft.Exchange'
Credential = $creds
}
$global:PSExchangeRemote = New-PSSession @ConnectionParams
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
}
'FTP' {
# First establish the FTP session
$WinSCPConParams = @{
Credential = $creds
Hostname = $RemoteHost
Protocol = 'Ftp'
FtpMode = 'Passive'
}
try {
$FTPSessionOption = New-WinSCPSessionOption @WinSCPConParams
$global:WinSCPSession = New-WinSCPSession -SessionOption $FTPSessionOption
}
catch {
Write-Error -Message ('Could not connect to {0} using {1} protocol!' -f $RemoteHost, $Type)
}
# Check the Connection State
if (-not $WinSCPSession.Opened) {
# Check the connection state and find out if the session is still open.
$m = 'Connection to {0} using Type {1} was established. ' -f $RemoteHost, $Type
$m += 'But now it seems to be lost!'
Write-Error -Message $m
}
}
'NetAppFAS' {
# Construct the splatting for Connect-NcController
$params = @{
Name = $RemoteHost
Credential = $creds
HTTPS = $true
}
# Check if -PassThru was passed. If so, a) do not set the default variable and b) return the
# session object to the caller.
if ($PSBoundParameters.ContainsKey('PassThru')) {
$params.Add('Transient', $true)
}
try {
$handle = Connect-NcController @params
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
if ($PSBoundParameters.ContainsKey('PassThru')) {
return $handle
}
}
'NetAppStorageGRID' {
# Construct the splatting for Connect-SgwServer
$params = @{
Name = $RemoteHost
Credential = $creds
SkipCertificateCheck = $true
}
# Check if -PassThru was passed. If so, a) do not set the default variable and b) return the
# session object to the caller.
if ($PSBoundParameters.ContainsKey('PassThru')) {
$params.Add('Transient', $true)
}
try {
$SgwSession = Connect-SgwServer @params
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
if ($PSBoundParameters.ContainsKey('PassThru')) {
return $SgwSession
}
}
'SCP' {
$WinSCPSessionParams = @{
Credential = $creds
Hostname = $RemoteHost
Protocol = 'Scp'
GiveUpSecurityAndAcceptAnySshHostKey = $True
}
try {
$SessionOption = New-WinSCPSessionOption @WinSCPSessionParams
$global:WinSCPSession = New-WinSCPSession -SessionOption $SessionOption
Write-Verbose -Message (
'SCP Connection established with {0}' -f $global:WinSCPSession.Hostname
)
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
# Check the Connection State
if (!($WinSCPSession.Opened)) {
# Check the connection state and find out if the session is still open.
$m = 'Connection to {0} using Type {1} was established. ' -f $RemoteHost, $Type
$m += 'But now it seems to be lost!'
Write-Error -Message $m
}
}
'VMware' {
try {
Connect-VIServer -Server $RemoteHost -Credential $creds -ErrorAction Stop | Out-Null
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
}
'VMwareCisServer' {
try {
if ($PassThru.IsPresent) {
Connect-CisServer -Server $RemoteHost -Credential $creds
}
else {
$null = Connect-CisServer -Server $RemoteHost -Credential $creds
}
}
catch {
# Write a error message to the log.
Write-Error -Message ('Unable to connect to {0} using Type {1}.' -f $RemoteHost, $Type)
}
}
}
}
}
}