Need help with function parms

I have a function that is using if statements for the parameter passed
it works fine if the parameter and value are given
but if the parameter is not passed and just the value given it will just error
even though I have a default set.

Is there a way to make an if statement on the value itself?

like if the parameter value -match “@” it equals the parameter $email else it equals the parameter $SAN

Hudzon,
Welcome back to the forum. Long time no see. :wave:t4: :wink:

Please share your code and error messages you might get.

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org ← Click it !!

Here is my little fuction, what I would like is for the user to be able to pass either or prameter without having to declare it and the scipt determine which one it is based on the email address having the @ symbol in the string.

function get-accinfo {
    [CmdletBinding()]
    Param
    (
        [parameter(Mandatory=$true,
        ParameterSetName="ID")]
        [string]$ID,
        
        [parameter(Mandatory=$true,
        ParameterSetName="EMAIL")]
        [string]$EMAIL

        
    )

if ($email) {
get-user $email  | ForEach-Object {get-aduser $_.samaccountname -Properties * -Credential $creds} | ForEach-Object {
    $break = "#################################################################################`n"
  foreach ($Domain in "one.com,two.com,three.com,four.com".split(",")) {
    $en = $_.employeenumber  
    Get-ADUser -Server $Domain -LDAPFilter "(EmployeeNumber=$en)"  -Properties * -Credential $creds |
    Select-Object @{N='Account';E={"$($_.samAccountName) on $Domain"}}, @{n='Samaccountname';e={(New-Object System.Security.Principal.SecurityIdentifier $_.Sid).Translate([System.Security.Principal.NTAccount]).Value }},DistinguishedName,Displayname, mail, EmployeeNumber,  @{n='LikedMasterAccount';e={(New-Object System.Security.Principal.SecurityIdentifier $_.msExchMasterAccountSid).Translate([System.Security.Principal.NTAccount]).Value }} 
     
     $break    
  }}  }

  if ($BRID) {
     ForEach-Object {
        $break = "#################################################################################`n"
      foreach ($Domain in "one.com,two.com,three.com,four.com".split(",")) {
        $en = $ID
        Get-ADUser -Server $Domain -LDAPFilter "(EmployeeNumber=$en)"  -Properties * -Credential $creds |
        Select-Object @{N='Account';E={"$($_.samAccountName) on $Domain"}}, @{n='Samaccountname';e={(New-Object System.Security.Principal.SecurityIdentifier $_.Sid).Translate([System.Security.Principal.NTAccount]).Value }},DistinguishedName,Displayname, mail, EmployeeNumber, @{n='LikedMasterAccount';e={(New-Object System.Security.Principal.SecurityIdentifier $_.msExchMasterAccountSid).Translate([System.Security.Principal.NTAccount]).Value }} 
         
         $break    
      }}  }
    }

To set a default value for a parameter you assign it as you would any other variable with “= ‘VALUE’” within the Param-block.
If a user passes in a different value it overwrites the value you assigned previously.

Also if you set a default parameter you will have to either skip the Mandatory part of the parameter assignment as the user can choose to not assign a value when calling the script.

Param
    (
        [parameter(Mandatory=$false)]
        [string]$ID = 'ID'
        
        [parameter(Mandatory=$false)]
        [string]$EMAIL = 'EMAIL'

If you wish to limit the user to a couple of predefined values you can use ValidateSet in the Param-block like this:

        [parameter(Mandatory=$false)]
        [ValidateSet('ID','NAME','EMAIL')]
        [string]$ID = 'ID'

I think the easiest way to achieve your goal is to limit to a generic parameter and just check the value yourself. You could even extend this to accept samaccountname, distinguishedname, etc. In order to improve readability I stored your calculated expressions/properties in a variable. I also encourage you to look into splatting as well.

function Get-AccountInfo {
    [CmdletBinding()]
    Param(
        [parameter(Mandatory=$true,Position=0,HelpMessage='Enter the employee number or email address')]
        [string]$User
    )

    $filter = if($User -match '@'){
        "EmailAddress -eq '$User'"
    }
    else{
        "EmployeeNumber -eq '$User'"
    }

    $selectprops = @{N='Account';E={"$($_.samAccountName) on $Domain"}},
                   @{n='Samaccountname';e={(New-Object System.Security.Principal.SecurityIdentifier $_.Sid).Translate([System.Security.Principal.NTAccount]).Value }},
                   'DistinguishedName',
                   'Displayname',
                   'mail',
                   'EmployeeNumber',
                   @{n='LikedMasterAccount';e={(New-Object System.Security.Principal.SecurityIdentifier $_.msExchMasterAccountSid).Translate([System.Security.Principal.NTAccount]).Value }} 

    Get-ADUser -Server $Domain -Filter $filter -Properties mail,employeenumber,msExchMasterAccountSid -Credential $creds |
        Select-Object $selectprops

}

My final bit of advice is to limit the properties you query with Get-ADUser to those you actually use. The increased load on active directory In small environments this isn’t really an issue, but can be very disruptive in larger organizations.

1 Like

Hi,

The supplied script will accept either “ID” or “EMAIL” and only one of them not both.

You may also want to add a default parameterset to cmdletbinding():-

[CmdletBinding(DefaultParameterSetName="ID")]

and this logic can detect which parameterset was used:-

switch ($PsCmdlet.ParameterSetName) {
    "EMAIL" {

    }
    "ID" {

    }
}

You could also use a vailidate pattern regex for the email parameter:-

[ValidatePattern('@')]

you could go more complex on the regex but this would limit the portability of the script.

Hmmm … that wouldn’t accomplish the requirement to determine the provided parameter only based on the input of the value … without the parameter name.

For that KrzyDoug has the best solution, I’m just covering alternatives :slight_smile:

But I would suggest that if you have a mixed list of IDs and EMAILs then there is something wrong with the source,

Alternativly use regex to determine the parameter (Assuming no IDs contain ‘@’)

#Email
'@'

#ID
'^[^@]*$'

if this was my function I would add a properties parameter:-

[Parameter()]
        [String[]]
        $Properties

and use logic to process the results output

process {
        if ($Properties) {
            Get-ADUser -Filter 'UserPrincipalName -eq $email' -Properties $Properties
        }else{
            Get-ADUser -Filter 'UserPrincipalName -eq $email'
        }
        
    }

(This is from a function that finds AD users from a list of email addesses, and work on the pipeline)