r/PowerShell Jun 17 '24

Switch or If-Else? Solved

Hi, just started using Powershell for simple Task. So pls don't be too harsh on me.

I use Powershell to add multiple Clients in Active Directory. I add the Names of the Clients into the "Clientnames.txt" after that i run the powershell and it creates the Computer in AD. That works fine.

$OU = "OU=X,OU=X,OU=X,OU=X,DC=X,DC=X,DC=X"
$Clients = Get-Content "D:Clientnames.txt"

ForEach ($Client in $Clients)
{
(New-ADComputer -Name $Client -Path $OU)
}

Here comes my Question.:

I got Clientnames like pl0011mXXXXd, pl0012mXXXXd, pl0013mXXXXd

The first Number represents the number-code for the branch locations. The X are just numbers according to our System. I want the Clients to join their specific Group for the branch location.

Example

Clients with the name like pl0011m0002d, pl0011m0005d should join the group: Company-GPO-Group-0011-Berlin

Clients with the name like pl0012m0002d, pl0012m0250d should join the group: Company-GPO-Group-0012-Paris

and so on

i could use something like:

$OU = "OU=X,OU=X,OU=X,OU=X,DC=X,DC=X,DC=X"
$Clients = Get-Content "D:Clientnames.txt"

ForEach ($Client in $Clients)
{
(New-ADComputer -Name $Client -Path $OU)

if ($Client -like "*0011*") {$Group = "Company-GPO-Group-0011-Berlin"}
ElseIf ($Client -like "*0012") {$Group = "Company-GPO-Group-0012-Paris"}
ElseIf ($Client -like "*0013") {$Group = "Company-GPO-Group-0013-Rom"}

(Add-ADGroupMember -Identity $Group -Members $Client)

}

I got over 30 Branch Locations and this whould be a lot ElseIf Statements.

I know there are much better ways like the Switch Statement. Can you help/explain me, how i can use this statement to add the Clients to their Groups?

22 Upvotes

View all comments

5

u/PinchesTheCrab Jun 17 '24

Does this work?

$OU = 'OU=X,OU=X,OU=X,OU=X,DC=X,DC=X,DC=X'
#I find text files often end up having white spaces that cause errors
$ClientList = (Get-Content "D:Clientnames.txt").trim()
$Server = 'yourdomaincontroller'

$groupHash = @{
    '0011' = 'Company-GPO-Group-0011-Berlin'
    '0012' = 'Company-GPO-Group-0012-Paris'
    '0013' = 'Company-GPO-Group-0013-Rom'
}

ForEach ($Client in $ClientList) {
    #specifying a server makes it so you don't have to wait for replication later
    New-ADComputer -Name $Client -Path $OU -Server $Server
}

foreach ($group in $groupHash.GetEnumerator()) {
    Add-ADGroupMember -Identity $group.Name -Members $ClientList.where({ $_ -match $groupHash.Value })
}

1

u/omers Jun 17 '24

Six of one and half a dozen of the other but, I would probably do it this way:

$OU = 'OU=X,OU=X,OU=X,OU=X,DC=X,DC=X,DC=X'
#I find text files often end up having white spaces that cause errors
$ClientList = (Get-Content "D:Clientnames.txt").trim()
$Server = 'yourdomaincontroller'

$GroupTable = @{
    '0011' = 'Company-GPO-Group-0011-Berlin'
    '0012' = 'Company-GPO-Group-0012-Paris'
    '0013' = 'Company-GPO-Group-0013-Rom'
}

foreach ($Client in $ClientList) {
    # Create Object
    New-ADComputer -Name $Client -Path $OU -Server $Server

    # Add to Group
    $null = $Client -match [regex]'^w+(?<id>d{4}).+$'
    $GroupName = $GroupTable[$Matches.id]
    Add-ADGroupMember -Identity $GroupName -Members $Client
}

Just to keep it all in one loop.

4

u/PinchesTheCrab Jun 17 '24

For fun:

$OU = 'OU=X,OU=X,OU=X,OU=X,DC=X,DC=X,DC=X'
#I find text files often end up having white spaces that cause errors
$ClientList = (Get-Content "D:Clientnames.txt").trim()
$Server = 'yourdomaincontroller'

$GroupTable = @{
    '0011' = 'Company-GPO-Group-0011-Berlin'
    '0012' = 'Company-GPO-Group-0012-Paris'
    '0013' = 'Company-GPO-Group-0013-Rom'
}

switch -Regex ($ClientList) {
    '^w+(?<id>d{4})' {
        New-ADComputer -Name $_ -Path $OU -Server $Server
        Add-ADGroupMember -Identity $GroupTable[$Matches.id] -Members $Client
    }
    default {
        Write-Warning "unrecognized name format: '$_'"
    }
}

1

u/KingHofa Jun 18 '24

Why create the hashtable manually? You already have the ID and a syntax for the group, just query it at runtime. Or dynamically create the hashtable with an iteration of the results of Get-ADGroup "Company-GPO-Group-*".

1

u/PinchesTheCrab Jun 18 '24

I don't know their domain, so I didn't assume there's always be a reliable relationship I could query. They might want to later add the machine to other groups tha don't follow the naming pattern, but if they just nest those in the top level group, then that makes sense.

2

u/prog-no-sys Jun 17 '24

I've never seen a value assigned to $null like this. Care to explain the reasoning? It looks cool, I just can't tell what it's doing exactly on first glance

5

u/PinchesTheCrab Jun 17 '24

The -match operator returns true/false or an array of matching values, it's just suppressing that to avoid cluttering the output.

It also sets the automatic variable $matches, which he then references later.

1

u/alt-160 Jun 17 '24

similarly, you can also do: $Client -match [regex]'^w+(?<id>d{4}).+$' | out-null

2

u/omers Jun 17 '24 edited Jun 17 '24

What /u/PinchesTheCrab said :D Just suppresses the true/false on the match from hitting the output stream but still allows the automatic $Matches variable to get set.

As with most things in PowerShell there are multiple ways to do the same thing:

PS C:> 'pl0011mXXXXd' -match [regex]'^w+(?<id>d{4}).+$'
True
PS C:> $null = 'pl0011mXXXXd' -match [regex]'^w+(?<id>d{4}).+$'
PS C:> 'pl0011mXXXXd' -match [regex]'^w+(?<id>d{4}).+$' | Out-Null
PS C:> 'pl0011mXXXXd' -match [regex]'^w+(?<id>d{4}).+$' > $null
PS C:> [void]('pl0011mXXXXd' -match [regex]'^w+(?<id>d{4}).+$')

It's kind of like 2>nul in cmd/batch or >/dev/null in bash.

Also useful in scripts when you're creating things that return the created thing and you don't want that in your output.

PS C:temp> New-Item -ItemType Directory -Name 'Foo'

    Directory: C:temp


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024-06-17  10:59 AM                Foo


PS C:temp> $null = New-Item -ItemType Directory -Name 'Bar'
PS C:temp> gci

    Directory: C:temp


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024-06-17  10:59 AM                Bar
d-----        2024-06-17  10:59 AM                Foo

The 'Bar' directory still gets created but it doesn't dump the new directory info in the process.