title: Using ValidateScript with custom functions defined later in script
body: <p>Is it possible to use custom functions with <code>ValidateScript</code>, where the function is defined later in the script.
  Additionally, is it possible to reference other parameters when calling this function (i.e. assuming there's no circular dependency)?</p>
  
  <p>I understand why this may not be possible, but as it's something that would be useful I'm hoping MS implemented some special rule to allow the script to be read and function definitions made available prior to the validation of the parameters occurring.</p>
  
  <p>e.g. </p>
  
  <pre><code>#Run-DemoScript.ps1
  param (
      [Parameter(Mandatory = $true)]
      [string]$DbInstance 
      ,
      [Parameter(Mandatory = $true)]
      [string]$DbCatalog 
      ,
      [Parameter(Mandatory = $true)]
  
      #
      # Is this possible; i.e.
      # - Validate-Country is not defined until later in this script
      # - DbInstance and DbCatalog parameters are defined alongside Country
      [ValidateScript({Validate-Country -Country $_ -DbInstance $DbInstance -DbCatalog $DbCatalog})] 
      #
  
  
      [string]$Country
  )
  
  #returns $true if the country is in the database's country table; otherwise false
  function Validate-Country {
      [CmdletBinding()]
      param (
          [Parameter(Mandatory = $true)]
          [string]$DbInstance
          ,
          [Parameter(Mandatory = $true)]
          [string]$DbCatalog
          ,
          [Parameter(Mandatory = $true)]
          [string]$Country
      )
      process {
          $Country = $Country -replace "'","''"
          ((Execute-SQLQuery -DbInstance $DbInstance -DbCatalog $DbCatalog -Query "select top 1 1 x from dbo.Country where Name = '$Country'") | Measure-Object | Select -ExpandProperty Count) -gt 0
      }
  }
  
  function Execute-SQLQuery {
      #...
  }
  
  "Script ran with Country $Country"
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>It seems you can move the whole function definition into the <code>ValidateScript</code> attribute, and can still access that function later in the script; e.g:</p>
  
  <pre><code>param(
      [Parameter(Mandatory = $true)]
      [ValidateScript({
          function IsValid ($test) {
              $test -eq 'test'
          }
          IsValid $_
      })]
      [string]$x
  )
  
  
  "Output: $x"
  "Is Valid? $(IsValid $x)"
  </code></pre>
  
  <p>However that's quite painful.  Also it doesn't allow referencing sibling parameters (e.g. below)</p>
  
  <pre><code>param(
      [Parameter(Mandatory = $true)]
      [string]$y
      ,
      [Parameter(Mandatory = $true)]
      [ValidateScript({
          function IsValid ($a,$b) {
              $a -eq $b
          }
          IsValid $_, $y
      })]
      [string]$x 
  )
  
  
  "X: $x"
  "Y: $Y"
  "Is Valid? $(IsValid $x $y)"
  </code></pre>