inspec / train

Transport Interface to unify communication over SSH, WinRM, and friends.
Apache License 2.0
119 stars 89 forks source link

Transports to detect PowerCLI Version causes a logic issue. PowerShell Core (PWSH) + Offline Environment #725

Open HerbBoy opened 2 years ago

HerbBoy commented 2 years ago

Version:

4.52.9

Environment:

PowerCLI Version: 12.5.0.19195797 OS: RHEL 8.4 PowerShell Core Version: 7.2.1-1.rh

Scenario:

This appeared in an offline, highside env. All dependencies already present (inspec, powershell core).

I first tried to import the library.

Import-Module vmware.powercli
...
Exception: The VMware.ImageBuilder module is not currently supported on the Core edition of PowerShell.

After that did not work, I just copied over the structure and placed the VMware.PowerCLI and all its dependencies into /root/.local/share/powershell/Modules/

After I did that I was able to run PowerCLI commands. Connect to a server etc.

However I get the following error from InSpec

Unable to determine PowerCLI Module version, is it installed?

The file in question: /opt/inspec/embedded/lib/ruby/gems/2.7.0/gems/train-3.8.6/lib/train/transports/vmware.rb

The issue is how the logic is handled to identify the PowerCLI version:

version_command = "[string](Get-Module -Name VMware.PowerCLI -ListAvailable | Select -ExpandProperty Version)"

If this is switched to:

version_command = "[string](Get-InstalledModule -Name VMware.PowerCLI | Select -ExpandProperty Version)"

This will work regardless of if it was installed or imported, or the files placed in the module directories.

However changing this then makes the actual stdout to contain data that breaks the logic currently in place to capture the return code sent from stdin.

PS /root>> inspec exec ./vmware-vsphere-esxi-7.0-stig-baseline -t vmware:// --input vmhostName=192.168.1.62
here1
[string](Get-InstalledModule -Name VMware.PowerCLI | Select -ExpandProperty Version)
12.4.1.18769701
PS /root>
here2
ion)
12.4.1.18769701
PS /root>
here3
ion)
12.4.1.18769701
here4
echo $?
True
PS /root>
here5
o $?
True
PS /root>
here6
o $?
True
#<struct Train::Extras::CommandResult stdout="ion)\n\e[?1l12.4.1.18769701\n", stderr="", exit_status=1>
Unable to determine PowerCLI Module version, is it installed?

As you can see from the above output, "ion)" remains in the stdout which is actually from the initial command containing the last 5 characters of the word "Version"

This could be solved by changing the logic used to parse out the return code.

Steps to Reproduce:

1. Offline Environment with no access to a PowerShell Repository (PowerShell Core)
2. Bring over the PowerCLI Modules and place into /root/.local/share/powershell/Modules/
3. Run a Connect-VIServer or whatever command to validate it is installed
4. Run ESXi InSpec Profile from https://github.com/vmware/dod-compliance-and-automation

Expected Result:

For this to function without issue as it does when modules are installed or imported.

Actual Result:

Fails

HerbBoy commented 2 years ago

Update: PowerShell Core Version: 7.2.1-1.rh appeared to be the root cause of this issue.

Downgrading back to PowerShell Core Version: 7.2.0-1.rh InSpec works without modification to the transport vmware.rb module.

However, I am not sure if this means it is an issue with PowerShell or still the way InSpec train is parsing the stdout stdin and stderr.

Keeping this open for the time being.

HerbBoy commented 2 years ago

Please see https://github.com/PowerShell/PowerShell/issues/17020

HerbBoy commented 2 years ago

is there any movement to get this resolved?

HerbBoy commented 2 years ago

bumping again.