Yamez
Yamez

Reputation: 25

Powershell Foreach usage and syntax

I'm attempting to script the creation of accounts in active directory using a csv file. Unfortunately I'm new to PowerShell and scripting in general and am facing difficulty managing a foreach() loop which is intended to handle each of the columns in the csv document I import.

I suspect that I cannot define my variables in one block after foreach() like I have, but am unsure and would appreciate some guidance. Specifically, the purpose of the code is read a csv document and assign each item to a variable that it then uses to create a service account with those values.

The Ideal situation is one where I can create a csv with several hundred rows, execute the script and end with several hundred matching service accounts.

$SVC = (import-csv C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain")) `
foreach($variable in %SVC) {

    $name = $SVC.Name
    $Pass = $SVC.Pass
    $WhatDo = $SVC.WhatDo
    $Location = $SVC.Location
    $Domain = $SVC.Domain


        New-ADuser `
            -Name $name `
            -AccountPassword (Convertto-SecureString $Pass -AsPlainText -Force) `
            -CannotChangePassword $true `
            -Description $WhatDo `
            -DisplayName $name `
            -Enabled $true `
            -GivenName $name `
            -PasswordNeverExpires $True `
            -Office $Location `
            -Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
            -SamAccountName $name `
            -UserPrincipleName $name + "@" + $domain + ".net" `

        Start-Sleep -Seconds 15

    Get-ADUser `
        -Identity $name | Add-ADPrincipalGroupMembership `
        -MemberOf "Group1","Group2","Group3"  

    }

Upvotes: 0

Views: 393

Answers (4)

w21froster
w21froster

Reputation: 36

I prefer using ForEach-Object rather than foreach.

It would be something like:

$SVC = (Import-CSV C:\users\me\desktop\Test.csv -header("Name", "Pass", "WhatDo", "Location", "Domain")) 
$SVC | ForEach-Object {

        New-ADuser `
            -Name $_.Name `
            -AccountPassword (Convertto-SecureString $_.Pass -AsPlainText -Force) `
            -CannotChangePassword $true `
            -Description $_.WhatDo `
            -DisplayName $_.Name `
            -Enabled $true `
            -GivenName $_.Name `
            -PasswordNeverExpires $True `
            -Office $_.Location `
            -Path "OU=Service-Accounts, Ou=Accunts, OU=_CORP, DC=$Domain, DC=net" `
            -SamAccountName $_.Name `
            -UserPrincipleName $_.Name + "@" + $_.Domain + ".net" 

        Start-Sleep -Seconds 15

    Get-ADUser `
        -Identity $_.Name | Add-ADPrincipalGroupMembership `
        -MemberOf "Group1","Group2","Group3"  

    }

$_ represents the current item in the pipeline. ($SVC in your case, which was the wrong variable anyways.) It's less code and I think it's a cleaner way of doing things!

Upvotes: 1

Thomas Glaser
Thomas Glaser

Reputation: 2157

There are quite a few things wrong in your code, not just the foreach.

But let's start with that: foreach ($variable in $SVC) means that $variable will have the the current item inside your loop, yet you are accessing $SVC in your loop which is still referring to the original collection. $variable is not a good name either, so you should change that to something more meaningful. Also, you wrote %SVC instead of $SVC.

You are also using backtick (`) a lot, sometimes incorrectly. You should only use it when your cmdlet invokation spans multiple lines. In the case of Import-Csv it's not, yet there's backtick at the end. There's also one on the last line of New-ADUser. Some prefer to use Parameter Splatting instead of backticks, but's thats a matter of taste.

Considering you are creating service accounts, I would write the first part like this:

$serviceAccounts = Import-Csv C:\users\me\desktop\Test.csv -Header Name,Pass,WhatDo,Location,Domain

foreach($serviceAccount in $serviceAccounts) {

Then inside your loop you can access the indivdual properties through $serviceAccount:

$name = $serviceAccount.Name

Also, PowerShell expands variables when using double quotes, so -UserPrincipleName can be written like this: -UserPrincipleName "$name@$domain.net"

Upvotes: 1

guiwhatsthat
guiwhatsthat

Reputation: 2434

Here is an example how you can do it.(Don't forget the delimiter)

$csv = Import-Csv -Path C:\temp\csv.csv -Header "a","b","c" -Delimiter ";"
foreach($row in $csv){
    $row.a
    $row.b
    $row.c
}

Here are some more examples how foreach works: Take a look https://ss64.com/ps/foreach.html

Examples

Loop through an array of strings:

 $trees = @("Alder","Ash","Birch","Cedar","Chestnut","Elm")

 foreach ($tree in $trees) {
   "$tree = " + $tree.length
 }

Loop through a collection of the numbers, echo each number unless the number is 2:

 foreach ($num in 1,2,3,4,5) {
  if ($num -eq 2) { continue } ; $num
 }

Loop through a collection of .txt files:

  foreach ($file in get-ChildItem *.txt) {
    Echo $file.name
  }

Upvotes: 0

fdafadf
fdafadf

Reputation: 819

Rename $SVC to $SVCs then foreach ($SVC in $SVCs)

Upvotes: 0

Related Questions