Reputation: 25
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
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
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
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