PowerShell / Operation-Validation-Framework

MIT License
225 stars 32 forks source link

SafeGetValue() method not available in PSv4 #34

Open bwright86 opened 6 years ago

bwright86 commented 6 years ago

The Get-TestFromScript function uses the method call SafeGetValue() against [AST] types. This method does not appear to be available in PSv4 consoles. I also don't see the need to call this method for the logic being performed.

Current Behavior

Method invocation failed because [System.Management.Automation.Language.ArrayLiteralAst] does not contain a method named 'SafeGetValue'.

Possible Solution

Extract tags with $tagElements.Elements.Value, instead of $tagElements.SafeGetValue() https://github.com/PowerShell/Operation-Validation-Framework/blob/0bc93ef8582a8bf66a8899f9295d30aa3d921f68/OperationValidation/Private/Get-TestFromScript.ps1#L43 https://github.com/PowerShell/Operation-Validation-Framework/blob/0bc93ef8582a8bf66a8899f9295d30aa3d921f68/OperationValidation/Private/Get-TestFromScript.ps1#L48

Steps to Reproduce (for bugs)

  1. Build an OVF module with a Simple or Comprehensive test .ps1
  2. Add a tag or multiple tags to the Describe's -Tag parameter
  3. Make the module discoverable by PSModulePath
  4. In a Powershell v4 console, execute the following command: Get-OperationValidation

    Output:

    Method invocation failed because [System.Management.Automation.Language.ArrayLiteralAst] does not contain a method
    named 'SafeGetValue'.
    At C:\Program Files\WindowsPowerShell\Modules\OperationValidation\Private\Get-TestFromScript.ps1:48 char:21
    +                     $item.Tags = $tagElements.SafeGetValue()
    +                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

Context

Attempting to write and use OVF modules in my server environment, and do not currently have PSv5.1 installed.

Your Environment

bwright86 commented 6 years ago

As a side note, it was difficult to find out where the SafeGetValue method was coming from, it could have been an extended attribute added by Powershell to the .Net classes. But that doesn't appear to be the case.

My desktop (Running PSv5) and one of the server (Running PSv4) are loading the same DLL: System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

But digging deeper into the GAC to confirm that the DLL is the same, I found my answer: Desktop - File Version: 10.0.10514.6 Server - File Version: 6.3.9600.18728

Not sure if these DLL's are installed into the GAC by Powershell or .NET Framework install. But there is a difference in the version.

devblackops commented 5 years ago

Thanks for reporting this @bwright86. I'll take a look.

miketheitguy commented 5 years ago

I know this is going to sound a bit crazy, but @bwright86 is there any reason you wouldn't move to PSv5.1 on your servers? There are probably legit reasons, but the benefits are enormous from both a powershell perspective but also a security perspective (better logging, etc.)

I'll see if I can help out with this one but I feel like upgrading is a really, really good idea if you can.

bwright86 commented 5 years ago

Lol, @miketheitguy, it does not sound crazy. We are in the process of upgrading our servers to PSv5.1, but it takes a while for my server team to push it out in all environments.

I can’t wait to realize the benefits of the new version, as I have a few projects on hold that are waiting for this (e.g. PSModule repo, hardening steps, and logging to enable.)

I currently cloned this repo and changed it to support PSv4, so I have been able to run my first infrastructure tests 🙂

But I wanted to raise awareness around that method not being available in older versions of PowerShell or .Net Framework.

Thanks for the response!