en-us/about_ScriptCop_Rules.help.txt

ScriptCop rules can help you detect problems in your scripts, and can even
help you repair them.
 
There are two flavors of ScriptCop rules: Tests and Repairs. Each rule
is a single PowerShell command (either a function or a script file).
 
    To Register a ScriptCop rule, use Register-ScriptCopRule
 
    To Unregister a ScriptCop rule, use Unregister-ScriptCopRule
 
Both Test and Repair functions work by using some very specific parameter set
to pass down information to the command. Any PowerShell function or script
that accepts this set of parameters can be used as a rule in ScriptCop.
 
Any Test can report a problem with the command in a few ways:
 
- It can write an error with information about major problems with command
- It can write a warning with information about minor problems with the command
- It can write a detail message with information about how to fix it
 
Let's take a look at the signatures, and then at some of the examples:
 
The simplest signature that a Test command can have is the TestCommandInfo
 
    [Parameter(ParameterSetName='TestCommandInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.CommandInfo]
    $CommandInfo
     
The CommandInfo object in PowerShell is what comes back from Get-Command. There are 8 types of
CommandInfo objects, and a command that accepts this could report any issue from any one of them.
 
Each of the individual types can also be used as a signature for the Test:
 
TestFunctionInfo (this will only work on functions, not script files)
 
    [Parameter(ParameterSetName='TestFunctionInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.FunctionInfo]
    $FunctionInfo
     
TestScriptInfo (this will only work on script files (.ps1))
 
    [Parameter(ParameterSetName='TestScriptInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.ExternalScriptInfo]
    $ScriptInfo
     
TestCmdletInfo (this will work only on compiled cmdlets)
 
    [Parameter(ParameterSetName='TestCmdletInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.CmdletInfo]
    $CmdletInfo
     
TestApplicationInfo (this will work on PowerShell module (.psm1), PowerShell data (.psd1) or other files)
 
    [Parameter(ParameterSetName='TestApplicationInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.ApplicationInfo]
    $ApplicationInfo
 
You can also make a rule that returns information about a module:
 
    [Parameter(ParameterSetName='TestModuleInfo',Mandatory=$true,ValueFromPipeline=$true)]
    [Management.Automation.PSModuleInfo]
    $ModuleInfo
 
Each of these simple types leaves open a lot of possibility, but requiring that all
rules conform to these signatures doesn't help us write rules that are fast.
 
For instance, if you need to write a lot of rules that used help content, those rules
would be very slow to run because each rule would need to continue to get the help content
 
To make rules that do advanced things (like interact with help content or tokenize the script) can use
some more advanced parameter sets:
 
TestScriptToken will only be passed tokens from complete PowerShell scripts.
 
    [Parameter(ParameterSetName='TestScriptToken',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.PSToken[]]
    $ScriptToken,
     
    [Parameter(ParameterSetName='TestScriptToken',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.CommandInfo]
    $ScriptTokenCommand,
     
    [Parameter(ParameterSetName='TestScriptToken',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.CommandInfo]
    $ScriptText,
     
 
TestHelpContent will be passed a sumarized help object (the result of Get-Help)
 
    [Parameter(ParameterSetName='TestHelpContent',ValueFromPipelineByPropertyName=$true)]
    $HelpContent,
     
    [Parameter(ParameterSetName='TestHelpContent',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.CommandInfo]
    $HelpCommand
 
     
     
The signature for a repair function is a lot simpler.
 
Each repair requires three pieces of data, which are returned from Test-Command.
 
    # The error parameter contains the error returned from a test
    [Parameter(ParameterSetName='RepairScriptCopIssue',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.ErrorRecord]
    $ScriptCopError,
     
    [Parameter(ParameterSetName='RepairScriptCopIssue',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [Management.Automation.CommandInfo]
    $Rule,
     
    [Parameter(ParameterSetName='RepairScriptCopIssue',Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [PSObject]
    $Source,
         
    [Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$true)]
    [Switch]
    $Silent,
     
    [Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$true)]
    [Switch]
    $WhatIf,
     
    [Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$true)]
    [Switch]
    $Confirm
     
The error parameter contains the error returned from a test
 
The rule parameter contains the rule that generated the error
 
The source parameter contains the command or module that generated the error
 
The silent parameter indicates if the test can interact with the user.
     
While the variety of signatures that you can use to write a ScriptCop rule are quite complicated,
writing one isn't.
 
You write a function that uses one or more of the parameter sets above. Your put it into the Rules directory.
 
Then it is a scriptcop rule.
 
When ScriptCop is run, it will run each function you've registered. If that function outputs an error,
then ScriptCop displays that error to the user.
 
To see a few concrete examples, run:
 
    Get-Help writing_a_scriptcop_rule.walkthru