powershellforeachactive-directoryoutputimport-csv

PowerShell - How can I get output in the shell to list all existing accounts from my variable without my script terminating first?


so I understand the problem is the code will iterate in the foreach loop once and then exit, listing only one existing account in the output.

Is there a way to skip the "exit" statement until it is finished iterating the rest of the accounts to be displayed? I still need the script to terminate to work with my email scripts and prevent accounts from being created in my next foreach loop.

$csv = Import-CSV "c:\accounts.csv"


foreach ($name in $csv)  {


If ($accountname.Length -le 20) { $accountname = $name.FirstName + "." + $name.LastName} 
If ($accountname.Length -gt 20) { $accountname = $name.FirstName.Substring(0,3) + "." + $name.LastName.Substring(0,12) }


If (Get-ADUser -filter {samaccountname -eq $accountname} | fl *)  

{Write-Warning  "The account $accountname already exists."
exit}
}

try {
foreach ($name in $csv){


If ($accountname.Length -le 20) { $accountname = $name.FirstName + "." + $name.LastName} 
If ($accountname.Length -gt 20) { $accountname = $name.FirstName.Substring(0,3) + "." + $name.LastName.Substring(0,12) }

New-ADUser -Name ($name.LastName + ", " + $name.FirstName + " (" + $name.emailaddress + ")") -Path "OU=test,OU=test test,DC=test,DC=com" -Surname $name.LastName -GivenName $name.FirstName -DisplayName ($name.LastName + ", " + $name.FirstName + " (" + $name.emailaddress + ")") -samaccountname ($accountname) -EmailAddress $name.emailaddress -AccountPassword (ConvertTo-SecureString "password" -AsPlainText -force) -PassThru -ChangePasswordAtLogon $False -Enabled $True 



}
}


catch  [Microsoft.ActiveDirectory.Management.ADException]
{ if ($error[0].Exception.Message -eq "The server is unwilling to process the request") {}

else {
    
  Write-Warning $Error[0] 
  Write-host $error[0].TargetObject -ForegroundColor Red 
      }
}


catch [Microsoft.ActiveDirectory.Management.ADIdentityAlreadyExistsException]
{
 Write-Warning  $Error[0] 
 Write-Host $Error[0].TargetObject -ForegroundColor Red
}


If ($csv.Template -eq "Sharepoint" -and $error[0].Exception.Message -ne "The specified account already exists")
{cd c:\email
.\email.ps1}



echo "`nUser Account Creation Complete" 
  
} 

csv file Output


Solution

  • It seems you want the script to first test all accountnames you create are new and can be used for new users, or if there are any existing accounts.

    If you have existing accounts, you want to list them all and stop the script, otherwise you want it to carry on and create users, send emails etc. (when you are finished writing that code)

    Below should do that for you, and will give you a choice if you want the remainder of the script to be executed or not:

    $csv = Import-Csv -Path "c:\accounts.csv"
    
    # create a list to store existing accounts in (if any)
    $existingAccounts = [System.Collections.Generic.List[object]]::new()
    
    # capture all non-existing accountnames you can use in variable $newAccounts
    $newAccounts = foreach ($name in $csv)  {
        # construct the accountname limited to 20 characters
        $accountname = $name.FirstName + "." + $name.LastName
        if ($accountname.Length -gt 20) { $accountname = $name.FirstName.Substring(0,3) + "." + $name.LastName.Substring(0,12) }
        # test if a user with that SamAccountName already exists
        $adUser = Get-ADUser -Filter "SamAccountName -eq '$accountname'"
        if ($adUser) {
            $existingAccounts.Add($adUser)
            Write-Warning  "The account $accountname already exists."
        }
        else {
            # output this accountname because it doesn't exist yet and you can create a new user with it
            $accountname
        }
    }
    # remove all duplicates from this array (if any)
    $newAccounts = $newAccounts | Sort-Object -Unique
    
    # test and display all accounts that already exist
    if ($existingAccounts.Count) {
        Write-Host 'These accounts already exist:' -ForegroundColor Yellow
        $existingAccounts | Format-List *
    }
    else {
        Write-Host 'These accountnames you can use to create new users:' -ForegroundColor Green
        Write-Host ($newAccounts -join [environment]::NewLine)
    }
    
    ## This is the point where you need to decide if you want to stop the script 
    ## (let it run out) or carry on with the remainder
    
    $answer = Read-Host "Do you want the rest of the script to continue?  (Y|N)"
    if ($answer[0] -eq 'Y') {
        # do the rest of the script when you're finished with it
        # create the new users with the SamAccountNames you have in $newAccounts
        # email some people
        # etc..
    }