Help with Account Creation Script

Hello, I inherited an student account creation script that a previous admin wrote in PowerShell. I'm still learning the basics of PowerShell and need some help.

I would like to be able to increment by 1 ascending up on the usernames if it is not available and use that for all aspects of the account creation sections. So if JMSmith is taken the script will try JMSmith1, then JMSmith2, etc. That way I don't have users with JMSmith2 for their username in active driectory but JMSmith@domain.edu for their email.

Thank you for any help provided.

Here is the format of the CSV I place in the \ToBeProcessed folder.

id_num,first_name,middle_name,last_name,email_address
654321,Jason,M,Smith,darealmccoy@gmail.com

Open in new window


The script right now will try to only use JMSmith.

# =============================================================================================================================================================
#    Student Creation Script
# =============================================================================================================================================================
#    Global Variables used throughout the script
# =============================================================================================================================================================

$DataSourceDir = "\\server1\IT\AccountCreation\ToBeProcessed"                   #This is the directory that the CSVs are dropped into
$DataWorkingDir = "\\server1\IT\AccountCreation\Working"                        #This is the directory that we move the current CSVs to work on
$DataProcessedDir = "\\server1\IT\AccountCreation\ProcessedCSVs"                #After we have processed CSVs, we move the files here
$HelpdeskPassword = "nottherealpassword"                                        #Password for the Admin user on Office365
$LiveSession = $Null                                                            #This will eventually contain the Office365 remote powershell session
$NewStudents = @()                                                              #This will eventually contian an array of all of the new student accounts to create
$FullyCreatedStudents = @()                                                     #This will eventually contain an array of all new student accounts that had both an AD user account and email address made
$PartiallyCreatedStudents = @()                                                 #This will eventually contain an array of student accounts that were only partially created

#Variables for output data email
$OutputDataEmailBody = "Attached are new students email addresses."             #Subject of email containing student data, specifically new email addresses
$OutputDataEmailSub = "New Students Raw Data"
$EmailAddressToSendOutputDataTo = "user@domain.edu"
$ErrorEmailAddress = "user@domain.edu"


# =============================================================================================================================================================
#    Functions
# =============================================================================================================================================================

# =============================================================================================================================================================
#   Import Active Directory module and create Office365 remote powershell session
# =============================================================================================================================================================
function Load-StudentUserCreationEnviroment 
    {
        if (-not (Get-Module ActiveDirectory))
            {
                Import-module ActiveDirectory
            }

        #Load Exchange Server 2010 Management Shell if not loaded. You may delete/comment out this step if you are running the script from the Exchange Management Shell 
        $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchangeserver.domain.edu/PowerShell/ -Authentication Kerberos
        Import-PSSession $ExchangeSession -AllowClobber -DisableNameChecking
        
        #Create PSSession for Office365
        $LivePassword = ConvertTo-securestring -Force -AsPlainText $HelpdeskPassword
        $LiveCred = new-object -typename System.Management.Automation.PSCredential -argumentlist "admin@domian.edu",$LivePassword
        New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic –AllowRedirection -Name Live -ErrorAction SilentlyContinue
        
        #This changes the LiveSession variable to the Office365 PSSession.  It passes the PSSession object up out of this function
        Set-Variable -Name LiveSession -Value (Get-PSSession -Name Live) -Scope 1
    }

# =============================================================================================================================================================
#   The opposite of Load-StudentUserCreationEnviroment     
# =============================================================================================================================================================
function UnLoad-StudentUserCreationEnviroment 
    {
        if (Get-Module ActiveDirectory)
            {
    
                Remove-module ActiveDirectory
            }

        #Remove Exchange Server 2010 Management Shell if not loaded. You may delete/comment out this step if you are running the script from the Exchange Management Shell 
        Get-PSSession -ComputerName exchangeserver.domain.edu | Remove-PSSession
        
        
        # Remove PSSession for Office365
        $LiveSession | Remove-PSSession -ErrorAction SilentlyContinue
        $LiveSession = $Null
        
    }

# =============================================================================================================================================================
#   Creates the student mailbox    
# =============================================================================================================================================================
function Create-Mailbox ($this_DisplayName, $this_EmailAddress, $this_first_name, $this_last_name, $this_Initial, $this_Password)
    {
        Write-Host "Creating Mailbox for $this_DisplayName" -ForegroundColor blue
        Invoke-Command -Session $LiveSession -ScriptBlock {param ($IvDisplayName,$IvPassword,$IvEmailAddress,$Ivfirst_name,$Ivlast_name,$IvInitial) `
            New-MailBox -Name $IvDisplayName -Password $IvPassword -DisplayName $IvDisplayName -FirstName $Ivfirst_name -LastName $Ivlast_name -MicrosoftOnlineServicesID $IvemailAddress -Initial $IvInitial -ErrorAction SilentlyContinue } `
            -Arg $this_DisplayName,$this_Password,$this_EmailAddress,$this_first_name,$this_last_name,$this_Initial > $results
                
            
        if (Invoke-Command -Session $LiveSession -ScriptBlock {param ($InvokeEm) Get-Mailbox -Identity $InvokeEm } -Arg $this_EmailAddress -ErrorAction SilentlyContinue )
        {
            Write-Host "Mailbox with the email address of $this_EmailAddress has just been successfully created." -ForegroundColor blue
            $exitcode = $True
            $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Mailbox with the email address of $this_EmailAddress has just been successfully created." -PassThru
        }
        else
        {
            Write-Host "Failed to create mailbox for $this_DisplayName." -ForegroundColor red
            $exitcode = $False
            $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Failed to create mailbox for $this_DisplayName." -PassThru
        }
        
    }

# =============================================================================================================================================================
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function Test-ADUserAlreadyExists ($this_id_num, $this_samAccountName, $this_ADuserDisplayName, $this_LegacyDisplayName,  $this_AddressBookDisplayName)
    {
        if (Get-ADUser -filter {(employeeID -eq $this_id_num) -or (employeeNumber -eq $this_id_num)} -ErrorAction SilentlyContinue)
            {
                Write-Host "User  $this_AddressBookDisplayName already has an AD User account with the same ID Number of $this_id_num" -ForegroundColor red
                $solid = $False
                return $solid
            }
        if (Get-ADUser -filter {(samAccountName -eq $this_samAccountName)} -ErrorAction SilentlyContinue)
            {
                Write-Host "User  $this_AddressBookDisplayName already has an AD User account with the same login as $this_samAccountName" -ForegroundColor red
                $solid = $False
                return $solid
            }
        if ((Get-ADUser -Filter {(displayName -eq $this_ADuserDisplayName)} -ErrorAction SilentlyContinue) -or (Get-ADUser -Filter {(displayName -eq $this_LegacyDisplayName)} -ErrorAction SilentlyContinue))
            {
                Write-Host "User  $this_AddressBookDisplayName already has a AD User account with the same name as $this_ADuserDisplayName or $this_LegacyDisplayName" -ForegroundColor red
                $solid = $False
                return $solid
            }
        
        $solid = $True
        return $solid 
    }

# =============================================================================================================================================================    
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function Test-ADContactAlreadyExists ($this_ADuserDisplayName, $this_AddressBookDisplayName, $this_EmailAddress)
    {
        if (Get-MailContact -Identity $this_EmailAddress -ErrorAction SilentlyContinue)            
            {
                Write-Host "User $this_AddressBookDisplayName already has an AD Contact with the same email address of $this_EmailAddress" -ForegroundColor red
                $solid = $False
                return $solid
            }
        if ((Get-MailContact -Filter {(displayName -eq $this_ADuserDisplayName)} -ErrorAction SilentlyContinue) -or (Get-MailContact -Filter {(displayName -eq $this_AddressBookDisplayName)} -ErrorAction SilentlyContinue))
            {
                Write-Host "User $this_AddressBookDisplayName already has an AD Contact with the same name as $this_ADuserDisplayName or $this_AddressBookDisplayName" -ForegroundColor red
                $solid = $False
                return $solid
            }
        
        $solid = $True
        return $solid
         
    }
# =============================================================================================================================================================    
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function Test-MailboxAlreadyExists ($this_DisplayName, $this_EmailAddress)
    {
       if (Invoke-Command -Session $LiveSession -ScriptBlock {param ($InvokeEm) Get-MailContact -Identity $InvokeEm -ErrorAction SilentlyContinue } -Arg $this_EmailAddress -ErrorAction SilentlyContinue )
        {
            Write-Host "A contact with the email address $this_EmailAddress already exists.  Verify that this is not a Faculty or Staff user." -ForegroundColor red
            $solid = $False
            return $solid
        }
        if (Invoke-Command -Session $LiveSession -ScriptBlock {param ($InvokeDisName) Get-MailContact -Identity $InvokeDisName -ErrorAction SilentlyContinue} -Arg $this_DisplayName -ErrorAction SilentlyContinue )
        {
            Write-Host "A contact with the $this_DisplayName already exists. Verify that this is not a Faculty or Staff user." -ForegroundColor red
            $solid = $False
            return $solid
        }
        if (Invoke-Command -Session $LiveSession -ScriptBlock {param ($InvokeEm) Get-Mailbox -Identity $InvokeEm -ErrorAction SilentlyContinue} -Arg $this_EmailAddress -ErrorAction SilentlyContinue )
        {
            Write-Host "A mailbox with the email address of $this_EmailAddress already exists." -ForegroundColor red
            $solid = $False
            return $solid
        }
        if (Invoke-Command -Session $LiveSession -ScriptBlock {param ($InvokeDisName) Get-Mailbox -Identity $InvokeDisName -ErrorAction SilentlyContinue} -Arg $this_DisplayName -ErrorAction SilentlyContinue)
        {
            Write-Host "A mailbox with the Name of $this_DisplayName already exists." -ForegroundColor red
            $solid = $False
            return $solid
        }
        
        $solid = $True
        return $solid 
    }        

# =============================================================================================================================================================
#    Import working CSV files and output each new user object
# =============================================================================================================================================================
function Get-NewStudent   ($DataSourceDir, $DataWorkingDir)
    {
        #  Move files from the dump dir to the working dir
        dir $DataSourceDir -Filter *.csv | mv -Destination $DataWorkingDir
        
        #  Import all unique Students
        $NewTradStudents = dir $DataWorkingDir -Filter Trad*.csv | Import-CSV  | sort id_num –Unique
        $NewGradStudents = dir $DataWorkingDir -Filter Grad*.csv | Import-CSV  | sort id_num –Unique

        $AllUsersRaw = @()
        
        # Add their status as a new property
        
        foreach ($user in $NewTradStudents)
        {
            if (Get-GoodCSVLine $user)
            {
                $user | Add-Member NoteProperty Status "TRADStudent"
                $user | Add-Member NoteProperty userAccountOU "OU=Students,DC=domain,DC=edu"
                $user | Add-Member NoteProperty contactAccountOU "TRADStudent"
                
                $AllUsersRaw = $AllUsersRaw + $user
            }
        }
        
        foreach ($user in $NewGradStudents)
        {
            if (Get-GoodCSVLine $user)
            {
                $user | Add-Member NoteProperty Status "GRADStudent"
                $user | Add-Member NoteProperty userAccountOU "OU=GPS,OU=Students,DC=domain,DC=edu"
                $user | Add-Member NoteProperty contactAccountOU "GASStudent"
                
                $AllUsersRaw = $AllUsersRaw + $user
            }
        }
        
        #  Add some new fields that will eventually be generated
        foreach ($user in $AllUsersRaw)
        {
            $EachNewUser = New-Object System.Management.Automation.PsObject
            $EachNewUser = $user
            $EachNewUser | Add-Member NoteProperty samAccountName $Null
            $EachNewUser | Add-Member NoteProperty emailAddress $Null
            $EachNewUser | Add-Member NoteProperty UPN $Null
            $EachNewUser | Add-Member NoteProperty AddressBookDisplayName $Null
            $EachNewUser | Add-Member NoteProperty ADuserDisplayName $Null
            $EachNewUser | Add-Member NoteProperty LegacyDisplayName $Null
            $EachNewUser | Add-Member NoteProperty HomeDirectory $Null
            $EachNewUser | Add-Member NoteProperty NewPassword $Null
            $EachNewUser | Add-Member NoteProperty PasswordShortBy $Null
            
            #Create and make sure the Student ID number is as least 6 characters long for Email password
            
            if ($EachNewUser.id_num.length -lt 6)
            {
                $EachNewUser.NewPassword = $EachNewUser.id_num
                $numberLess = (6 - $EachNewUser.id_num.length)
                $EachNewUser.PasswordShortBy = $numberLess
                for($i=0; $i -lt $numberLess; $i++) 
                {
                    $EachNewUser.NewPassword += "0"
                }
            }
            else
            {
                $EachNewUser.NewPassword = $EachNewUser.id_num
            }    
               
            #$last_nameWithoutPunc = $Null
            $last_nameWithoutPunc = $Null
                
            # Create middle initial if there isn't one
            if (!($EachNewUser.middle_name))
            {
                $EachNewUser.middle_name = "X"
            } 
                
            #Get the users last name without punctuation and the right length
            $last_nameWithoutPunc =[System.Text.RegularExpressions.Regex]::Replace($EachNewUser.last_name,"[^1-9a-zA-Z_]","");
               
            #Create the SAMAccountName of the right length
            $EachNewUser.samAccountName = $EachNewUser.first_name.Substring(0,1) + $EachNewUser.middle_name.Substring(0,1) + $last_nameWithoutPunc 
            if ($($EachNewUser.samAccountName).length -gt 20){$EachNewUser.samAccountName = $($EachNewUser.samAccountName).Substring(0,20)}
               
            #All of the different Display Names
            $EachNewUser.AddressBookDisplayName = $EachNewUser.first_name + " " + $EachNewUser.middle_name.Substring(0,1) + "." + " " + $EachNewUser.last_name
            $EachNewUser.ADuserDisplayName = $EachNewUser.last_name + ", " + $EachNewUser.first_name + " " + $EachNewUser.middle_name.Substring(0,1) + "."
            $EachNewUser.LegacyDisplayName = $EachNewUser.first_name + " " + $EachNewUser.last_name
    
            #Polish off the remaining fields
            $EachNewUser.UPN = $EachNewUser.samAccountName + "@domain.edu"
            $EachNewUser.HomeDirectory = "\\server1\Students\" + $EachNewUser.samAccountName
                   
            #Create email address
            $EachNewUser.emailAddress = $EachNewUser.samAccountName + "@domain.edu"
    
            $EachNewUser            
            
        }
    }

# =============================================================================================================================================================
#    Create Home Directory
# =============================================================================================================================================================        
function Create-UserHomeDirectory 
    {
        param
        (
            [Parameter(Mandatory=$true)]
            $username,
            $permissions = 'F'
        )

        $folderpath = "\\server1\Students\$username"

        # Create Folder:
        if ((Test-Path $folderpath) -eq $false) 
        {
            md $folderpath | Out-Null
            
            # Add NTFS permissions using icacls.exe
            $result = icacls.exe ('"{0}" /grant:r {1}:(OI)(CI){2} ' -f $folderpath, $username, $permissions) 2>&1
            
            # Check status and report errors
            $exitcode = ($LASTEXITCODE -eq 0)
            $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Creating home folder $($folderpath)" -PassThru
            $exitcode | Add-Member NoteProperty ExitCode $LASTEXITCODE -PassThru
            
            Write-Host "Creating home folder $($folderpath) " -ForegroundColor blue
        }

        else
        {
            $exitcode = $False
            $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Folder $($folderpath) already existed." -PassThru
            Write-Host "Folder $($folderpath) already existed." -ForegroundColor red
        }
        
    }
   

# =============================================================================================================================================================
#    Sends emails from AccountCreator@domain.edu
# =============================================================================================================================================================
function SendEmail

    {
        Param ($To, $Subject, $Body, $Attach)

        $msg = New-Object Net.Mail.MailMessage
        $msg.From = "AccountCreator@domain.edu"
        $msg.To.Add($To)
        $msg.Body = $Body
        $msg.Subject = $Subject
        
        #Parse File Array and attach each file
        if ($Attach)
        {
            foreach ($FileToAttach in $Attach)
            {
                $att = New-Object Net.Mail.Attachment($FileToAttach.fullname)
                $msg.Attachments.Add($att)

                #Error check if required
                # Write-Output "Have attached an attachment"

            }
        }            

        $client = New-Object net.Mail.SmtpClient("mail.domain.edu")
        $client.Send($msg)

        #Error Check if required
        #Write-Output "E-mail message sent"

    }


# =============================================================================================================================================================
#    Check for blank fields in imported data
# =============================================================================================================================================================
function Get-GoodCSVLine ($line)
    {  
                
        if (!($line.first_name))
            {
                Write-Host "There is no first name specified, possibly a blank line." -ForegroundColor red
                $solid = $False
                return $solid
            }
           
        if (!($line.last_name))
            {
                Write-Host "There is no last name specified, possibly a blank line." -ForegroundColor red
                $solid = $False
                return $solid
            }
             
        if (!($line.id_num))
            {
                Write-Host "There is no student ID specified in $($line.first_name) $($line.last_name) ." -ForegroundColor red
                $solid = $False
                return $solid
            } 
            
        # Everything checked out    
        $solid = $True
        return $solid
    }


# =============================================================================================================================================================
#    Begin Execution of script
# =============================================================================================================================================================

#Load files to begin processing only if new files in the directory
if ((Test-Path ($DataSourceDir + "\*.csv")) -or (Test-Path ($DataWorkingDir + "\*.csv")))
{
    Load-StudentUserCreationEnviroment   
    
    $NewStudents = Get-NewStudent $DataSourceDir $DataWorkingDir
    
    if ($NewStudents)
    {   
        $i = 0
        
        foreach($user in $NewStudents)
        {
            #Visual progress bar if you are running the script manually
            if ($NewStudents.count)
            {
                $i = $i + 1
                Write-Progress -Activity "Percent New Users Processed" -status "New User $i" -percentComplete ($i / $NewStudents.count*100)
            }                
            
            $user | Add-Member NoteProperty CreatedADuser $False
            $user | Add-Member NoteProperty CreatedADcontact $False
            $user | Add-Member NoteProperty CreatedEmail $False
            $user | Add-Member NoteProperty CreatedUserHomeDir $False
            $user | Add-Member NoteProperty CreatedUserInfoLetter $False
            
            $user | Add-Member NoteProperty CreatedADuserLogMessage "Did not create AD user account for unknown reason."
            $user | Add-Member NoteProperty CreatedADcontactLogMessage "Did not create AD contact account for unknown reason."
            $user | Add-Member NoteProperty CreatedEmailLogMessage "Did not create Email account for unknown reason."
            $user | Add-Member NoteProperty CreatedUserHomeDirLogMessage "Did not create user's home directory for unknown reason."
            
            #Creating a secure string out of the students ID for the password
                $Pword = ConvertTo-SecureString $user.NewPassword -asplaintext -force
            
            #Test for and maybe creates a AD user
            if (Test-ADUserAlreadyExists $($user.id_num) $($user.samAccountName) $($user.ADuserDisplayName) $($user.LegacyDisplayName) $( $user.AddressBookDisplayName))
            {
                Write-Host "Creating AD User $($user.samAccountName)" -ForegroundColor blue
                
                
                
                New-ADUser -Name  $($user.samAccountName) `
                    -Path $($user.userAccountOU) `
                    -DisplayName $($user.ADuserDisplayName) `
                    -UserPrincipalName $($user.UPN) `
                    -GivenName $($user.first_name) `
                    -Surname $($user.last_name) `
                    -OtherName $($user.middle_name) `
                    -Initials $($user.middle_name.Substring(0,1)) `
                    -EmailAddress $($user.emailAddress) `
                    -HomeDrive H: `
                    -HomeDirectory $($user.HomeDirectory) `
                    -PasswordNeverExpires:$true `
                    -EmployeeID $($user.id_num) `
                    -AccountPassword $Pword `
                    -ChangePasswordAtLogon $False `
                    -Enabled $True > $results
                    
                Set-ADUser $($user.samAccountName) -Replace @{Pager = $user.id_num}
                Get-ADUser $($user.samAccountName) | Rename-ADObject -NewName $($user.ADuserDisplayName)
                Add-ADGroupMember -Identity PaperCut -Member $($user.samAccountName)
                Add-ADGroupMember -Identity Student_Group -Member $($user.samAccountName)
                
                $user.CreatedADuser = $True
            }
    
            #Test for and maybe creates a AD contact 
    
            if (Test-ADContactAlreadyExists $($user.ADuserDisplayName) $($user.AddressBookDisplayName) $($user.EmailAddress))
            {
                Write-Host "Creating AD Contact $($user.samAccountName)" -ForegroundColor blue
                New-MailContact -Name $($user.AddressBookDisplayName) `
                -ExternalEmailAddress $($user.emailAddress) `
                -Firstname $($user.first_name) `
                -Lastname $($user.last_name) `
                -OrganizationalUnit $($user.contactAccountOU) `
                -ErrorAction Continue > $results
                
                $user.CreatedADcontact = $True
            }  
                
            #Test for and maybe creates an Mailbox
        
            if (Test-MailboxAlreadyExists $($user.AddressBookDisplayName) $($user.emailAddress))
            {
                Create-Mailbox $($user.AddressBookDisplayName) $($user.emailAddress) $($user.first_name) $($user.last_name) $($user.middle_name.Substring(0,1)) $Pword $($user.DistributionListCustomField)
                
                $user.CreatedEmail = $True
                $user.CreatedEmailLogMessage = "Did not create Email account for unknown reason."
            }
        
            #Test for and maybe create Home Directory
            $rv = Create-UserHomeDirectory $($user.samAccountName)
            if ($rv)
            {
                $user.CreatedUserHomeDir = $True
                $user.CreatedUserHomeDirLogMessage = $rv.StatusMessage
            }
            else
            {
                $user.CreatedUserHomeDirLogMessage = $rv.StatusMessage
            }
        
            #Add user either to $FullyCreatedStudents or $PartiallyCreatedStudents 
            if (($user.CreatedADuser) -and ($user.CreatedADcontact) -and ($user.CreatedEmail) -and ($user.CreatedUserHomeDir))
            {
                $FullyCreatedStudents += $user
            }
            else
            {
                $PartiallyCreatedStudents += $user
            }
       
        }  # End of big for each loop
        
        # Create success logs and arrays
        #$FullyCreatedStudents | ft
        #$PartiallyCreatedStudents |ft
                       
            Write-Host "Beginning to send csv" -ForegroundColor blue
            #Lets send helpdesk the finalized data in a CSV
            $NewStudents | select id_num, first_name, last_name, emailAddress, samAccountName, email_address | Export-Csv -NoTypeInformation -Path $($DataWorkingDir + "\newEmailAddresses.csv")
            $FinishedCSV = dir $($DataWorkingDir + "\newEmailAddresses.csv")
            SendEmail $EmailAddressToSendOutputDataTo $OutputDataEmailSub $OutputDataEmailBody $FinishedCSV
            
            #Clean out Working directory
            #All done, move the procesed files to the $DataProcessed location.  
            #Attaching the files to the email takes a bit so we put the command in a do while loop till its done.

            $attempts = 0       #setting initial number of attempts to 0 for cleaning up working directory
            $again = $true      #default do/while loop test value
            do 
            {
                Remove-Item $($DataWorkingDir + "\newEmailAddresses.csv") -ErrorAction SilentlyContinue
                $Stoploop = $?        #capture the success/failure true/false status
                
                if ($Stoploop -ne $True) { Start-Sleep -s 5; $attempts++ }    #wait 5 seconds if a failure occured and increment to number of attempts
                else {$again = $false}
                
                if ($attempts -eq 50) {$again = $false}    #limiting attempts to 50
            }
            While ($again -eq $true)
            
        }
            
        UnLoad-StudentUserCreationEnviroment 
    
    }
    else { Write-Host "There were no good lines in the CSV files.  They are located in $($DataWorkingDir)." -ForegroundColor red }

Open in new window

PowerShell NewbieAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jose Gabriel Ortega CEE Solution Guide - CEO Faru Bonon ITCommented:
This expert suggested creating a Gigs project.
I'd propose a gig for it since it's almost a  550 lines script.
0
David Johnson, CD, MVPOwnerCommented:
You should export the functions to modules, move the globals to the calling script, use parameters for globals, I'd change most of the write-hosts to write-verbose and any error write-hosts to write-error
# =============================================================================================================================================================
#    Student Creation Script
# =============================================================================================================================================================
=============================================================================================================================================================
#    Functions
# =============================================================================================================================================================

# =============================================================================================================================================================
#   Import Active Directory module and create Office365 remote powershell session
# =============================================================================================================================================================
function script:Load-StudentUserCreationEnviroment 
{
  <#
      .SYNOPSIS
      Describe purpose of "Load-StudentUserCreationEnviroment" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .EXAMPLE
      Load-StudentUserCreationEnviroment
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Load-StudentUserCreationEnviroment

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  if (-not (Get-Module -Name ActiveDirectory))
  {
    Import-Module -Name ActiveDirectory
  }

  #Load Exchange Server 2010 Management Shell if not loaded. You may delete/comment out this step if you are running the script from the Exchange Management Shell 
  $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exchangeserver.domain.edu/PowerShell/ -Authentication Kerberos
  Import-PSSession -Session $ExchangeSession -AllowClobber -DisableNameChecking
        
  #Create PSSession for Office365
  $LivePassword = ConvertTo-SecureString -Force -AsPlainText -String $HelpdeskPassword
  $LiveCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'admin@domian.edu', $LivePassword
  New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection -Name Live -ErrorAction SilentlyContinue
        
  #This changes the LiveSession variable to the Office365 PSSession.  It passes the PSSession object up out of this function
  Set-Variable -Name LiveSession -Value (Get-PSSession -Name Live) -Scope 1
}

# =============================================================================================================================================================
#   The opposite of Load-StudentUserCreationEnviroment     
# =============================================================================================================================================================
function script:UnLoad-StudentUserCreationEnviroment 
{
  <#
      .SYNOPSIS
      Describe purpose of "UnLoad-StudentUserCreationEnviroment" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .EXAMPLE
      UnLoad-StudentUserCreationEnviroment
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online UnLoad-StudentUserCreationEnviroment

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  if (Get-Module -Name ActiveDirectory)
  {
    Remove-Module -Name ActiveDirectory
  }

  #Remove Exchange Server 2010 Management Shell if not loaded. You may delete/comment out this step if you are running the script from the Exchange Management Shell 
  Get-PSSession -ComputerName exchangeserver.domain.edu | Remove-PSSession
        
        
  # Remove PSSession for Office365
  $LiveSession | Remove-PSSession -ErrorAction SilentlyContinue
  $LiveSession = $Null
}

# =============================================================================================================================================================
#   Creates the student mailbox    
# =============================================================================================================================================================
function script:Create-Mailbox ([Object]$this_DisplayName, [Object]$this_EmailAddress, [Object]$this_first_name, [Object]$this_last_name, [Object]$this_Initial, [Object]$this_Password)
{
  <#
      .SYNOPSIS
      Describe purpose of "Create-Mailbox" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER this_DisplayName
      Describe parameter -this_DisplayName.

      .PARAMETER this_EmailAddress
      Describe parameter -this_EmailAddress.

      .PARAMETER this_first_name
      Describe parameter -this_first_name.

      .PARAMETER this_last_name
      Describe parameter -this_last_name.

      .PARAMETER this_Initial
      Describe parameter -this_Initial.

      .PARAMETER this_Password
      Describe parameter -this_Password.

      .EXAMPLE
      Create-Mailbox -this_DisplayName Value -this_EmailAddress Value -this_first_name Value -this_last_name Value -this_Initial Value -this_Password Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Create-Mailbox

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  Write-Host "Creating Mailbox for $this_DisplayName" -ForegroundColor blue
  Invoke-Command -Session $LiveSession -ScriptBlock {
    param ([Object]$IvDisplayName,[Object]$IvPassword,[Object]$IvEmailAddress,[Object]$Ivfirst_name,[Object]$Ivlast_name,[Object]$IvInitial) `
    New-MailBox -Name $IvDisplayName -Password $IvPassword -DisplayName $IvDisplayName -FirstName $Ivfirst_name -LastName $Ivlast_name -MicrosoftOnlineServicesID $IvEmailAddress -Initial $IvInitial -ErrorAction SilentlyContinue
  } `
  -ArgumentList $this_DisplayName, $this_Password, $this_EmailAddress, $this_first_name, $this_last_name, $this_Initial > $results
                
            
  if (Invoke-Command -Session $LiveSession -ScriptBlock {
      param ([Object]$InvokeEm) Get-Mailbox -Identity $InvokeEm
  } -ArgumentList $this_EmailAddress -ErrorAction SilentlyContinue )
  {
    Write-Host "Mailbox with the email address of $this_EmailAddress has just been successfully created." -ForegroundColor blue
    $exitcode = $True
    $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Mailbox with the email address of $this_EmailAddress has just been successfully created." -PassThru
  }
  else
  {
    Write-Host "Failed to create mailbox for $this_DisplayName." -ForegroundColor red
    $exitcode = $False
    $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Failed to create mailbox for $this_DisplayName." -PassThru
  }
}

# =============================================================================================================================================================
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function script:Test-ADUserAlreadyExists ([Object]$this_id_num, [Object]$this_samAccountName, [Object]$this_ADuserDisplayName, [Object]$this_LegacyDisplayName,  [Object]$this_AddressBookDisplayName)
{
  <#
      .SYNOPSIS
      Describe purpose of "Test-ADUserAlreadyExists" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER this_id_num
      Describe parameter -this_id_num.

      .PARAMETER this_samAccountName
      Describe parameter -this_samAccountName.

      .PARAMETER this_ADuserDisplayName
      Describe parameter -this_ADuserDisplayName.

      .PARAMETER this_LegacyDisplayName
      Describe parameter -this_LegacyDisplayName.

      .PARAMETER this_AddressBookDisplayName
      Describe parameter -this_AddressBookDisplayName.

      .EXAMPLE
      Test-ADUserAlreadyExists -this_id_num Value -this_samAccountName Value -this_ADuserDisplayName Value -this_LegacyDisplayName Value -this_AddressBookDisplayName Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Test-ADUserAlreadyExists

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  if (Get-ADUser -filter {
      (employeeID -eq $this_id_num) -or (employeeNumber -eq $this_id_num)
  } -ErrorAction SilentlyContinue)
  {
    Write-Host "User  $this_AddressBookDisplayName already has an AD User account with the same ID Number of $this_id_num" -ForegroundColor red
    $solid = $False
    return $solid
  }
  if (Get-ADUser -filter {
      (samAccountName -eq $this_samAccountName)
  } -ErrorAction SilentlyContinue)
  {
    Write-Host "User  $this_AddressBookDisplayName already has an AD User account with the same login as $this_samAccountName" -ForegroundColor red
    $solid = $False
    return $solid
  }
  if ((Get-ADUser -Filter {
        (displayName -eq $this_ADuserDisplayName)
    } -ErrorAction SilentlyContinue) -or (Get-ADUser -Filter {
        (displayName -eq $this_LegacyDisplayName)
  } -ErrorAction SilentlyContinue))
  {
    Write-Host "User  $this_AddressBookDisplayName already has a AD User account with the same name as $this_ADuserDisplayName or $this_LegacyDisplayName" -ForegroundColor red
    $solid = $False
    return $solid
  }
        
  $solid = $True
  return $solid 
}

# =============================================================================================================================================================    
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function script:Test-ADContactAlreadyExists ([Object]$this_ADuserDisplayName, [Object]$this_AddressBookDisplayName, [Object]$this_EmailAddress)
{
  if (Get-MailContact -Identity $this_EmailAddress -ErrorAction SilentlyContinue)            
  {
    Write-Host "User $this_AddressBookDisplayName already has an AD Contact with the same email address of $this_EmailAddress" -ForegroundColor red
    $solid = $False
    return $solid
  }
  if ((Get-MailContact -Filter {
        (displayName -eq $this_ADuserDisplayName)
    } -ErrorAction SilentlyContinue) -or (Get-MailContact -Filter {
        (displayName -eq $this_AddressBookDisplayName)
  } -ErrorAction SilentlyContinue))
  {
    Write-Host "User $this_AddressBookDisplayName already has an AD Contact with the same name as $this_ADuserDisplayName or $this_AddressBookDisplayName" -ForegroundColor red
    $solid = $False
    return $solid
  }
        
  $solid = $True
  return $solid
}
# =============================================================================================================================================================    
#   Verifies student information values in a row in the CSV 
# =============================================================================================================================================================
function script:Test-MailboxAlreadyExists ([Object]$this_DisplayName, [Object]$this_EmailAddress)
{
  <#
      .SYNOPSIS
      Describe purpose of "Test-MailboxAlreadyExists" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER this_DisplayName
      Describe parameter -this_DisplayName.

      .PARAMETER this_EmailAddress
      Describe parameter -this_EmailAddress.

      .EXAMPLE
      Test-MailboxAlreadyExists -this_DisplayName Value -this_EmailAddress Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Test-MailboxAlreadyExists

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  if (Invoke-Command -Session $LiveSession -ScriptBlock {
      param ([Object]$InvokeEm) Get-MailContact -Identity $InvokeEm -ErrorAction SilentlyContinue
  } -ArgumentList $this_EmailAddress -ErrorAction SilentlyContinue )
  {
    Write-Host "A contact with the email address $this_EmailAddress already exists.  Verify that this is not a Faculty or Staff user." -ForegroundColor red
    $solid = $False
    return $solid
  }
  if (Invoke-Command -Session $LiveSession -ScriptBlock {
      param ([Object]$InvokeDisName) Get-MailContact -Identity $InvokeDisName -ErrorAction SilentlyContinue
  } -ArgumentList $this_DisplayName -ErrorAction SilentlyContinue )
  {
    Write-Host "A contact with the $this_DisplayName already exists. Verify that this is not a Faculty or Staff user." -ForegroundColor red
    $solid = $False
    return $solid
  }
  if (Invoke-Command -Session $LiveSession -ScriptBlock {
      param ([Object]$InvokeEm) Get-Mailbox -Identity $InvokeEm -ErrorAction SilentlyContinue
  } -ArgumentList $this_EmailAddress -ErrorAction SilentlyContinue )
  {
    Write-Host "A mailbox with the email address of $this_EmailAddress already exists." -ForegroundColor red
    $solid = $False
    return $solid
  }
  if (Invoke-Command -Session $LiveSession -ScriptBlock {
      param ([Object]$InvokeDisName) Get-Mailbox -Identity $InvokeDisName -ErrorAction SilentlyContinue
  } -ArgumentList $this_DisplayName -ErrorAction SilentlyContinue)
  {
    Write-Host "A mailbox with the Name of $this_DisplayName already exists." -ForegroundColor red
    $solid = $False
    return $solid
  }
        
  $solid = $True
  return $solid 
}        

# =============================================================================================================================================================
#    Import working CSV files and output each new user object
# =============================================================================================================================================================
function script:Get-NewStudent   ([Object]$DataSourceDir, [Object]$DataWorkingDir)
{
  <#
      .SYNOPSIS
      Describe purpose of "Get-NewStudent" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER DataSourceDir
      Describe parameter -DataSourceDir.

      .PARAMETER DataWorkingDir
      Describe parameter -DataWorkingDir.

      .EXAMPLE
      Get-NewStudent -DataSourceDir Value -DataWorkingDir Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Get-NewStudent

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  #  Move files from the dump dir to the working dir
  Get-ChildItem $DataSourceDir -Filter *.csv | Move-Item -Destination $DataWorkingDir
        
  #  Import all unique Students
  $NewTradStudents = Get-ChildItem -Path $DataWorkingDir -Filter Trad*.csv |
  Import-Csv  |
  Sort-Object -Property id_num -Unique
  $NewGradStudents = Get-ChildItem -Path $DataWorkingDir -Filter Grad*.csv |
  Import-Csv  |
  Sort-Object -Property id_num -Unique

  $AllUsersRaw = @()
        
  # Add their status as a new property
        
  foreach ($user in $NewTradStudents)
  {
    if (Get-GoodCSVLine -line $user)
    {
      $user | Add-Member NoteProperty Status 'TRADStudent'
      $user | Add-Member NoteProperty userAccountOU 'OU=Students,DC=domain,DC=edu'
      $user | Add-Member NoteProperty contactAccountOU 'TRADStudent'
                
      $AllUsersRaw = $AllUsersRaw + $user
    }
  }
        
  foreach ($user in $NewGradStudents)
  {
    if (Get-GoodCSVLine -line $user)
    {
      $user | Add-Member NoteProperty Status 'GRADStudent'
      $user | Add-Member NoteProperty userAccountOU 'OU=GPS,OU=Students,DC=domain,DC=edu'
      $user | Add-Member NoteProperty contactAccountOU 'GASStudent'
                
      $AllUsersRaw = $AllUsersRaw + $user
    }
  }
        
  #  Add some new fields that will eventually be generated
  foreach ($user in $AllUsersRaw)
  {
    $EachNewUser = New-Object -TypeName System.Management.Automation.PsObject
    $EachNewUser = $user
    $EachNewUser | Add-Member NoteProperty samAccountName $Null
    $EachNewUser | Add-Member NoteProperty emailAddress $Null
    $EachNewUser | Add-Member NoteProperty UPN $Null
    $EachNewUser | Add-Member NoteProperty AddressBookDisplayName $Null
    $EachNewUser | Add-Member NoteProperty ADuserDisplayName $Null
    $EachNewUser | Add-Member NoteProperty LegacyDisplayName $Null
    $EachNewUser | Add-Member NoteProperty HomeDirectory $Null
    $EachNewUser | Add-Member NoteProperty NewPassword $Null
    $EachNewUser | Add-Member NoteProperty PasswordShortBy $Null
            
    #Create and make sure the Student ID number is as least 6 characters long for Email password
            
    if ($EachNewUser.id_num.length -lt 6)
    {
      $EachNewUser.NewPassword = $EachNewUser.id_num
      $numberLess = (6 - $EachNewUser.id_num.length)
      $EachNewUser.PasswordShortBy = $numberLess
      for($i = 0; $i -lt $numberLess; $i++) 
      {
        $EachNewUser.NewPassword += '0'
      }
    }
    else
    {
      $EachNewUser.NewPassword = $EachNewUser.id_num
    }    
               
    #$last_nameWithoutPunc = $Null
    $last_nameWithoutPunc = $Null
                
    # Create middle initial if there isn't one
    if (!($EachNewUser.middle_name))
    {
      $EachNewUser.middle_name = 'X'
    } 
                
    #Get the users last name without punctuation and the right length
    $last_nameWithoutPunc = [System.Text.RegularExpressions.Regex]::Replace($EachNewUser.last_name,'[^1-9a-zA-Z_]','')
               
    #Create the SAMAccountName of the right length
    $EachNewUser.samAccountName = $EachNewUser.first_name.Substring(0,1) + $EachNewUser.middle_name.Substring(0,1) + $last_nameWithoutPunc 
    if ($($EachNewUser.samAccountName).length -gt 20)
    {
      $EachNewUser.samAccountName = $($EachNewUser.samAccountName).Substring(0,20)
    }
               
    #All of the different Display Names
    $EachNewUser.AddressBookDisplayName = $EachNewUser.first_name + ' ' + $EachNewUser.middle_name.Substring(0,1) + '.' + ' ' + $EachNewUser.last_name
    $EachNewUser.ADuserDisplayName = $EachNewUser.last_name + ', ' + $EachNewUser.first_name + ' ' + $EachNewUser.middle_name.Substring(0,1) + '.'
    $EachNewUser.LegacyDisplayName = $EachNewUser.first_name + ' ' + $EachNewUser.last_name
    
    #Polish off the remaining fields
    $EachNewUser.UPN = $EachNewUser.samAccountName + '@domain.edu'
    $EachNewUser.HomeDirectory = '\\server1\Students\' + $EachNewUser.samAccountName
                   
    #Create email address
    $EachNewUser.emailAddress = $EachNewUser.samAccountName + '@domain.edu'
    
    $EachNewUser
  }
}

# =============================================================================================================================================================
#    Create Home Directory
# =============================================================================================================================================================        
function script:Create-UserHomeDirectory 
{
  <#
      .SYNOPSIS
      Describe purpose of "Create-UserHomeDirectory" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER username
      Describe parameter -username.

      .PARAMETER permissions
      Describe parameter -permissions.

      .EXAMPLE
      Create-UserHomeDirectory -username Value -permissions Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online Create-UserHomeDirectory

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  param
  (
    [Parameter(Mandatory = $True)]
    [Object]$username,
    [string]$permissions = 'F'
  )

  $folderpath = "\\server1\Students\$username"

  # Create Folder:
  if ((Test-Path $folderpath) -eq $False) 
  {
    $Null = mkdir $folderpath
            
    # Add NTFS permissions using icacls.exe
    $result = icacls.exe ('"{0}" /grant:r {1}:(OI)(CI){2} ' -f $folderpath, $username, $permissions) 2>&1
            
    # Check status and report errors
    $exitcode = ($LASTEXITCODE -eq 0)
    $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Creating home folder $($folderpath)" -PassThru
    $exitcode | Add-Member NoteProperty ExitCode $LASTEXITCODE -PassThru
            
    Write-Host "Creating home folder $($folderpath) " -ForegroundColor blue
  }

  else
  {
    $exitcode = $False
    $exitcode = $exitcode | Add-Member NoteProperty StatusMessage "Folder $($folderpath) already existed." -PassThru
    Write-Host "Folder $($folderpath) already existed." -ForegroundColor red
  }
}
   

# =============================================================================================================================================================
#    Sends emails from AccountCreator@domain.edu
# =============================================================================================================================================================
function script:SendEmail

{
  <#
      .SYNOPSIS
      Describe purpose of "SendEmail" in 1-2 sentences.

      .DESCRIPTION
      Add a more complete description of what the function does.

      .PARAMETER To
      Describe parameter -To.

      .PARAMETER Subject
      Describe parameter -Subject.

      .PARAMETER Body
      Describe parameter -Body.

      .PARAMETER Attach
      Describe parameter -Attach.

      .EXAMPLE
      SendEmail -To Value -Subject Value -Body Value -Attach Value
      Describe what this call does

      .NOTES
      Place additional notes here.

      .LINK
      URLs to related sites
      The first link is opened by Get-Help -Online SendEmail

      .INPUTS
      List of input types that are accepted by this function.

      .OUTPUTS
      List of output types produced by this function.
  #>


  Param ([Object]$To, [Object]$Subject, [Object]$Body, [Object]$Attach)

  $msg = New-Object -TypeName Net.Mail.MailMessage
  $msg.From = 'AccountCreator@domain.edu'
  $msg.To.Add($To)
  $msg.Body = $Body
  $msg.Subject = $Subject
        
  #Parse File Array and attach each file
  if ($Attach)
  {
    foreach ($FileToAttach in $Attach)
    {
      $att = New-Object -TypeName Net.Mail.Attachment -ArgumentList ($FileToAttach.fullname)
      $msg.Attachments.Add($att)

      #Error check if required
      # Write-Output "Have attached an attachment"
    }
  }            

  $client = New-Object -TypeName net.Mail.SmtpClient -ArgumentList ('mail.domain.edu')
  $client.Send($msg)

  #Error Check if required
  #Write-Output "E-mail message sent"
}


# =============================================================================================================================================================
#    Check for blank fields in imported data
# =============================================================================================================================================================
function Get-GoodCSVLine ([Object]$line)
{
  if (!($line.first_name))
  {
    Write-Host 'There is no first name specified, possibly a blank line.' -ForegroundColor red
    $solid = $False
    return $solid
  }
           
  if (!($line.last_name))
  {
    Write-Host 'There is no last name specified, possibly a blank line.' -ForegroundColor red
    $solid = $False
    return $solid
  }
             
  if (!($line.id_num))
  {
    Write-Host "There is no student ID specified in $($line.first_name) $($line.last_name) ." -ForegroundColor red
    $solid = $False
    return $solid
  } 
            
  # Everything checked out    
  $solid = $True
  return $solid
}


# =============================================================================================================================================================
#    Begin Execution of script
# =============================================================================================================================================================
function script:Create-NewStudents
{
  <#
      .SYNOPSIS
      Short Description
      .DESCRIPTION
      Detailed Description
      .EXAMPLE
      Create-NewStudents
      explains how to use the command
      can be multiple lines
      .EXAMPLE
      Create-NewStudents
      another example
      can have as many examples as you like
  #>
  [CmdletBinding()]
  param (
    [Parameter(Mandatory=$True,HelpMessage="This is the directory that the CSVs are dropped into")]
    [string]$DataSourceDir = '\\server1\IT\AccountCreation\ToBeProcessed',
    [Parameter(Mandatory=$True,HelpMessage="This is the directory that we move the current CSVs to work on")]
        [string]$DataWorkingDir = '\\server1\IT\AccountCreation\Working',
        [Parameter(Mandatory=$True,HelpMessage="After we have processed CSVs, we move the files here")]
        [string]$DataProcessedDir = '\\server1\IT\AccountCreation\ProcessedCSVs',
        [Parameter(Mandatory=$True,HelpMessage="Password for the Admin user on Office365")]
    [string]$HelpdeskPassword = 'nottherealpassword',
    [string]$EmailAddressToSendOutputDataTo = 'user@domain.edu',
        [Parameter(Mandatory=$True,HelpMessage="Address to send Error Messages")]
    [string]$ErrorEmailAddress = 'user@domain.edu'
  )
  #Variables for output data email
  #Subject of email containing student data, specifically new email addresses
  $OutputDataEmailBody = 'Attached are new students email addresses.'
  $OutputDataEmailSub = 'New Students Raw Data'
  #This will eventually contain the Office365 remote powershell session
  $LiveSession = $Null, 
  #This will eventually contain an array of all new student accounts to create
  $NewStudents = @()
  #This will eventually contain an array of all new student accounts that had both an AD user account and email address made
  $FullyCreatedStudents = @()
  #This will eventually contain an array of student accounts that were only partially created      
  $PartiallyCreatedStudents = @()

  #Load files to begin processing only if new files in the directory
  $sampleCSV = 'id_num,first_name,middle_name,last_name,email_address\n654321,Jason,M,Smith,darealmccoy@gmail.com'
  #>
  if ((Test-Path ($DataSourceDir + '\*.csv')) -or (Test-Path ($DataWorkingDir + '\*.csv')))
  {
    Load-StudentUserCreationEnviroment   
    
    $NewStudents = Get-NewStudent -DataSourceDir $DataSourceDir -DataWorkingDir $DataWorkingDir
    
    if ($NewStudents)
    {   
      $i = 0
      
      foreach($user in $NewStudents)
      {
        #Visual progress bar if you are running the script manually
        if ($NewStudents.count)
        {
          $i = $i + 1
          Write-Progress -Activity 'Percent New Users Processed' -Status "New User $i" -PercentComplete ($i / $NewStudents.count*100)
        }                
        
        $user | Add-Member NoteProperty CreatedADuser $False
        $user | Add-Member NoteProperty CreatedADcontact $False
        $user | Add-Member NoteProperty CreatedEmail $False
        $user | Add-Member NoteProperty CreatedUserHomeDir $False
        $user | Add-Member NoteProperty CreatedUserInfoLetter $False
        $user | Add-Member NoteProperty CreatedADuserLogMessage 'Did not create AD user account for unknown reason.'
        $user | Add-Member NoteProperty CreatedADcontactLogMessage 'Did not create AD contact account for unknown reason.'
        $user | Add-Member NoteProperty CreatedEmailLogMessage 'Did not create Email account for unknown reason.'
        $user | Add-Member NoteProperty CreatedUserHomeDirLogMessage "Did not create user's home directory for unknown reason."
        
        #Creating a secure string out of the students ID for the password
        $Pword = ConvertTo-SecureString -String $user.NewPassword -AsPlainText -Force
        
        #Test for and maybe creates a AD user
        if (Test-ADUserAlreadyExists -this_id_num $($user.id_num) -this_samAccountName $($user.samAccountName) -this_ADuserDisplayName $($user.ADuserDisplayName) -this_LegacyDisplayName $($user.LegacyDisplayName) -this_AddressBookDisplayName $( $user.AddressBookDisplayName))
        {
          Write-Host "Creating AD User $($user.samAccountName)" -ForegroundColor blue
          
          New-ADUser -Name  $($user.samAccountName) `
          -Path $($user.userAccountOU) `
          -DisplayName $($user.ADuserDisplayName) `
          -UserPrincipalName $($user.UPN) `
          -GivenName $($user.first_name) `
          -Surname $($user.last_name) `
          -OtherName $($user.middle_name) `
          -Initials $($user.middle_name.Substring(0,1)) `
          -EmailAddress $($user.emailAddress) `
          -HomeDrive H: `
          -HomeDirectory $($user.HomeDirectory) `
          -PasswordNeverExpires:$True `
          -EmployeeID $($user.id_num) `
          -AccountPassword $Pword `
          -ChangePasswordAtLogon $False `
          -Enabled $True > $results
          
          Set-ADUser $($user.samAccountName) -Replace @{
            Pager = $user.id_num
          }
          Get-ADUser $($user.samAccountName) | Rename-ADObject -NewName $($user.ADuserDisplayName)
          Add-ADGroupMember -Identity PaperCut -Member $($user.samAccountName)
          Add-ADGroupMember -Identity Student_Group -Member $($user.samAccountName)
          
          $user.CreatedADuser = $True
        }
        
        #Test for and maybe creates a AD contact 
        
        if (Test-ADContactAlreadyExists -this_ADuserDisplayName $($user.ADuserDisplayName) -this_AddressBookDisplayName $($user.AddressBookDisplayName) -this_EmailAddress $($user.EmailAddress))
        {
          Write-Host "Creating AD Contact $($user.samAccountName)" -ForegroundColor blue
          New-MailContact -Name $($user.AddressBookDisplayName) `
          -ExternalEmailAddress $($user.emailAddress) `
          -Firstname $($user.first_name) `
          -Lastname $($user.last_name) `
          -OrganizationalUnit $($user.contactAccountOU) `
          -ErrorAction Continue > $results
          
          $user.CreatedADcontact = $True
        }  
        
        #Test for and maybe creates an Mailbox
        
        if (Test-MailboxAlreadyExists -this_DisplayName $($user.AddressBookDisplayName) -this_EmailAddress $($user.emailAddress))
        {
          Create-Mailbox -this_DisplayName $($user.AddressBookDisplayName) -this_EmailAddress $($user.emailAddress) -this_first_name $($user.first_name) -this_last_name $($user.last_name) -this_Initial $($user.middle_name.Substring(0,1)) -this_Password $Pword $($user.DistributionListCustomField)
          
          $user.CreatedEmail = $True
          $user.CreatedEmailLogMessage = 'Did not create Email account for unknown reason.'
        }
        
        #Test for and maybe create Home Directory
        $rv = Create-UserHomeDirectory -username $($user.samAccountName)
        if ($rv)
        {
          $user.CreatedUserHomeDir = $True
          $user.CreatedUserHomeDirLogMessage = $rv.StatusMessage
        }
        else
        {
          $user.CreatedUserHomeDirLogMessage = $rv.StatusMessage
        }
        
        #Add user either to $FullyCreatedStudents or $PartiallyCreatedStudents 
        if (($user.CreatedADuser) -and ($user.CreatedADcontact) -and ($user.CreatedEmail) -and ($user.CreatedUserHomeDir))
        {
          $FullyCreatedStudents += $user
        }
        else
        {
          $PartiallyCreatedStudents += $user
        }
      }  # End of big for each loop
      
      # Create success logs and arrays
      #$FullyCreatedStudents | ft
      #$PartiallyCreatedStudents |ft
      
      Write-Host 'Beginning to send csv' -ForegroundColor blue
      #Lets send helpdesk the finalized data in a CSV
      $NewStudents |
      Select-Object -Property id_num, first_name, last_name, emailAddress, samAccountName, email_address |
      Export-Csv -NoTypeInformation -Path $($DataWorkingDir + '\newEmailAddresses.csv')
      $FinishedCSV = Get-ChildItem -Path $($DataWorkingDir + '\newEmailAddresses.csv')
      SendEmail -To $EmailAddressToSendOutputDataTo -Subject $OutputDataEmailSub -Body $OutputDataEmailBody -Attach $FinishedCSV
      
      #Clean out Working directory
      #All done, move the procesed files to the $DataProcessed location.  
      #Attaching the files to the email takes a bit so we put the command in a do while loop till its done.
      
      $attempts = 0       #setting initial number of attempts to 0 for cleaning up working directory
      $again = $True      #default do/while loop test value
      do 
      {
        Remove-Item -Path $($DataWorkingDir + '\newEmailAddresses.csv') -ErrorAction SilentlyContinue
        $Stoploop = $?        #capture the success/failure true/false status
        
        if ($Stoploop -ne $True) 
        {
          Start-Sleep -Seconds 5
          $attempts++
        }    #wait 5 seconds if a failure occured and increment to number of attempts
        else 
        {
          $again = $False
        }
        
        if ($attempts -eq 50) 
        {
          $again = $False
        }    #limiting attempts to 50
      }
      While ($again -eq $True)
    }
    
    UnLoad-StudentUserCreationEnviroment
  }
  else 
  {
    Write-Error -Message "There were no good lines in the CSV files.  They are located in $($DataWorkingDir)."
    Write-Error ('CSV Data Sample')
    Write-Error -Message ('id_num,first_name,middle_name,last_name,email_address\n654321,Jason,M,Smith,darealmccoy@gmail.com')
  }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.