<# .SYNOPSIS Checks parameters of a specific command for parameters that should have a value but are not Mandatory. .DESCRIPTION If a parameter is not marked as Mandatory but the intention is for a value to be supplied, this function will look for an alias that begins with the string "Required_". If such an alias is found and the parameter is not bound, this function will throw an exception or set a breakpoint depending on the options supplied. .PARAMETER Context You must pass $MyInvocation.MyCommand as the value of this parameter. .PARAMETER BoundParams You must pass $PSBoundParameters as the value of this parameter. It can also be supplied by pipeline. .PARAMETER SetBreakpoint If this is set, then an exception will not be thrown. Instead, a breakpoint will be set on the line where this function was called. Because that is earlier in the stack however, the breakpoint will not be hit unless the parameter fails validation again. .PARAMETER Debug If you set -Debug with -SetBreakpoint, then the breakpoint info will be written to the Debug stream. .NOTES SetBreakpoint is not well-tested and may not work on scripts that aren't saved to disk. .EXAMPLE $PSBoundParameters | Validate-MandatoryOptionalParameters -Context $MyInvocation.MyCommand .LINK https://www.briantist.com/how-to/throw-exception-on-unbound-mandatory-powershell-parameter/ #> function Validate-MandatoryOptionalParameters { [CmdletBinding()] param( [Parameter( Mandatory=$true )] [System.Management.Automation.CommandInfo] $Context , [Parameter( Mandatory=$true, ValueFromPipeline=$true )] [System.Collections.Generic.Dictionary[System.String,System.Object]] $BoundParams , [Switch] $SetBreakpoint ) Process { foreach($param in $Context.Parameters.GetEnumerator()) { if ($param.Value.Aliases.Where({$_ -imatch '^Required_'})) { if (!$BoundParams[$param.Key]) { if ($SetBreakpoint) { $stack = Get-PSCallStack | Select-Object -Index 1 Set-PSBreakpoint -Line $stack.ScriptLineNumber -Script $stack.ScriptName | Write-Debug } else { throw [System.ArgumentException]"'$($param.Key)' in command '$($Context.Name)' must be supplied by the caller." } } } } } }