0

Summary: I am attempting to structure my script with less redundancy. The issue is that I am having to repeat a function for each switch although the are going to the same destination and accomplishing the same task.

Question: Is it possible to take the switch es age,name and profession and convert it to a single function?

Side Note: I am using a psobject and storing its URI, enumurating that and instantiating the $Search variable as that URI specified to each member in the psobject.

function Search-PersonnelData {
  param(
    [switch]$Name,
    [switch]$Age,
    [switch]$Profession,
    [switch]$All,
    [switch]$Less,
    [switch]$Count,
    [string]$Search,
    [string]$Limit
  )
    if ($Limit.Length -eq 0  -or ($Limit -match $invalidnumber))
    {
      $Limit = 15
      Write-Warning -Message 'Invalid limit specified, setting to 15 by default'
    }

 # HERE IS WHERE I AM REPEATING THE SAME FUNCTION OVER
    # Name Query
    if($Name)
    {
    $searchTerms = Get-QueryType -userinput Name
    $Results = Invoke-RestMethod -Method Get -Uri $apiUrl$searchTerms"?term=$Search&limit=$Limit" -WebSession $currentsession
    }
    # Age Query
    if($Age)
    {
    $searchTerms = Get-QueryType -userinput Age
    $Results = Invoke-RestMethod -Method Get -Uri $apiUrl$searchTerms"?term=$Search&limit=$Limit" -WebSession $currentsession
    }
    # Profession Query
    if($Profession)
    {
      $searchTerms = Get-QueryType -userinput 'Profession'
      $Results = Invoke-RestMethod -Method Get -Uri $apiUrl$searchTerms"?term=$Search&limit=$Limit" -WebSession $currentsession
    }
 ##########################Here is where there repeition ends###############################
    if($Results.DataBase.UUID.Count -eq 0)
    {
      Write-Warning -Message 'No results found'
      break
      }
      if($SignatureCount -eq $true)
      {
        $Results.DataBase| Group-Object | Select-Object -Property count,name -ExcludeProperty RunspaceId
      }
      if($Less -eq $true)
      {
        $Results.DataBase | Select-Object -Property $TableFormat -ExcludeProperty RunspaceId
      }
      if($All -eq $true)
      {
        $Results.DataBase | Select-Object -Property $Gridtable -ExcludeProperty RunspaceId
      }
      if($Count -eq $false -and ($less -eq $false)-and ($all -eq $false))
      {
        $Results.DataBase| Select-Object -Property $TableFormat | Format-Table -AutoSize
        $Results.DataBase | Group-Object | Select-Object -Property count,name -ExcludeProperty RunspaceId | Format-Table -AutoSize
      }
}
$EndPoints = New-Object psobject
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name 'Profession' -Value "by_profession"
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name 'Age' -Value "by_age"
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name Name -Value "by_Name"


function Get-QueryType {
  param(
    $userinput
  )
  $EndPoints.psobject.Members |
  Where-Object {$_.Name -eq $userinput } |
  ? {$_.Membertype -eq "noteproperty"} | 
  %{ $_.Value }
}
2
  • 1
    Are Name, Age, and Profession searches supposed to be mutually exclusive? It looks like you are going to overwrite $results if you have multiple switches. So it looks like you would want to use parameter sets and then do a switch statement on which set you use. Commented Mar 3, 2017 at 14:42
  • @BenH yes that is correct those switches are to be mutually exclusive. Is this the best possible structure for my script though? I feel like those functions are totally redundant and flawed. Commented Mar 3, 2017 at 14:47

2 Answers 2

3

So I would propose you use a hashtable to do the lookups:

function Search-PersonnelData {
    param(
        [ValidateSet('Name', 'Age', "Profession")]
        [string]$queryType,
        ...
    )
    ...

    $hashtable = @{
        "Name"          = "by_name"
        "Age"           = "by_age"
        "Profession"    = "by_profession"
    }

    $searchTerms = $hashtable[$queryType]
    $Results = Invoke-RestMethod -Method Get -Uri $apiUrl$searchTerms"?term=$Search&limit=$Limit" -WebSession $currentsession
    ...
}

edit, forgot to add, I dropped all this code completely:

$EndPoints = New-Object psobject
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name 'Profession' -Value "by_profession"
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name 'Age' -Value "by_age"
Add-Member -InputObject $EndPoints -MemberType NoteProperty -Name Name -Value "by_Name"


function Get-QueryType {
param(
    $userinput
)
$EndPoints.psobject.Members |
Where-Object {$_.Name -eq $userinput } |
? {$_.Membertype -eq "noteproperty"} | 
%{ $_.Value }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I will attempt this change and post back with results. Thanks.
This is a great fix, however, is there a clever way to auto-complete Profession, Age and Name? I am going to create some functions to alias these I think. like function age {Get-PersonnelData age}
Okay, I figured it out Tab Completion does work so -QueryType will suggest Age,Profession,Name. Thanks again.
not only that, it will not allow anything else to be passed to it
0

It's a little bit long, but I think you can do the following:

($Name,'Name'), ($Age,'Age'), ($Profession,'Profession') | % { if ($_[0]) { $searchTerms = Get-QueryType -userinput $_[1], $Results = Invoke-RestMethod -Method Get -Uri $apiUrl$searchTerms"?term=$Search&limit=$Limit" -WebSession $currentsession} }  

And BTW, You used correctly most of the times the if with boolean vars, and you can save lots of lines if you change other part on your code like this:

if($Limit.Length -eq 0), if($SignatureCount -eq $true)

to:

if(-not $limit), if($SignatureCount)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.