PSScriptAnalyzer
PSScriptAnalyzer copied to clipboard
Documentation for implementing rules in a .NET assembly
Apologies if I've just missed something, but I can't seem to find much in the way of documentation for implementing rules in a .NET assembly. I took a stab at it anyway by creating a class that implements IScriptRule, but ScriptAnalyzer can't seem to find it. I just get something like:
Invoke-ScriptAnalyzer : Exception of type 'System.Exception' was thrown.
At line:1 char:1
+ Invoke-ScriptAnalyzer -Path C:\local\test.ps1 -Cu ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceExists: (Microsoft.Windo....ScriptAnalyzer:ScriptAnalyzer) [Invoke-ScriptAnalyzer], Exception
+ FullyQualifiedErrorId : Cannot find ScriptAnalyzer rules in the specified path,Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands.InvokeScriptAnalyzerCommand
I've tried adding an [Export(typeof(IScriptRule))] attribute to my class, but it didn't help.
@mattpwhite you didn't miss anything. Unfortunately, the way to write an external .net assembly rule is not documented and even if you were to write such a rule, it is somewhat cumbersome. But since you have already taken the dive, let me know if this can provide any help. If you have created a dll
that contains the rule, you can set CustomRulePath
to point that dll
. This should make PSSA load the rules in that dll
.
it is somewhat cumbersome.
Yeah, it seems like it might be. I hadn't gotten far enough along to figure out how I might deploy this but it does seem awkward. I had been thinking that I would ship the dll as part of a module, without including the ScriptAnalyzer assembly and declare ScriptAnalyzer as a RequiredModule in the manifest, but hadn't really looked into the details.
This should make PSSA load the rules in that dll
That's what I tried - -CustomRulePath C:\path\to\my.dll
, but I got the error in the original post. I'll try to create a minimal repro and put it up somewhere (assuming it still doesn't work).
If it matters, my desire to do this in C# instead of PS is mostly because I think it's a lot easier to write this type of code in C#. A few generic extension/helper methods can make things a lot easier/more concise when walking up or down an AST and IntelliSense is very helpful when dealing with the dozens of different derived types of AST. PS in VS Code has come a long way, but the IntelliSense is still pretty shaky (to be expected for a dynamic language). I have an existing assembly with cmdlets in it that use the AST APIs for things like code search, stashing the rules in there and taking advantage of the existing utility methods would be preferable to writing the rules in PS.
Well it has been over a year, but I finally took a stab at this.
When I specify by dll with a test IScriptRule
in it (just using Get-ScriptAnalyzerRule
for now, not actually trying to run the rule):
- MEF imports the built-in rules along with the test rule in my dll here: https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Engine/ScriptAnalyzer.cs#L962
- Immediately after that, the
ScriptRules
property containing all of the rules is nulled out: https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Engine/ScriptAnalyzer.cs#L972 - An error is then thrown here because no rules were loaded. https://github.com/PowerShell/PSScriptAnalyzer/blob/development/Engine/ScriptAnalyzer.cs#L817
Either I'm missing something or this is broken because all IScriptRule
s are ignored when a custom rule path is specified.
I am sorry If I have missed anything, has this been fixed(or identified as bug?) in recent versions ? It would be great if we could revisit this in the PSSA 2.0. I am basically looking for a documentation to implement custom rules in .NET, similar to PowerShell.
@bergmeister @SydneyhSmith @rjmholt
@jegannathanmaniganadan According to the previous maintainer it could theoretically be possible to do that right now but you might need to do some work to figure out whether he's right or not... It's definitely not a bug but rather a feature to be implemented and documented properly and already on the team's tracker that they consider to look at in v2
Thanks @bergmeister for the quick response. Let me take a stab at this, mostly over the weekend.
Looks like the Exception of type 'System.Exception' was thrown.
exception is still occurring when an attempt is made to run rules defined in an assembly when -IncludeDefaultRules
is false
, presumably due to the rules being cleared immediately here as pointed out by @mattpwhite.