When you're writing scripts that are primarily meant for use in continuous integration or deployment environments, a lot of your inputs (maybe all of your inputs) are going to come from environment variables that are always set when you're running the scripts in production (but which rarely exist on your development box). There are a lot of different ways of handling this, but the one I find most elegant is to use PowerShell's dynamic parameter block.
Dynamic parameters in PowerShell have a couple of downsides (which, now that I think of it, we should really see about fixing, since PowerShell is open source).
- The first is that they are not easily discoverable. Even when you're in the conditions where the dynamic parameters will be emitted, they do not show up in either
Get-Help
orGet-Command
(nor even inGet-Parameter
, which does fetch dynamic parameters added by providers, but doesn't find the ones added by the command itself). - The second is that they don't set variables in the function scope. You have to fetch your dynamic parameter values from
$PSBoundParameters
at runtime.
In the case where you're dealing with environment variables set by automation tools, however, they're basically the perfect foil, because these parameters need to be mandatory (in the sense that you must have a value), but they cannot be mandatory (because in real use, they must get their values from the environment).
The example below shows how to add one dynamic parameter which works the same way (in code) whether you provide the value at the command-line or via an environment variable, and prompts as a mandatory parameter when there's no value provided at all. I want to call out a couple of points:
- I wrote
AddEnvironmentalParameter
because it was only 3 lines of code more than not writing it, but now I could create a bunch of these really easy (except for the documentation). - You should consider adding the parameter help to your command's
.DESCRIPTION
the way I did here, so there's some documentation of them - When the dynamic parameter is not mandatory, you must set it's value in
$PSBoundParameters
yourself. You could even skip adding the parameter, if you don't want to support overriding environment variables. - Don't forget the first couple of lines in the begin block (although you can put those in any block), so you can use the parameter as a simple variable the way you normally would