Home
Join
check
  • You could probably use the Abstract Syntax Tree of PowerShell, here's an example

    https://chrislgardner.dev/powershell/2018/08/22/finding-default-parameter-values.htmlOpens a new window

    Out of curiousity, the last example seems to provide what you're asking? How would you like it to be different?

    Pepper graySpice (1) flagReport
    1 found this helpful thumb_up thumb_down
  • View Best Answer in replies below

    8 Replies

    • Powershell
      $no_param = test
      $param = test @{char = 'b'}
      
      if ($no_param.char -eq $param.char) {write-host 'same'} else {write-host 'not same'}
      

      Default values don't exist as soon as the optional parameter is specified. You can call the function again to get default values.

      Pepper graySpice (1) flagReport
      Was this post helpful? thumb_up thumb_down
    • Zed, thanks for the reply. Unfortunately, you can't reference the parameter by dot notation. ​Calling the function within itself would cause a loop without something to break out of it as well. If I were to go that route of $param -eq $no_param, an output would be needed to compare the values. Unless I'm mistaking what you've meant?

      Closest I've got to what I wanted is parsing the definition using RegEx:

      Text
      (Get-Command -Name test).Definition -match '(?s)(?<=\$hashmap = )(@{.*(?=}))}'
      
      iex $Matches[0]
      

      I just figured there would've been a simpler way.

      • local_offer Tagged Items
      • Tag by ZedZed
      Was this post helpful? thumb_up thumb_down
    • Well, if you're trying to do the comparison within the parameter and your default values are hardcoded within the parameter, you could just compare to that.

      Powershell
      if ($hashmap.char -eq 'a') {}
      

      It will cut down on the reusability of the code but it's the simplest way to do it.

      You could add a second parameter for defaults.

      Pepper graySpice (1) flagReport
      Was this post helpful? thumb_up thumb_down
    • Ahh, I see what you're getting at. Although I'm looking for more of a dynamic test. The reusability I've mentioned comes from not wanting to compare new values with static values somewhere else down the line. Using the RegEx above, here's an example of what I am essentially after.

      Here, test -hashmap @{rand='8'} will throw an error:

      Powershell
      function test {
      [CmdletBinding()]
          Param(
              [parameter(Mandatory=$false)]
              [hashtable]$hashmap = @{
                  char = 'a'
                  num  = 2
                  bool = $true
              }
          )
          BEGIN 
          {
              $default_values = 
                  (Get-Command -Name $MyInvocation.MyCommand.Name).Definition -match '(?s)(?<=\$hashmap = @{).*?(?=})' | 
                      ForEach-Object -Process { Invoke-Expression -Command "@{$($Matches[0])}" }
          }
          PROCESS
          {
              if ($PSBoundParameters.ContainsKey('hashmap'))
              {
                  $PSBoundParameters.Values.Keys | 
                      ForEach-Object -Process {
                          if ($_ -notin $default_values.keys) { throw "$_ not in `$default" }
                          else { $_ }
                      }
              }
          }
      }
      
      Was this post helpful? thumb_up thumb_down
    • You could probably use the Abstract Syntax Tree of PowerShell, here's an example

      https://chrislgardner.dev/powershell/2018/08/22/finding-default-parameter-values.htmlOpens a new window

      Out of curiousity, the last example seems to provide what you're asking? How would you like it to be different?

      Pepper graySpice (1) flagReport
      1 found this helpful thumb_up thumb_down
    • You can also test for a keys existence via $default_values["$_"] i.e.

      Powershell
      if ($null -eq $default_values["$_"]) {throw "$_ not in `$default"}
      
      Was this post helpful? thumb_up thumb_down
    • saidbrandon​, pardon the tardy response. I was actually looking to AST in form of the automatic variable of $ast, but using the PS Parser didn't occur to me. I marked it as the answer because it is basically what I was initially after. I ended up going [System.Management.Automation.Language.Parser] rather, but still in the same ball park.

      The below is what I came up with if anyone is interested; I also didn't care about anything other command types besides functions so it only works with that:

      Powershell
      Function Get-ParameterValues {
      [outputtype([PSCustomObject])]   
          Param(
              [Parameter(Mandatory=$true,
                         ValueFromPipelineByPropertyName=$true)]
              [string[]]$Name
          )
          BEGIN
          {
              function clearref {
                  $cmdlet,$errors,$tokens = $null
              }
              $parameter_name  = [System.Collections.ArrayList]::new()
              $parameter_value = [System.Collections.ArrayList]::new()
              $parameter_type  = [System.Collections.ArrayList]::new()
          }
          PROCESS
          {
              foreach ($command in $Name)
              {
                  try
                  {
                      clearref 
                      $(
                          if ($resolved = ($actual = Get-Command -Name $command -ErrorAction 'Stop').ResolvedCommand)
                          {
                              Write-Verbose -Message "Alias provided: [$command]"
                              $resolved
                          }
                          else {
                              $actual
                          }
                      ) | Set-Variable -Name 'cmdlet'
                      
                      if ($cmdlet.CommandType -ne 'Function')
                      {
                          Write-Warning -Message "Unable to parse command of type: [$($cmdlet.CommandType)]."
                          Remove-Variable -Name 'cmdlet'
                          Break
                      }
                      else 
                      {
                          $ps_AST = [System.Management.Automation.Language.Parser]::ParseInput($cmdlet.Definition, [ref]$tokens, [ref]$errors)
                          foreach ($parameter in $ps_AST.ParamBlock.Parameters)
                          {
                              $null = $parameter_name.Add($parameter.Name.VariablePath.UserPath)
                              $null = $parameter_value.Add($parameter.DefaultValue.Extent.Text) 
                              $null = $parameter_type.Add($parameter.StaticType.FullName)
                          }
                      }
                  }
                  catch { $_ }
                  finally 
                  { 
                      if ($cmdlet) 
                      { 
                          for ($i = 0; $i -lt [math]::Max($parameter_name.Count,$parameter_value.Count); $i++)
                          {
                              [PSCustomObject]@{
                                  FunctionName   = @($cmdlet.Name)[$i]
                                  ParameterName  = $parameter_name[$i]
                                  ParameterType  = $parameter_type[$i]                            
                                  ParameterValue = $parameter_value[$i] 
                              }
                          } #end for-loop
                      } #endif
                  } #end finally
              } #end foreach-loop
          }
          END { }
      }
      
      1 found this helpful thumb_up thumb_down
    • saidbrandon​, also regarding the example I used that provided a solution. I was trying to avoid having to come up with a RegEx patterns to parse for parameters of different types. I only had accounted for a hashtable but doesn't mean that's all I was going to use. This way it's more of a dynamic approach.

      Was this post helpful? thumb_up thumb_down

    Read these next...

    • Simple command to monitor Windows 10 temperature?

      Simple command to monitor Windows 10 temperature?

      Hardware

      I feel like this has probably been address before, although I was wondering if someone is aware of a simple command I can run to report the internal temperature of a Windows 10 PC?I think all computers monitor the temperature, although I've only found thi...

    • Remote access to DVR?

      Remote access to DVR?

      Security

      Hi!I have an older Hikvision DVR that I need to provide remote access to. The users would be mainly accessing it from their smartphones. I tested their software, iVMS, by assigning one of my public IP's to the DVR and it worked fine. However the issue is ...

    • Snap! -- Survival Kits, Forest Bubble on Mars, AI Movie Plots, Leprosy & Livers

      Snap! -- Survival Kits, Forest Bubble on Mars, AI Movie Plots, Leprosy & Livers

      Spiceworks Originals

      Your daily dose of tech news, in brief. Welcome to the Snap! Flashback: Back on December 6, 1907, Mathematical Logician J. Barkley Rosser Born (Read more HERE.) Bonus Flashback: Back on December 6, 1998, International Space Station assemb...

    • Spark! Pro Series - 6 December 2022

      Spark! Pro Series - 6 December 2022

      Spiceworks Originals

      Today in History: 6 December 1240 – Mongols led by Batu Khan occupy and destroy Kyiv after an 8 day siege; out of 50,000 people in the city only 2,000 survive 1849 – Harriet Tubman escapes from slavery in Maryl...

    • The most boring but interesting Phishing Attempt I've seen

      The most boring but interesting Phishing Attempt I've seen

      Security

      Hello There,We've recently had a phishy email come through to one of our employees with an attachment to something work related. But here's the interesting part: The email was spoofed. When checked, the address was that of our own domain, however the emai...