Tchotchke
Tchotchke

Reputation: 399

Powershell Pipe to Switch Statement to format a phone number

I am attempting to query AD to get the phone number for a user then format it to a standard format (###-####). I'm using a Switch statement because I've seen the number in a handful of different formats. With the way I have my code set up though I am getting an error: "The term Switch is not recognized as a name of a cmdlet, function, script file..."

Here's the code:

$ADInfo = Get-ADUser $User.Email.split("@")[0] -Properties * -Server $DC
$User.'Phone Number' = $ADInfo.telephoneNumber | Switch -regex ($_) {
    '^\d{5}$'                     
    {                        
        "{0:38#-####}" -f $_
        break
    }
    '^\d{7}$' 
    {
        "{0:###-####}" -f $_
        break
    }
    default
    {
        break
    } 

}

Am I misunderstanding how the pipeline works? I suppose I could just save this info to a temp variable and then enter a Switch statement but this seemed like an effective way to use the pipeline.

Anyhow, any help is appreciated! Thanks!

Upvotes: 1

Views: 1791

Answers (2)

TheMadTechnician
TheMadTechnician

Reputation: 36322

As suggested by Mathias R. Jessen, here's an example of how to use Switch without having to iterate through things with a ForEach loop, or piping anything to it.

Switch will iterate an array on its own, so there's no need to nest it in a loop, or even pipe anything in this case. It can be done as such:

$ADInfo = Get-ADUser $User.Email.split("@")[0] -Properties * -Server $DC
    $User.'Phone Number' = Switch -regex ($ADInfo.telephoneNumber) {
        '^\d{5}$'                     
        {                        
            "{0:38#-####}" -f $_
        }
        '^\d{7}$' 
        {
            "{0:###-####}" -f $_
        }
    }

Aside from that I would recommend using Continue instead of Break. Further example of when continue would be used within the Switch scriptblock:

$TestData = @('[email protected]','JDoe','(555)867-5309','Taco Tuesday')
Switch -regex ($TestData){
    '@' {"$_ is an email address.";continue}
    '^[+()\-\d\s]+$' {"$_ is a phone number.";continue}
    default {"$_ is unknown."}
}

Here we have something being done in the default block, so we want to include a continue statement in the previous cases so that if a match is found it moves to the next item in the array, and does not execute the default case. The output of that would be:

[email protected] is an email address.
JDoe is unknown.
(555)867-5309 is a phone number.
Taco Tuesday is unknown.

Upvotes: 3

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174690

Am I misunderstanding how the pipeline works?

Yes.

The pipeline can only pipe stuff to commands - and switch is not a command, it's a language keyword.

You can wrap your switch statement in a ForEach-Object block and pipe the input to that:

$User.'Phone Number' = $ADInfo.telephoneNumber | ForEach-Object {
    Switch -regex ($_) {
        '^\d{5}$'                     
        {                        
            "{0:38#-####}" -f $_
        }
        '^\d{7}$' 
        {
            "{0:###-####}" -f $_
        }
    }
}

As Ansgar points out, the break statements here are redundant (and not required), since your test cases are mutually exclusive

Upvotes: 7

Related Questions