# Massive 'if' statement script, is there a better way?

**URL:** https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361
**Category:** PowerShell Help
**Created:** [September 14, 2017, 10:38am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361 "2017-09-14T10:38:05Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 10:38am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/1 "2017-09-14T10:38:05Z")

</div>

Hello,

I have been tasked with constructing a mailer that will send staff information to certain people, based on their location and their roles. For instance:

```
$teamA = @()
$teamB = @()
$teamC = @()
$teamD = @()

$users = Import-CSV 'path_to_file.csv'

ForEach ($user in $users) { 

#DeptA
if (user.department -like 'deptA*' -and user.title -match "jobA") {$teamA += "Username: $($user.username)`r`nTitle: $($user.title)`r`nLocation: $($user.location)`r`nOther Stuff: $($user.stuff)"}
if (user.department -like 'deptA*' -and user.title -match "jobB") {$teamB += "Username: $($user.username)`r`nTitle: $($user.title)`r`nLocation: $($user.location)`r`nOther Stuff: $($user.stuff)"}
#and so on...

#DeptB
if (user.department -like 'deptB*' -and user.title -match "jobA") {$teamC += "Username: $($user.username)`r`nTitle: $($user.title)`r`nLocation: $($user.location)`r`nOther Stuff: $($user.stuff)"}
if (user.department -like 'deptB*' -and user.title -match "jobB") {$teamD += "Username: $($user.username)`r`nTitle: $($user.title)`r`nLocation: $($user.location)`r`nOther Stuff: $($user.stuff)"}
#and so on...

#now the mailer...

$body = @"
`r`n     
New Staff Accounts:

REPLACE

Do not reply to this email address.

Thank you!
     
"@

$email = @{

smtpserver = "myserver"
from = "New_Staff@my.org"
subject = "New Staff Stuff"    

}

if (-not [string]::IsNullOrEmpty($teamA)) {
Send-MailMessage @email -body $body.Replace("REPLACE",$teamA) -To "user.guy@email.com"
}

if (-not [string]::IsNullOrEmpty($teamB)) {
Send-MailMessage @email -body $body.Replace("REPLACE",$teamB) -To "user.guy@email.com","user.otherguy@email.com"
}

}
```

The thing is, I have 19 departments. Not just a and b shown here. Add on to this that…

$teamA will be emailed to personA  
$teamB will be emailed to person a AND b  
$teamC will be emailed to person c  
$teamD will be emailed to person d AND e

This is going to be long script of many, many If statements…unless there is a better way?

Thank you for any input.

---

<div class="post-metadata">

### Author: ![exoblivione](https://avatars.discourse-cdn.com/v4/letter/e/b782af/32.png) [@exoblivione](https://forums.powershell.org/u/exoblivione)
#### Post date: [September 14, 2017, 11:03am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/2 "2017-09-14T11:03:04Z")

</div>

Use a Switch

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 11:19am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/3 "2017-09-14T11:19:35Z")

</div>

Ok.

On which part? How will a switch account for variables including department + title + who to email?

Care to elaborate on how to effectively use a switch in this particular script?

I am not asking you to write any for me, but a bit more detail would be appreciated.

---

<div class="post-metadata">

### Author: ![exoblivione](https://avatars.discourse-cdn.com/v4/letter/e/b782af/32.png) [@exoblivione](https://forums.powershell.org/u/exoblivione)
#### Post date: [September 14, 2017, 11:24am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/4 "2017-09-14T11:24:37Z")

</div>

Each team variable would be evaluated and then depending on the team returned the switch will execute code specific to that team.

https://technet.microsoft.com/en-us/library/ff730937.aspx

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 11:29am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/5 "2017-09-14T11:29:51Z")

</div>

In your situation, I don’t think it matters if you use If statements or switches. It sounds like you have to account for every possible combination of department and job, and have code execute for it. Unless there is something in common amongst the various combinations, such as [user\_deptA@domain.com](mailto:user_deptA@domain.com) is always emailed for any DeptA/Job combo, I don’t see how you can trim down your code.

---

<div class="post-metadata">

### Author: ![worlock](https://avatars.discourse-cdn.com/v4/letter/w/c77e96/32.png) [@worlock](https://forums.powershell.org/u/worlock)
#### Post date: [September 14, 2017, 11:57am UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/6 "2017-09-14T11:57:22Z")

</div>

How about this:

```
$csv = Import-csv 'path_to_file.csv'
$TeamA = $csv | where {$_.department -match 'deptA' -and $_.title -match "jobA"}
$Teamb = $csv | where {$_.department -match 'deptA' -and $_.title -match "jobB"}
#and so on...

$TeamC = $csv | where {$_.department -match 'deptB' -and $_.title -match "jobA")
$TeamD = $csv | where {$_.department -match 'deptB' -and $_.title -match "jobB")
#and so on...
```

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 12:02pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/7 "2017-09-14T12:02:20Z")

</div>

Boy do I feel really stupid. I got too focused on what was provided. Doh!

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 12:29pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/8 "2017-09-14T12:29:25Z")

</div>

Why do you say that?

Currently, I think you are correct. I am interested to see suggestions of others ways, though.

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 12:31pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/9 "2017-09-14T12:31:35Z")

</div>

This is a bit better. Instead of filling empty arrays with the user information based on condition, you are setting the variable on each line.

That saves some lines. But yes, I still need to account for each variation of dept + title + email recipient, with Where conditions instead of If statements.

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 12:37pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/10 "2017-09-14T12:37:24Z")

</div>

The only code is sending an email to variable recipients based on user conditions.

I read the TechNet article that you linked when I started this script, but I could not put together how it works for this scenario.

I will have another look. Thanks

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 12:57pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/11 "2017-09-14T12:57:35Z")

</div>

This method also negates my ability to customize the string held by $TeamA - because we are just throwing the results of the Where condition into the variable…correct?

Whereas in my initial script, I was forming $TeamA like “user.username,user.title,user.location,user.stuff”, which is a customized version of the results of the Where condition.

---

<div class="post-metadata">

### Author: ![drobin1](https://avatars.discourse-cdn.com/v4/letter/d/9dc877/32.png) [@drobin1](https://forums.powershell.org/u/drobin1)
#### Post date: [September 14, 2017, 1:09pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/12 "2017-09-14T13:09:29Z")

</div>

I’d try separating the email sending part of the script from the data so that it’s not hard coded into the script logic if the departments ever change. For example, you could have a Send-CustomEmail function and a hash table with all the user data. Loop through that hash table and send the relevant data into your Send-CustomEmail function.

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 1:14pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/13 "2017-09-14T13:14:11Z")

</div>

Thanks for the idea.

In this scenario, the departments will not change. New users will be added to those departments, and that is who I am grabbing from the CSV. Those variables are covered programmatically.

What CAN change is the recipient of the email. If the dept head changes, for example, then I would need to change the email recipient to the new one.

But as a standard practice, I will definitely keep your suggestion in mind!

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 1:35pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/14 "2017-09-14T13:35:12Z")

</div>

I just meant that Ricks code simplifies your code by taking out 19 lines where your empty team arrays would have been and simplifies getting the users into the proper teams. You still have 19 lines of it, but still a little shorter code than a whole bunch of If statements. As for sending out the e-mail, I “may” have found a solution for you to shorten your code so that you don’t have to have 19 If statements, and minimize the changes you’d need to make for the recipients. I’m about to head somewhere in a minute, but will continue to work on the solution tonight to see if I can get it to work.

Derek is right. It’s good to separate out your code into re-usable functions to a specific task. However, the solution I think I have I’ll just post it as one script and let you take it from there.

---

<div class="post-metadata">

### Author: ![creed-cordonier](https://avatars.discourse-cdn.com/v4/letter/c/c68b51/32.png) [@creed-cordonier](https://forums.powershell.org/u/creed-cordonier)
#### Post date: [September 14, 2017, 1:59pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/15 "2017-09-14T13:59:42Z")

</div>

You’re right, at first glance, Ricks code does look shorter. But in the process it changes what gets loaded into $TeamA.

In my script, $TeamA is only the information from $users that I want in the array, formatted to make sense in an email. In Ricks alternate example, $TeamA is the full results of $user row that the Where condition.

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 5:22pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/16 "2017-09-14T17:22:37Z")

</div>

Ok, here we go.

First of all, here is the sample file that lists the users information. In you original code, you imported it into the $csv variable.

```
UserName,Department,Title,Location
user1,DeptA,JobA,Dallas
user2,DeptA,JobB,Houston
user3,DeptB,JobA,Garland
user4,DeptB,JobB,Richardson
user5,DeptA,JobA,Frisco
user6,DeptA,JobA,Dallas
user7,DeptB,JobB,Houston
user8,DeptB,JobA,Garland
```

Next, I created another CSV file (Referred to as TeamsData.txt in my script below) that lists the team information. It includes the following.

1. A label for each team (Team column). In the end, I found this wasn’t needed with what I did, but it’s still good to have if you want a visible label when you open the file to edit it.
2. The message recipients (Recipient field). This is a comma-separated list of the addresses of the department heads you want to send the per-team emails to. You edit this list as these users change.

NOTE: If you need more than one recipient for an e-mail, make sure to do a comma-separated list in a set of double-quotes (“”) as you see for the example on the TeamB & TeamD rows.

“[tuser1@olympiangods99.com](mailto:tuser1@olympiangods99.com),tuser2@olympiangods99.com”

1. The Department that is part of the Department/Title filter that is applied per team.
2. The Title that is part of the Department/Title filter that is applied per team.

```
Team,Recipient,Department,Title
TeamA,"tuser1@domain.com",DeptA,JobA
TeamB,"tuser1@domain.com,tuser2@domain.com",DeptA,JobB
TeamC,"tuser3@domain.com",DeptB,JobA
TeamD,"tuser3@domain.com,tuser4@domain.com",DeptB,JobB
```

Ok. Now for the piece-de-resistance. Hopefully, it works for you. It worked great for me. I, of course, filled in the necessary values for SmtpServer, From, & Subject, and added a few more parameters to make the Send-MailMessage command work against my server. As you add, or remove, teams, or change the department heads (i.e. message recipients), you just need to edit the TeamsData.txt file, not the script code.

```
$EmailArgs = @{
                SmtpServer = "myserver"
                From = "New_Staff@my.org"
                Subject = "New Staff Stuff"
              }

$MsgBody = @"
`r`n     
New Staff Accounts:

REPLACE

Do not reply to this email address.

Thank you!
    
"@

$UserData = Import-Csv -Path C:\Data\UserData.txt
$TeamsData = Import-Csv -Path C:\Data\TeamsData.txt

ForEach($Team in $TeamsData)
{
  $TeamResults = $UserData | Where{($_.Department -like "$($Team.Department)*") -and ($_.Title -match "$($Team.Title)")}
  If($TeamResults)
  {
    ForEach($Result in $TeamResults)
    {
      $BodyReplacementTxt += "Username: $($Result.UserName)`r`nTitle: $($Result.Title)`r`nLocation: $($Result.Location)`r`n`n"
    }
    $Recipient = $Team.Recipient -split ","
    Send-MailMessage @EmailArgs -Body $MsgBody.Replace("REPLACE",$BodyReplacementTxt) -To $Recipient
  }
  Remove-Variable TeamResults,BodyReplacementTxt,Recipient -ErrorAction SilentlyContinue
}
```

Hope this helps.

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 5:43pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/17 "2017-09-14T17:43:56Z")

</div>

FYI, this is what the body of one of my test messages shows.

```
New Staff Accounts:

Username: user3
Title: JobA
Location: Garland

Username: user8
Title: JobA
Location: Garland

Do not reply to this email address.

Thank you!
```

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 5:50pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/18 "2017-09-14T17:50:43Z")

</div>

Got rid of the comment line in my code. I wrote it, when I was going to use the Team column from the TeamsData.txt file.

---

<div class="post-metadata">

### Author: ![miracles1315](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@miracles1315](https://forums.powershell.org/u/miracles1315)
#### Post date: [September 14, 2017, 6:14pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/19 "2017-09-14T18:14:05Z")

</div>

Adding the -ErrorAction parameter to my Remove-Variable cmdlet.

---

<div class="post-metadata">

### Author: ![jabezk](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/jabezk/32/428_2.png) [@jabezk](https://forums.powershell.org/u/jabezk)
#### Post date: [September 15, 2017, 4:54pm UTC](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361/20 "2017-09-15T16:54:18Z")

</div>

Here’s a suggestion for another way. I like using dictionary (or hashtable, depending on your point of view 🙂 lookups for this sort of thing instead of writing tons of if or case statements.

The first step I’d do is generate a dictionary of the departments with another dictionary as each key’s value. Something like this:

```
$depts = @{}

65..90 | %{$depts.Add("Dept$([char]$_)", @{})}

foreach($team in $depts.GetEnumerator()) { 
    65..90 | %{$team.Value.Add("Job$([char]$_)", @())}
}
```

That will produce a dictionary like this, with each value in the main dictionary being another dictionary with an array as its value:

```
Name Value
---- -----
TeamS {JobC, JobB, JobW, JobX...}
TeamQ {JobC, JobB, JobW, JobX...}
TeamR {JobC, JobB, JobW, JobX...}
TeamJ {JobC, JobB, JobW, JobX...}
TeamK {JobC, JobB, JobW, JobX...}
TeamI {JobC, JobB, JobW, JobX...}
TeamC {JobC, JobB, JobW, JobX...}
TeamA {JobC, JobB, JobW, JobX...}
TeamX {JobC, JobB, JobW, JobX...}
TeamO {JobC, JobB, JobW, JobX...}
TeamH {JobC, JobB, JobW, JobX...}
TeamN {JobC, JobB, JobW, JobX...}
TeamZ {JobC, JobB, JobW, JobX...}
TeamB {JobC, JobB, JobW, JobX...}
TeamP {JobC, JobB, JobW, JobX...}
TeamM {JobC, JobB, JobW, JobX...}
TeamG {JobC, JobB, JobW, JobX...}
TeamE {JobC, JobB, JobW, JobX...}
TeamV {JobC, JobB, JobW, JobX...}
TeamD {JobC, JobB, JobW, JobX...}
TeamY {JobC, JobB, JobW, JobX...}
TeamU {JobC, JobB, JobW, JobX...}
TeamW {JobC, JobB, JobW, JobX...}
TeamF {JobC, JobB, JobW, JobX...}
TeamL {JobC, JobB, JobW, JobX...}
TeamT {JobC, JobB, JobW, JobX...}
```

Then, using Kyven’s CSV for some data, associate each user with a department and title:

```
$csv = import-csv test.csv

foreach ($user in $csv) {
    $props = @{"Department" = $user.Department; "Location" = $user.Location; "Username" = $user.Username}
    $depts[$user.Department][$user.Title] += New-Object -TypeName PSObject -Property $props
}
```

Then you can look up each user based on their department and title:

```
> $depts[$user.Department][$user.Title]

Username Department Location
-------- ---------- --------
user1 DeptA Dallas
```

In this case I used an array to stash the user objects in, but you could just as easily build strings or something else as the value for the $user.Title key.

You might build pre-defined lists of departments and titles to build your dictionaries. You go even further and generate your keys and values based on the CSV attributes, then insert the users that way rather than generating the combinations.

Ideas to consider…

[Next page](https://forums.powershell.org/t/massive-if-statement-script-is-there-a-better-way/9361.md?page=2)
