Skip to content

NullReferenceException on PSShouldProcess Rule. #1539

Closed

Description

Before submitting a bug report:

  • Make sure you are able to repro it on the latest released version
  • Perform a quick search for existing issues to check if this bug has already been reported

Steps to reproduce

I'm using PowerShellBuild and my module was made with Stucco.

I haven't changed the template. And the Analyze task was working fine yesterday.

I can't give steps to reproduce yet, working on it. Could I send someone my zipped module ? Not ready to make my code full public.

If an unexpected error was thrown then please report the full error details using e.g. $error[0] | Select-Object *

PSMessageDetails      : 
Exception             : System.NullReferenceException: Object reference not set to an instance of an object.
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.TryGetShouldProcessValueFromAst(FunctionInfo functionInfo, Boolean& hasShouldProcessSet)
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.SupportsShouldProcess(String cmdName)
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.CheckForSupportShouldProcess()
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.<AnalyzeScript>d__7.MoveNext()
                           at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
                           at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
                           at Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer.<>c__DisplayClass83_1.<AnalyzeSyntaxTree>b__2()
TargetObject          : C:\Users\avezina\gitrepos\etl.devops.serviceManagement\Output\ServiceManagement\0.6.2\Formatting\Deployment.format.ps1
CategoryInfo          : InvalidOperation: (C:\Users\avezin...ment.format.ps1:String) [Invoke-ScriptAnalyzer], NullReferenceException
FullyQualifiedErrorId : RULE_ERROR,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at Test-PSBuildScriptAnalysis, C:\Users\avezina\Documents\WindowsPowerShell\Modules\PowerShellBuild\0.4.0\Public\Test-PSBuildScriptAnalysis.ps1: line 31
                        at <ScriptBlock>, C:\Users\avezina\Documents\WindowsPowerShell\Modules\PowerShellBuild\0.4.0\psakeFile.ps1: line 66
                        at Invoke-Task, C:\Users\avezina\Documents\WindowsPowerShell\Modules\psake\4.8.0\public\Invoke-Task.ps1: line 108
                        at <ScriptBlock>, C:\Users\avezina\Documents\WindowsPowerShell\Modules\psake\4.8.0\public\Invoke-psake.ps1: line 300
                        at ExecuteInBuildFileScope, C:\Users\avezina\Documents\WindowsPowerShell\Modules\psake\4.8.0\private\ExecuteInBuildFileScope.ps1: line 55
                        at Invoke-psake, C:\Users\avezina\Documents\WindowsPowerShell\Modules\psake\4.8.0\public\Invoke-psake.ps1: line 258
                        at <ScriptBlock>, C:\Users\avezina\gitrepos\etl.devops.serviceManagement\build.ps1: line 42
                        at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}



Environment data

> $PSVersionTable

Name                           Value                                                                                                                                                                                                                       
----                           -----                                                                                                                                                                                                                       
PSVersion                      5.1.19041.1                                                                                                                                                                                                                 
PSEdition                      Desktop                                                                                                                                                                                                                     
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                                                                     
BuildVersion                   10.0.19041.1                                                                                                                                                                                                                
CLRVersion                     4.0.30319.42000                                                                                                                                                                                                             
WSManStackVersion              3.0                                                                                                                                                                                                                         
PSRemotingProtocolVersion      2.3                                                                                                                                                                                                                         
SerializationVersion           1.1.0.1                                                                                                                                                                                                                     


> (Get-Module -ListAvailable PSScriptAnalyzer).Version | ForEach-Object { $_.ToString() }
1.19.0

Activity

  1. rjmholt commented on Jul 7, 2020

    @rjmholt
    Contributor

    From #1538 (comment).

    Here's the relevant code:

    /// <summary>
    /// Attempt to find whether a function has SupportsShouldProcess set based on its AST.
    /// </summary>
    /// <param name="functionInfo">The function info object referring to the function.</param>
    /// <param name="hasShouldProcessSet">True if SupportsShouldProcess is set, false if not. Value is not valid if this method returns false.</param>
    /// <returns>True if a value for SupportsShouldProcess was found, false otherwise.</returns>
    private bool TryGetShouldProcessValueFromAst(FunctionInfo functionInfo, out bool hasShouldProcessSet)
    {
    // Get the body of the function
    ScriptBlockAst functionBodyAst = (ScriptBlockAst)functionInfo.ScriptBlock.Ast.Find(ast => ast is ScriptBlockAst, searchNestedScriptBlocks: false);
    // Go through attributes on the parameter block, since this is where [CmdletBinding()] will be
    foreach (AttributeAst attributeAst in functionBodyAst.ParamBlock.Attributes)
    {
    // We're looking for [CmdletBinding()]
    if (!attributeAst.TypeName.FullName.Equals("CmdletBinding", StringComparison.OrdinalIgnoreCase))
    {
    continue;
    }
    foreach (NamedAttributeArgumentAst namedArgumentAst in attributeAst.NamedArguments)
    {
    // We want [CmdletBinding(SupportsShouldProcess)]
    if (!namedArgumentAst.ArgumentName.Equals("SupportsShouldProcess", StringComparison.OrdinalIgnoreCase))
    {
    continue;
    }
    // [CmdletBinding(SupportsShouldProcess)] is the same as [CmdletBinding(SupportsShouldProcess = $true)]
    if (namedArgumentAst.ExpressionOmitted)
    {
    hasShouldProcessSet = true;
    return true;
    }
    // Otherwise try to get the value assigned to the parameter, and assume false if value cannot be determined
    try
    {
    hasShouldProcessSet = LanguagePrimitives.IsTrue(
    Helper.GetSafeValueFromExpressionAst(
    namedArgumentAst.Argument));
    }
    catch
    {
    hasShouldProcessSet = false;
    }
    return true;
    }
    }
    hasShouldProcessSet = false;
    return false;
    }

  2. avezinaATastus commented on Jul 7, 2020

    @avezinaATastus
    Author

    After looking at my version control,

    • June 29th
      • My Machine : Doesn't work today (pretty sure it worked back then)
      • AzureDevOps Pipeline (windows-latest) : Works
    • July 5th
      • My Machine : Doesn't work
      • AzureDevOps Pipeline (windows-latest) : Worked

    EDIT : I wasn't analyzing checked-in code. ignore this comment.

  3. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    Using 1.18.0, I have better details about the error, I think.

    writeErrorStream      : True
    PSMessageDetails      :
    Exception             : System.Management.Automation.RuntimeException: The following exception occurred while constructing the attribute "ServerTransformAttribute": "Value cannot be null.
                            Parameter name: key" ---> System.ArgumentNullException: Value cannot be null.
                            Parameter name: key
                               at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
                               at System.Runtime.CompilerServices.ConditionalWeakTable`2.TryGetValue(TKey key, TValue& value)
                               at ServerTransformAttribute..ctor()
                               at CallSite.Target(Closure , CallSite , Object )
                               at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
                               --- End of inner exception stack trace ---
                               at System.Management.Automation.Language.Compiler.GetAttribute(AttributeAst attributeAst)
                               at System.Management.Automation.Language.Compiler.GetRuntimeDefinedParameter(ParameterAst parameterAst, Boolean& customParameterSet, Boolean& usesCmdletBinding)
                               at System.Management.Automation.Language.Compiler.GetParameterMetaData(ReadOnlyCollection`1 parameters, Boolean automaticPositions, Boolean& usesCmdletBinding)
                               at System.Management.Automation.CompiledScriptBlockData.InitializeMetadata()
                               at System.Management.Automation.ScriptBlock.get_Attributes()
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.SupportsShouldProcess(String cmdName)
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.CheckForSupportShouldProcess()
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.<AnalyzeScript>d__7.MoveNext()
                               at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
                               at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer.<>c__DisplayClass83_1.<AnalyzeSyntaxTree>b__2()
    TargetObject          : C:\Users\avezina\gitrepos\etl.devops.serviceManagement\Output\ServiceManagement\0.6.2\Public\Update-mdbDeployment.ps1
    CategoryInfo          : InvalidOperation: (C:\Users\avezin...bDeployment.ps1:String) [Invoke-ScriptAnalyzer], RuntimeException
    FullyQualifiedErrorId : RULE_ERROR,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand
    ErrorDetails          :
    InvocationInfo        : System.Management.Automation.InvocationInfo
    ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    PipelineIterationInfo : {0, 1}

    ServerTransformAttribute is a ArgumentTransformationAttribute derived class. I have two other very similar.

  4. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    I tried doing that function TryGetShouldProcessValueFromAst in powershell, and I did not have a problem.

    **********************
    Windows PowerShell transcript start
    Start time: 20200708104529
    Username: \avezina
    RunAs User: \avezina
    Configuration Name: 
    Machine: PC-INFO3 (Microsoft Windows NT 10.0.19041.0)
    Host Application: powershell.exe
    Process ID: 15884
    PSVersion: 5.1.19041.1
    PSEdition: Desktop
    PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.19041.1
    BuildVersion: 10.0.19041.1
    CLRVersion: 4.0.30319.42000
    WSManStackVersion: 3.0
    PSRemotingProtocolVersion: 2.3
    SerializationVersion: 1.1.0.1
    **********************
    Transcript started, output file is ./test
    ~\Downloads\0.6.2
    
    ➜
    
    PS>$tokens = $Errors = $null
    ~\Downloads\0.6.2
    
    ➜
    
    PS>$ast = [System.Management.Automation.Language.Parser]::ParseInput(${Function:Get-mdbServer}, [ref]$tokens, [ref]$Errors)
    ~\Downloads\0.6.2
    
    ➜
    
    PS>foreach ($attributeast in $ast.ParamBlock.Attributes) {
        if (-not $attributeast.TypeName.FullName -eq 'CmdletBinding') { continue }
        
        foreach ($namedargumentast in $attributeast.NamedArguments) {
            if (-not $namedargumentast.ArgumentName -eq 'SupportsShouldProcess') { continue }
            if ($namedargumentast.ExpressionOmitted) {
                $hasShouldProcessSet = $true
                return $true
            }
            try {
                $hasShouldProcessSet = $namedargumentast.Argument -eq [bool]::TrueString
            } catch {
                $hasShouldProcessSet = $false
            }
            return $true
        }
        
    }
    True
    ~\Downloads\0.6.2
    
    ➜
    
    PS>$hasShouldProcessSet
    False
    ~\Downloads\0.6.2
    
    ➜
    
    PS>Stop-Transcript
    **********************
    Windows PowerShell transcript end
    End time: 20200708104550
    **********************
    
  5. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    I suspect the error you're seeing in 1.18 was fixed in #1397.

    I would be nice to work out what's causing the NRE here though.

    Does this happen consistently, and if so, can you pinpoint a change in your own script that causes it? If you roll back to a particular script change, does this error stop occurring?

  6. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    Here is the weird thing now :
    I went back to my June 29 commit. ( before implementing my three ArgumentTransformationAttribute derived class ( [Server | Service | Environment]TransformAttribute ) )
    And I am getting an error using 1.18.0 and 1.19.0

    
    writeErrorStream      : True
    PSMessageDetails      : 
    Exception             : System.Management.Automation.RuntimeException: The following exception occurred while 
                            constructing the attribute "EnvironmentTransformAttribute": "Value cannot be null.
                            Parameter name: key" ---> System.ArgumentNullException: Value cannot be null.
                            Parameter name: key
                               at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
                               at System.Runtime.CompilerServices.ConditionalWeakTable`2.TryGetValue(TKey key, TValue& 
                            value)
                               at EnvironmentTransformAttribute..ctor()
                               at CallSite.Target(Closure , CallSite , Object )
                               at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
                               --- End of inner exception stack trace ---
                               at System.Management.Automation.Language.Compiler.GetAttribute(AttributeAst attributeAst)
                               at System.Management.Automation.Language.Compiler.GetRuntimeDefinedParameter(ParameterAst 
                            parameterAst, Boolean& customParameterSet, Boolean& usesCmdletBinding)
                               at 
                            System.Management.Automation.Language.Compiler.GetParameterMetaData(ReadOnlyCollection`1 
                            parameters, Boolean automaticPositions, Boolean& usesCmdletBinding)
                               at System.Management.Automation.CompiledScriptBlockData.InitializeMetadata()
                               at System.Management.Automation.ScriptBlock.get_Attributes()
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.Suppo
                            rtsShouldProcess(String cmdName)
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.Check
                            ForSupportShouldProcess()
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules.UseShouldProcessCorrectly.<Anal
                            yzeScript>d__7.MoveNext()
                               at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
                               at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
                               at Microsoft.Windows.PowerShell.ScriptAnalyzer.ScriptAnalyzer.<>c__DisplayClass83_1.<Analyz
                            eSyntaxTree>b__2()
    TargetObject          : C:\Users\avezina\gitrepos\etl.devops.serviceManagement\Output\ServiceManagement\0.4.0\Public\U
                            pdate-mdbDeployment.ps1
    CategoryInfo          : InvalidOperation: (C:\Users\avezin...bDeployment.ps1:String) [Invoke-ScriptAnalyzer], 
                            RuntimeException
    FullyQualifiedErrorId : RULE_ERROR,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand
    ErrorDetails          : 
    InvocationInfo        : System.Management.Automation.InvocationInfo
    ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    PipelineIterationInfo : {0, 1}
    
    
    

    I'm currently not sure if I was always analyzing (but my runs in Azure DevOps seems to) but I will try to check.

    The two 'big' changes in my code since the 29th is "PSTypeNames implementation and formatting" and the argument transformation I finished sunday.

  7. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    It looks like PowerShell is trying to reconstruct your attribute and is unable to because one of the parameters required to construct it is null. Are you sure you're using your attribute right?

    It seems like PSScriptAnalyzer needs to protect itself here -- we should add a try/catch around the Attributes property reference allowing us to just skip the attributes. Because PowerShell throws here when accessing all attributes, it means we can't selectively skip over attributes, but that's just how things are I think.

  8. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    I tried to clean up my PS environment in VSCode. Went back even earlier and uninstalled PSSA 1.18.0

    My module : no more ArgumentTransformationAttributes, no more pstypenames.

    Made also sure that I don't use SupportsShouldProcess anywhere (not needed for now)

    I am back to the NRE.

  9. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    I am back to the NRE.

    The original one that you reported in the description? Does it happen every time you run PSSA?

  10. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    yes
    yes

    I can privately send my zipped module, if you'd like.

  11. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    Yeah I think that's the right next step. Can you send it through to psscriptanalyzer@microsoft.com

  12. 3 remaining items

  13. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    Multiple ways.

    Mostly via my psake task, but also manually.

    I could repro by

    Set-Location ~\Downloads\ServiceManagement\0.6.2
    Invoke-ScriptAnalyzer -Path . -Recurse
  14. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    arghh, didn't want to close.

  15. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    oh fuck. it is my machine.
    Calisse que j'haïs ça.

    Just tested in an "almost fresh" windows VM. Installed PSSA@1.19, ran Invoke-ScriptAnalyzer -Path . -Recurse and it worked.

    Thanks for helping!
    fuck

  16. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    Now, I gotta find what is causing that.

    Could it be that I have some version of my module installed ? EDIT : Nope

  17. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    Final edit
    I had my module still installed. (That damn PS5 bug with the classes)
    Removed it, made sure it wasn't installed anymore.
    Closed VSCode. Reopened VSCode.
    My Analyze task now works, no PSSA errors.

    Thanks again for your help and patience.

  18. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    From the stack traces you've reported, I'm thinking that there is a bug in PSSA here as well as one in PowerShell. The key is being able to reproduce without VSCode though. If you can just use Invoke-ScriptAnalyzer in an ordinary PowerShell prompt and reproduce it, that would be really helpful

  19. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    I have been able to do that.

    Just tried this, and I got the NREs

    I re-installed my module (from my private azdo artifact nuget feed).

    install-module ServiceManagement -Repository TestFeed -Credential (Find-Credential AzDoPat*) -RequiredVersion 0.6.2
    Set-Location ~\Downloads\ServiceManagement\0.6.2
    Invoke-ScriptAnalyzer -Path . -Recurse

    EDIT:
    And after uninstalling the module (and restarting a new ps session, because of the class), no NRE when invoking the analysis

  20. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    If you try this in PS7 does the issue ever occur?

  21. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    I will need to install it.

    Gonna spin a vm to try.

  22. rjmholt commented on Jul 8, 2020

    @rjmholt
    Contributor

    My thinking is that if you're defining attributes as PS classes, then there are some issues in PS 5.1 with that, as you've alluded to. Bugs like that have been fixed in PS 7, although PSSA should still defend itself from them

  23. avezinaATastus commented on Jul 8, 2020

    @avezinaATastus
    Author

    I have completed the test with PS7.

    I had no errors.

    I will try harder to keep that info in my head.

    Not yet ready to switch to full-time (or part-time) ps7.

  24. webtroter commented on Aug 23, 2021

    @webtroter

    Thank you past me :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions