From 0a197a6ceb9f2d8f0f7352fd914be61197f2f49b Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Mon, 12 Feb 2024 06:00:00 -0500 Subject: [PATCH] refactor: update `Invoke-VCFCommand` (#268) --- CHANGELOG.md | 1 + PowerVCF.psd1 | 2 +- PowerVCF.psm1 | 131 +++++++++--------- .../functions/other/Invoke-VCFCommand.md | 127 +++++++++++++++++ .../functions/sos/Invoke-VCFCommand.md | 91 ------------ mkdocs.yml | 3 +- 6 files changed, 194 insertions(+), 161 deletions(-) create mode 100644 docs/documentation/functions/other/Invoke-VCFCommand.md delete mode 100644 docs/documentation/functions/sos/Invoke-VCFCommand.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 876b1c30..4671393a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Removed the deprecated `Get-VCFNsxManagerCluster` alias from `Get-VCFNsxtCluster`. - Removed the deprecated `Get-VCFNsxEdgeCluster` alias from `Get-VCFEdgeCluster`. - Removed the deprecated `New-VCFNsxEdgeCluster` alias from `New-VCFEdgeCluster`. +- Refactors `Invoke-VCFCommand` to run commands on SDDC Manager without the need for SSH across PowerShell editions and operating systems. ## v2.4.1 diff --git a/PowerVCF.psd1 b/PowerVCF.psd1 index 2f325ac3..6b50ddd3 100644 --- a/PowerVCF.psd1 +++ b/PowerVCF.psd1 @@ -11,7 +11,7 @@ RootModule = 'PowerVCF.psm1' # Version number of this module. -ModuleVersion = '2.5.0.1005' +ModuleVersion = '2.5.0.1006' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PowerVCF.psm1 b/PowerVCF.psm1 index cdfedaff..7f620a4e 100644 --- a/PowerVCF.psm1 +++ b/PowerVCF.psm1 @@ -6042,96 +6042,91 @@ Function Validate-EdgeClusterSpec { #EndRegion APIs for managing Validations (Not Exported) -#Region SoS Operations +#Region Utility Functions (Exported) Function Invoke-VCFCommand { <# .SYNOPSIS - Connects to the specified SDDC Manager using SSH and invoke SSH commands (SoS). + Run a command on SDDC Manager. .DESCRIPTION - The Invoke-VCFCommand cmdlet connects to the specified SDDC Manager over SSH using vcf user and subsequently - run elevated SOS commands using the root account. + The Invoke-VCFCommand cmdlet runs a command within the SDDC Manager appliance. .EXAMPLE - Invoke-VCFCommand -vcfpassword VMware1! -rootPassword VMware1! -sosOption general-health - This example will run and display the output of "/opt/vmware/sddc-support/sos --general-health". + Invoke-VCFCommand -server sfo-vcf01.sfo.rainpole.io -user admin@local -pass VMw@re1!VMw@re1! -vmUser vcf -vmPass VMw@re1! -command "echo Hello World." + This example runs the command provided on the SDDC Manager appliance as the vcf user. - .EXAMPLE - Invoke-VCFCommand -sosOption general-health - This example will ask for vcf and root password to the user and then run and display the output of "/opt/vmware/sddc-support/sos --general-health". + .PARAMETER server + The fully qualified domain name of the SDDC Manager. + + .PARAMETER user + The username to authenticate to the SDDC Manager. + + .PARAMETER pass + The password to authenticate to the SDDC Manager. + + .PARAMETER vmUser + The username to authenticate to the virtual machine. + + .PARAMETER vmPass + The password to authenticate to the virtual machine. + + .PARAMETER command + The command to run on the virtual machine. #> Param ( - [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $vcfPassword, - [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $rootPassword, - [Parameter (Mandatory = $true)] [ValidateSet("general-health", "compute-health", "ntp-health", "password-health", "get-vcf-summary", "get-inventory-info", "get-host-ips", "get-vcf-services-summary")] [String] $sosOption + [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$server, + [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$user, + [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$pass, + [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$vmUser, + [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$vmPass, + [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$command ) - $poshSSH = Resolve-PSModule -moduleName "Posh-SSH" # POSH module is required, if not present skipping - if ($poshSSH -eq "ALREADY_IMPORTED" -or $poshSSH -eq "IMPORTED" -or $poshSSH -eq "INSTALLED_IMPORTED") { - # Expected sudo prompt from SDDC Manager for elevated commands. - $sudoPrompt = "[sudo] password for vcf" - # Validate if the SDDC Manager vcf password parameter is passed. If not, prompt the user and then build vcfCreds PSCredential object. - if ( -not $PsBoundParameters.ContainsKey("vcfPassword") ) { - Write-Output "Please provide the SDDC Manager vcf user password:" - $vcfSecuredPassword = Read-Host -AsSecureString - $vcfCred = New-Object System.Management.Automation.PSCredential ('vcf', $vcfSecuredPassword) - } else { - # Convert the clear text input password to secure string. - $vcfSecuredPassword = ConvertTo-SecureString $vcfPassword -AsPlainText -Force - # Build credential object. - $vcfCred = New-Object System.Management.Automation.PSCredential ('vcf', $vcfSecuredPassword) - } - # Validate if the SDDC Manager root password parameter is passed. If not, prompt the user and then build rootCreds PSCredential object. - if ( -not $PsBoundParameters.ContainsKey("rootPassword") ) { - Write-Output "Please provide the root credential to run elevated commands in SDDC Manager:" - $rootSecuredPassword = Read-Host -AsSecureString - $rootCred = New-Object System.Management.Automation.PSCredential ('root', $rootSecuredPassword) - } else { - # Convert the clear text input password to secure string. - $rootSecuredPassword = ConvertTo-SecureString $rootPassword -AsPlainText -Force - # Build credential object. - $rootCred = New-Object System.Management.Automation.PSCredential ('root', $rootSecuredPassword) - } - # Depending on the SoS command, there will be a different pattern to match at the end of the ssh stream output. - switch ($sosOption) { - "general-health" { $sosEndMessage = "For detailed report" } - "compute-health" { $sosEndMessage = "Health Check completed" } - "ntp-health" { $sosEndMessage = "For detailed report" } - "password-health" { $sosEndMessage = "completed" } - "get-inventory-info" { $sosEndMessage = "Health Check completed" } - "get-vcf-summary" { $sosEndMessage = "SOLUTIONS_MANAGER" } - "get-host-ips" { $sosEndMessage = "Health Check completed" } - "get-vcf-services-summary" { $sosEndMessage = "VCF SDDC Manager Uptime" } - } + $vcfWorkloadDomainDetails = Get-VCFWorkloadDomain | Where-Object { $_.type -eq "MANAGEMENT" } + $vcenterServerDetails = Get-VCFvCenter | Where-Object { $_.fqdn -eq $vcfWorkloadDomainDetails.vcenters.fqdn } - # Create SSH session to SDDC Manager using vcf user. By default, SSH is disabled for the root account. - Try { - $sessionSSH = New-SSHSession -Computer $sddcManager -Credential $vcfCred -AcceptKey - } Catch { - $errorString = ResponseException; Write-Error $errorString + if ($PSVersionTable.PSEdition -eq 'Core') { + if (!($status = Test-Connection -TargetName $vcfWorkloadDomainDetails.vcenters.fqdn -TcpPort 443 -Quiet)) { + Throw "Unable to connect to Management Domain vCenter Server ($vcfWorkloadDomainDetails.vcenters.fqdn)." } - if ($sessionSSH.Connected -eq "True") { - $stream = $SessionSSH.Session.CreateShellStream("PS-SSH", 0, 0, 0, 0, 1000) - # Build the SOS command to run. - $sshCommand = "sudo /opt/vmware/sddc-support/sos " + "--" + $sosOption - # Invoke the SSH stream command. - $outInvoke = Invoke-SSHStreamExpectSecureAction -ShellStream $stream -Command $sshCommand -ExpectString $sudoPrompt -SecureAction $rootCred.Password - if ($outInvoke) { - Write-Output "Running the remote SoS command. Output will display when the the run is completed. This might take a while, please wait..." - $stream.Expect($sosEndMessage) - } - # Destroy the connection previously established. - Remove-SSHSession -SessionId $sessionSSH.SessionId | Out-Null + } elseif ($PSVersionTable.PSEdition -eq 'Desktop') { + $OriginalProgressPreference = $Global:ProgressPreference; $Global:ProgressPreference = 'SilentlyContinue' + if (!($status = Test-NetConnection -ComputerName $vcfWorkloadDomainDetails.vcenters.fqdn -Port 443 -WarningAction SilentlyContinue)) { + $Global:ProgressPreference = $OriginalProgressPreference + Throw "Unable to connect to Management Domain vCenter Server ($vcfWorkloadDomainDetails.vcenters.fqdn)." } + $Global:ProgressPreference = $OriginalProgressPreference + } + + $vcfDetail = Get-VCFRelease -domainId $vcfWorkloadDomainDetails.id + + if ( ($vcfDetail.version).Split("-")[0] -ge "4.5.0.0") { + $pscCredentialDetails = Get-VCFCredential | Where-Object { $_.resource.resourceType -eq "PSC" -and ($_.username).Split('@')[-1] -eq $vcfWorkloadDomainDetails.ssoName } } else { - Write-Error "PowerShell Module Posh-SSH staus is: $poshSSH. Posh-SSH is required to run this cmdlet. Please install the module and try again." + $pscCredentialDetails = Get-VCFCredential | Where-Object { $_.resource.resourceType -eq "PSC" } + } + + Connect-VIServer -Server $vcenterServerDetails.fqdn -User $pscCredentialDetails.username -Password $pscCredentialDetails.password -WarningAction SilentlyContinue | Out-Null + + if ($DefaultVIServer.Name -ne $vcenterServerDetails.fqdn) { + Throw "Unable to authenticate to Management Domain vCenter Server ($vcfWorkloadDomainDetails.vcenters.fqdn), check credentials and try again." + } + + Try { + $output = Invoke-VMScript -VM ($server.Split(".")[0]) -ScriptText $command -GuestUser $vmUser -GuestPassword $vmPass -Server $vcenterServerDetails.fqdn + $output + } Catch { + throw "Error executing command: $_" + } Finally { + Disconnect-VIServer -Server $vcenterServerDetails.fqdn -Confirm:$false -WarningAction SilentlyContinue | Out-Null } } Export-ModuleMember -Function Invoke-VCFCommand -#EndRegion SoS Operations + +#EndRegion Utility Functions (Exported) #Region Utility Functions (Not Exported) diff --git a/docs/documentation/functions/other/Invoke-VCFCommand.md b/docs/documentation/functions/other/Invoke-VCFCommand.md new file mode 100644 index 00000000..9dcf10a7 --- /dev/null +++ b/docs/documentation/functions/other/Invoke-VCFCommand.md @@ -0,0 +1,127 @@ +# Invoke-VCFCommand + +## Synopsis + +Run a command on SDDC Manager. + +## Syntax + +```powershell +Invoke-VCFCommand [-server] [-user] [-pass] [-vmUser] [-vmPass] [-command] [] +``` + +## Description + +The `Invoke-VCFCommand` cmdlet runs a command within the SDDC Manager appliance. + +## Examples + +### Example 1 + +```powershell +Invoke-VCFCommand -server sfo-vcf01.sfo.rainpole.io -user admin@local -pass VMw@re1!VMw@re1! -vmUser vcf -vmPass VMw@re1! -command "echo Hello World." +``` + +This example runs the command provided on the SDDC Manager appliance as the `vcf` user. + +## Parameters + +### -server + +The fully qualified domain name of the SDDC Manager. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -user + +The username to authenticate to the SDDC Manager. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -pass + +The password to authenticate to the SDDC Manager. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -vmUser + +The username to authenticate to the virtual machine. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -vmPass + +The password to authenticate to the virtual machine. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 5 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -command + +The command to run on the virtual machine. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 6 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### Common Parameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). diff --git a/docs/documentation/functions/sos/Invoke-VCFCommand.md b/docs/documentation/functions/sos/Invoke-VCFCommand.md deleted file mode 100644 index ada99504..00000000 --- a/docs/documentation/functions/sos/Invoke-VCFCommand.md +++ /dev/null @@ -1,91 +0,0 @@ -# Invoke-VCFCommand - -## Synopsis - -Connects to the specified SDDC Manager using SSH and invoke SSH commands (SoS). - -## Syntax - -```powershell -Invoke-VCFCommand [[-vcfPassword] ] [[-rootPassword] ] [-sosOption] [] -``` - -## Description - -The `Invoke-VCFCommand` cmdlet connects to the specified SDDC Manager over SSH using the `vcf` user and subsequently run elevated SOS commands using the `root` account. - -???+ note "Note" - - The `Invoke-VCFCommand` cmdlet requires the `POSH-SSH` module to be installed. - -## Examples - -### Example 1 - -```powershell -Invoke-VCFCommand -vcfpassword VMware1! -rootPassword VMware1! -sosOption general-health -``` - -This example will run and display the output of "/opt/vmware/sddc-support/sos --general-health". - -### Example 2 - -```powershell -Invoke-VCFCommand -sosOption general-health -``` - -This example will ask for vcf and root password to the user and then run and display the output of "/opt/vmware/sddc-support/sos --general-health". - -## Parameters - -### -vcfPassword - -{{ Fill vcfPassword Description }} - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: False -Position: 1 -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -rootPassword - -{{ Fill rootPassword Description }} - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: False -Position: 2 -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -sosOption - -{{ Fill sosOption Description }} - -```yaml -Type: String -Parameter Sets: (All) -Aliases: - -Required: True -Position: 3 -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### Common Parameters - -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). diff --git a/mkdocs.yml b/mkdocs.yml index 2330a6cd..96ef2701 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -278,7 +278,6 @@ nav: - documentation/functions/sos/Get-VCFHealthSummaryTask.md - documentation/functions/sos/Request-VCFHealthSummaryBundle.md - documentation/functions/sos/Start-VCFHealthSummary.md - - documentation/functions/sos/Invoke-VCFCommand.md - Support Bundles: - documentation/functions/sos/Get-VCFSupportBundleTask.md - documentation/functions/sos/Request-VCFSupportBundle.md @@ -312,6 +311,8 @@ nav: - documentation/functions/aria-suite/aria-operations-logs/Set-VCFVrliConnection.md - Workspace ONE Access: - documentation/functions/aria-suite/workspace-one-access/Get-VCFWsa.md + - Other: + - documentation/functions/other/Invoke-VCFCommand.md - Community: - community/index.md - Contributing: community/contributing.md