Switch usage

This topic contains 11 replies, has 5 voices, and was last updated by  Scriptimus Prime 2 years, 1 month ago.

  • Author
    Posts
  • #30641

    Graham Beer
    Participant

    Is this the correct usage of a switch command ?

    So below is part of testing, but the full script will evaluate if the input is either a UUID number or a MACaddress, then pass the result to import a machine with the number passed. The command requires either a -SmBiosGuid or -MACAddress.

    $Identifer = "F8:16:54:C1:83:33"
    
        $UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
        $MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
        
        Switch ($Identifer) {
        {$Identifer -match $UUID} { "UUID" }
        {$Identifer -match $MAC} { "MACAddress" }
        }
  • #30642

    Graham Beer
    Participant

    I'm thinking an ElseIf is the better solution :

    
    function add-machine
    {
        [CmdletBinding()]
        Param
        (
            # Param1 help description
            [Parameter(Mandatory=$true,
                       ValueFromPipeline=$True,
                       HelpMessage="Computer Name then either MACAddress or UUID (SmBiosGuid)")]
            [string[]]$ComputerName,
            [string[]]$Identifer,
            
            [string]$ErrorLog = 'c:\temp\AddDeviceError.txt'
        )         
        
        Begin
        {
    #Import Configuration Manager module
        $ModulePath = $env:SMS_ADMIN_UI_PATH.Replace("i386","ConfigurationManager.psd1")
        Import-Module $ModulePath
        }
        Process
        {
        [regex]$MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
            [regex]$UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
    
            if ($Identifier -match $MAC) 
                { Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -MacAddress $Identifier }
            elseif ($Identifier -match $UUID)
                { Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -SmBiosGuid $Identifier }
            else
                {Write-Warning "Not a valid MAC Address or SmBiosGuid"}
        }
    
         #Import-CMComputerInformation -CollectionName "All Systems" -ComputerName $ComputerName -SmBiosGuid 
        }
        End
        {
        }
    
  • #30644

    Rob Simmers
    Participant

    Your example is basically attempting to match and if it matches then you can identify the identifier passed. See the example code below for switch and validateset implementations:

    function Test-ValidateSet {
        param (
            [ValidateSet("MAC", "UUID")]
            [string]$IdentifierType,
            [string]$Identifier
            
        )
        
        switch ($IdentityType) {
            "MAC" {$Pattern = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"}
            "UUID"{ $Pattern = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" }
        }
        
        if ($Identifier -match $Pattern) {
            
        }
        else {
            "Bad identifier"   
        }
    }
    
    
    
    function Test-Switch {
        param (
            [string]$Identifier,
            [switch]$IsUUID
            
        )
        #Default pattern is MAC, so if you wanted to pass a UUID you'd have to specify the IsUUID switch
        $Pattern = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$" }
        if ($IsUUID) {$Pattern = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" }
            
        if ($Identifier -match $Pattern) {
            
        }
        else {
            "Bad identifier"
        }
    }
    
  • #30645

    Graham Beer
    Participant

    Rob, brilliant. Funny, now i look at what you have done looks logical. Not used the ValidateSet yet, useful to know. Learn't a bit more today, so many thanks.

  • #30646

    Graham Beer
    Participant

    Rob, with the test-validate, do i pass the MAC or UUID to the Identifer ?

  • #30702

    Curtis Smith
    Participant

    Graham, your way works, but you would typically structure it something like this.

    $Identifer = "F8:16:54:C1:83:33"
    #$Identifer = "d75e6376-7133-11e5-9d70-feff819cdc9f"
    
        $UUID = "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$"
        $MAC = "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$"
        
        Switch -regex ($Identifer) {
            $UUID { "UUID" }
            $MAC { "MACAddress" }
        }
    

    or if you did not want to use variables

    $Identifer = "F8:16:54:C1:83:33"
    #$Identifer = "d75e6376-7133-11e5-9d70-feff819cdc9f"
        
        Switch -regex ($Identifer) {
            "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$" { "UUID" }
            "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$" { "MACAddress" }
        }
    
  • #30705

    Scriptimus Prime
    Participant

    Great examples above. Here's how I'd handle it.

    Function Test-Function {
            
        [CmdletBinding(SupportsShouldProcess=$true,
                            ConfirmImpact='Medium')]
        Param (
            # Specifies the UUID or MAC Address
            [Parameter(Mandatory=$true)]
            [System.String]
            [ValidateScript({($_ -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") -or ($_ -match "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$")})]
            [System.String]
            $Identifer
    
        )
    
        If ($Identifer -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") {
            # MAC Address was entered
            "MAC Address"
        }
        Else {
            # UUID was entered
            "UUID"
        }
        
    }
    

    Then some test code

    Test-Function -Identifer 20:58:9D:17:EF:52
    Test-Function -Identifer f6f94322-7138-11e5-9d70-feff819cdc9f
    Test-Function -Identifer Nonsense
    
  • #30720

    Graham Beer
    Participant

    Curtis and Scriptimus thank, both excellent solution. Fascinated by yours Scriptimus. Thank you !

  • #30721

    Graham Beer
    Participant

    My "Catch" doesn't seem to work if the regex is not met...

    Function Test-Function {
            
        [CmdletBinding(SupportsShouldProcess=$true,
                            ConfirmImpact='Medium')]
        Param (
            # Specifies the UUID or MAC Address
            [Parameter(Mandatory=$true)]
            [System.String]
            [ValidateScript({($_ -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") -or ($_ -match "^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$")})]
            [System.String]
            $Identifer
    
        )
    
    try {
        If ($Identifer -match "^\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}\:\w{2}$") {
            # MAC Address was entered
            write-output "MAC Address" -ea STOP
        }
        Else {
            # UUID was entered
            write-output "UUID" -ea STOP
        }
    }
    catch {
        {
        #No Return
        write-warning $($_.Exception.Message)
        }
      }
    }
    
  • #30723

    Scriptimus Prime
    Participant

    The design here is that the Validate script will not allow the function to get past the parameter section if the regex is not matched.

    As for the try/catch. This would typically go inside the If/Else scriptblocks but only if you wanted to handle something that could catastrophically fail.

    In this situation you're not doing anything except returning a string. The If/Else is sufficient.

    To eliminate confusion further instead of write-output "UUID" as you used above, in the final code you could use
    return 'UUID'

  • #30847

    Max Kozlov
    Participant

    Scriptimus Prime, why you do test for $Identifier twice ?
    your code
    "# UUID was entered
    write-output "UUID" -ea STOP"

    with this design can't be executed at all because the ValidateScript disallow it

  • #30848

    Scriptimus Prime
    Participant

    Yes Max, I gave that some thought.

    The validate script seemed to be the more PowerShell way to start the script.

    However, from then I couldn't find a way to identify what was passed without testing again.

    if the reduction of iterations was an objective, then perhaps it would be better to use switch or If, ElseIf, Else.

You must be logged in to reply to this topic.