To Unregister a ScriptCop rule, use Unregister-ScriptCopRuleBoth 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]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]TestScriptInfo (this will only work on script files (.ps1))
[Parameter(ParameterSetName='TestScriptInfo',Mandatory=$True,ValueFromPipeline=$True)] [Management.Automation.ExternalScriptInfo]TestCmdletInfo (this will work only on compiled cmdlets)
[Parameter(ParameterSetName='TestCmdletInfo',Mandatory=$True,ValueFromPipeline=$True)] [Management.Automation.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]You can also make a rule that returns information about a module:
[Parameter(ParameterSetName='TestModuleInfo',Mandatory=$True,ValueFromPipeline=$True)] [Management.Automation.PSModuleInfo]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[]] ,
[Parameter(ParameterSetName='TestScriptToken',Mandatory=$True,ValueFromPipelineByPropertyName=$True)] [Management.Automation.CommandInfo] ,
[Parameter(ParameterSetName='TestScriptToken',Mandatory=$True,ValueFromPipelineByPropertyName=$True)] [Management.Automation.CommandInfo] ,TestHelpContent will be passed a sumarized help object (the result of Get-Help)
[Parameter(ParameterSetName='TestHelpContent',ValueFromPipelineByPropertyName=$True)] ,
[Parameter(ParameterSetName='TestHelpContent',Mandatory=$True,ValueFromPipelineByPropertyName=$True)] [Management.Automation.CommandInfo]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] ,
[Parameter(ParameterSetName='RepairScriptCopIssue',Mandatory=$True,ValueFromPipelineByPropertyName=$True)] [Management.Automation.CommandInfo] ,
[Parameter(ParameterSetName='RepairScriptCopIssue',Mandatory=$True,ValueFromPipelineByPropertyName=$True)] [PSObject] ,
[Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$True)] [Switch] ,
[Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$True)] [Switch] ,
[Parameter(ParameterSetName='RepairScriptCopIssue',ValueFromPipelineByPropertyName=$True)] [Switch]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