<#
Copyright (c) 2015, Adam Beardwood
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: 
 
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution. 
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#>

#Requires -version 3

<#
.SYNOPSIS
	Creates new CDS Users from CSV input
.DESCRIPTION
    Generates new user accounts & mailboxes from information provided via csv
.PARAMETER csv
	CSV file containing user information
	CSV format is: samaccountname,firstname,surname,initial,email,enddate,description,department,sitename
	Enddate should be in the format: YYYY-MM-DD
.PARAMETER homeonly
	Only create home folders
.PARAMETER nohome
	Don't create home folders
.PARAMETER nohome
	Don't create mailbox
.EXAMPLE
    C:\>New-CDSUser.ps1 -csv "newusers.csv"
.NOTES
    Author: Adam Beardwood
    Date: March 11, 2015
	v1.0: Initial Release
#>

[CmdletBinding(DefaultParameterSetName="create")]
param
(
[Parameter(Mandatory=$true, HelpMessage="CSV with user details",ParameterSetName='create')][ValidateScript({Test-Path $_})] [Object] $csv,
[Parameter(Mandatory=$false, HelpMessage="Don't create home folders",ParameterSetName='create')][Switch] $nohome,
[Parameter(Mandatory=$false, HelpMessage="Don't create mailbox",ParameterSetName='create')][Switch] $nomail,

[Parameter(Mandatory=$false, HelpMessage="Only create home folders",ParameterSetName='homeonly')][Switch] $homeonly,
[Parameter(Mandatory=$true, HelpMessage="SamAccountName",ParameterSetName='homeonly')][string] $username
)

write-verbose "Import AD Module"
$Env:ADPS_LoadDefaultDrive = 0
if($(Get-Module -Name ActiveDirectory) -eq $null){try{Ipmo ActiveDirectory -ea Stop}catch{write-host "Error: Active Directory Powershell Module is required for this script to function" -foregroundcolor red;exit 1}}

write-verbose "Check to ensure that required scripts are present"
If(!(Test-Path "$PSScriptRoot\Permission-HomeDrive.ps1")){write-host "Error: Permission-HomeDrive.ps1 script is required for this script to function" -foregroundcolor red;exit 1}

# FUNCTION DEFINITIONS #
. $PSScriptRoot\Permission-HomeDrive.ps1

function createHomedrive($homepath, $samaccountname)
{
	
	If(!(Test-path "$homepath\$samaccountname")){
		try{
			$dummyfolder = (gc $Homepath\adduser.cfg | Select-string "DUMMY_DIR=*").tostring().replace("DUMMY_DIR=","")
			$homeroot = (gc $Homepath\adduser.cfg | Select-string "HOMES_DIR=*").tostring().replace("HOMES_DIR=","")
			$dummypath = (gci $dummyfolder -Filter "dummy*" | Select -first 1).fullname
			if(!$dummypath){
				write-host "Error: No more homedrive dummies available for use. Could not create homedrive for $samaccountname" -foregroundcolor red;return
			}
			
			move-item $dummypath "$homeroot\$samaccountname"
		}catch{
			write-host "Error: Couldn't create homedrive for $samaccountname`n$_" -foregroundcolor yellow;return
		}
	}else{
		write-host "Error: Homedrive folder already exists for user $samaccountname" -foregroundcolor red;return
	}
	
	if(Test-Path "$homepath\$samaccountname"){	
		permissionHomedrive -homepath $homeroot -samaccountname $samaccountname
	}else{
		wtite-host "Error: Homedrive folder creation has failed" -foregroundcolor red;return
	}
	

}

function generatePassword
{
	$One = "Amsterdam","Athens","Berlin","Budapest","Canberra","Damascus","Gibraltar","Helsinki","London","Moscow","Paris","Stockholm","Tokyo","Washington","Zagreb"
	$Two = "Ape","Badger","Camel","Dingo","Frog","Gorilla","Hippo","Koala","Lion","Monkey","Orca","Possum","Rabbit","Snake","Tiger","Unicorn","Wolf","Yak","Zebra"
	$Three = "Red","Orange","Yellow","Green","Blue","Indigo","Violet","White","Black"
	$Password = "$(Get-Random $Three)$($(Get-Random -max 100 -min 0).ToString("00"))$(Get-Random $One)$(Get-Random $Two)"

	Return $Password
}

function addGroups($site, $samaccountname)
{
	write-verbose "Add users to any site-specific groups"
	switch ($site){
		BHM1{
			Add-ADGroupMember -Identity "aec.bhm.allusers" -Members $samaccountname -Confirm:$False
		}DBY1{
			Add-ADGroupMember -Identity "aec.dby.allusers" -Members $samaccountname -Confirm:$False
		}BFS1{
			Add-ADGroupMember -Identity "aec.bfs.allusers" -Members $samaccountname -Confirm:$False
		}
	}

	write-verbose "Add users to any generic groups"
	Add-ADGroupMember -Identity "ITSD_Customers" -Members $samaccountname -Confirm:$False
	Add-ADGroupMember -Identity "Wireless Users" -Members $samaccountname -Confirm:$False
}
# END FUNCTION DEFINITIONS #

# STATIC VARIABLES #
$Company = "Controls and Data Services"
$Country = "GB"
$HomeDrive = "H:"
$HomePath = "\\controlsdata.com\fs\homes"
$ExchangeServer = "http://bhm1dag01.controlsdata.com/powershell"
# END STATIC VARIABLES #

# SITE-BASED DATA #
$bhm1city = "Birmingham"
$bhm1Office = "Birmingham Business Park"
$bhm1address = ""
$bhm1PostalCode = "B28"
$bhm1State = "West Midlands"

$dby1city = "Derby"
$dby1Office = "Bassett Block"
$bhm1address = ""
$dby1PostalCode = "DE24 8BJ"
$dby1State = "Derbyshire"

$bfs1city = "Belfast"
$bfs1Office = "Belfast Engineering Centre"
$bhm1address = ""
$bfs1PostalCode = "BT2 7LA"
$bfs1State = "Northern Ireland"
# END SITE-BASED DATA #

# HOMEDRIVE CREATION ONLY #
if($homeonly){
	$samaccountname = $username.tolower()
	try{get-aduser $samaccountname | Out-Null}catch{write-host "Error: Supplied username does not match a valid user - $samaccountname" -foregroundcolor red;exit 1}
	$homepath = "$homepath\$($samaccountname.substring(0,1))"
	createHomedrive $homepath $samaccountname
	write-verbose "Processing Complete"
	exit 0
}
# END HOMEDRIVE CREATION ONLY #

$users = Import-CSV $csv

write-verbose "Create remote Exchange session"
try{
	$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ExchangeServer
	Import-PSSession $session -AllowClobber | Out-Null
}catch{
	write-host "Invalid credentials or Exchange server unavailable"
	exit 1
}

#Regex pattern match for samaccountname; alphanumeric and underscores only, start with alpha.
$pat = "^[a-zA-Z][a-zA-Z0-9_]+$"

foreach($user in $users){

	write-verbose "Validate optional user data"
	if($user.enddate -ne ""){[datetime]$enddate = get-date $user.enddate}else{$enddate = $null}
	if($user.description -ne ""){$description = $user.description}else{$description = $null}
	if($user.department -ne ""){$department = $user.department}else{$department = $null}
	if($user.initial -ne ""){$initial = $user.initial}else{$initial = $null}

    write-verbose "Validate mandatory user data"
	if($user.samaccountname -cmatch $pat){$samaccountname = $user.samaccountname.tolower()}else{write-host "Error: Invalid samaccountname specified for $samccountname";continue}
	if($user.firstname -ne ""){$firstname = $user.firstname}else{write-host "Error: Invalid firstname specified for $samaccountname";continue}
	if($user.surname -ne ""){$surname = $user.surname}else{write-host "Error: Invalid surname specified for $samaccountname";continue}
	if($user.email -ne ""){$email = $user.email}else{if($initial -eq $null){$email = "$firstname.$surname@controlsdata.com"}else{$email = "$firstname.$initial.$surname@controlsdata.com"}}
	if($user.sitename -ne ""){$sitename = $user.sitename}else{write-host "Error: Invalid sitename specified for $samaccountname";continue}
	
	$homepath = "$homepath\$($samaccountname.substring(0,1))"
	
		$displayname = "$surname, $firstname $initial".trim()

		write-host "`nNew user will be created with the following information:" -foregroundcolor yellow
		write-host "Displayname: " -foregroundcolor gray -nonewline 
		write-host "$displayname"
		write-host "Username: " -foregroundcolor gray -nonewline 
		write-host "$samaccountname"
		write-host "Email: " -foregroundcolor gray -nonewline 
		write-host "$email"
		write-host "End Date: " -foregroundcolor gray -nonewline 
		if($enddate -ne $null){write-host "$(get-date $enddate -Format 'dd/MM/yyyy')"}else{write-host "None"}
		write-host "Sitename: " -foregroundcolor gray -nonewline 
		write-host "$sitename"
		write-host "Description: " -foregroundcolor gray -nonewline 
		write-host "$description"
		write-host "Department: " -foregroundcolor gray -nonewline 
		write-host "$department`n"
		
		$message = "Create new user based on this information?";
		$y = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Create User";
		$n = new-Object System.Management.Automation.Host.ChoiceDescription "&No","Skip User";
		$choices = [System.Management.Automation.Host.ChoiceDescription[]]($y,$n);
		$answer = $host.ui.PromptForChoice("",$message,$choices,1)
		
		:main switch ($answer){
			0{
			
			write-verbose "Generate Password"
			$password = generatePassword
			$sspass = ConvertTo-SecureString $password -AsPlainText -Force
			
				switch($sitename){
					BHM1{
						try{
							New-ADUser -Name $displayname -AccountExpirationDate $enddate -AccountPassword $sspass -ChangePasswordAtLogon $true -City $bhm1city -Company $company -Country $country -Department $department -Description $description -Enabled $true -GivenName $firstname -Initials $initial -Office $bhm1office -Path "OU=Users,OU=$sitename,OU=CDS,DC=controlsdata,DC=com" -PostalCode $bhm1PostalCode -SamAccountName $samaccountname -State $bhm1State -StreetAddress $bhm1address -Surname $surname -UserPrincipalName $email -HomeDrive $HomeDrive -HomeDirectory "$Homepath\$samaccountname" -Confirm:$false -ea stop
						}catch{
							write-host "Error: Couldn't create user $samaccountname`n$_" -foregroundcolor yellow;break main
						}
						addGroups $sitename $samaccountname
					}
					DBY1{
						try{
							New-ADUser -Name $displayname -AccountExpirationDate $enddate -AccountPassword $sspass -ChangePasswordAtLogon $true -City $dby1city -Company $company -Country $country -Department $department -Description $description -Enabled $true -GivenName $firstname -Initials $initial -Office $dby1office -Path "OU=Users,OU=$sitename,OU=CDS,DC=controlsdata,DC=com" -PostalCode $dby1PostalCode -SamAccountName $samaccountname -State $dby1State -StreetAddress $dby1address -Surname $surname -UserPrincipalName $email -HomeDrive $HomeDrive -HomeDirectory "$Homepath\$samaccountname" -Confirm:$false -ea stop
						}catch{
							write-host "Error: Couldn't create user $samaccountname`n$_" -foregroundcolor yellow;break main
						}
						addGroups $sitename $samaccountname
					}
					BFS1{
						try{
							New-ADUser -Name $displayname -AccountExpirationDate $enddate -AccountPassword $sspass -ChangePasswordAtLogon $true -City $bfs1city -Company $company -Country $country -Department $department -Description $description -Enabled $true -GivenName $firstname -Initials $initial -Office $bfs1Office -Path "OU=Users,OU=$sitename,OU=CDS,DC=controlsdata,DC=com" -PostalCode $bfs1PostalCode -SamAccountName $samaccountname -State $bfs1State -StreetAddress $bfs1address -Surname $surname -UserPrincipalName $email -HomeDrive $HomeDrive -HomeDirectory "$Homepath\$samaccountname" -Confirm:$false -ea stop
						}catch{
							write-host "Error: Couldn't create user $samaccountname`n$_" -foregroundcolor yellow;break main
						}
						addGroups $sitename $samaccountname
					}
					default{
						write-host "Error: Invalid sitename specified for $samaccountname" -foregroundcolor yellow;break main
					}
				}
			
				[array]$result += "Created $samaccountname with password: $password`n"
				
				
				if(!$nomail){
					write-verbose "Create mailbox"
					try{
						Enable-Mailbox -Identity "CDS\$samaccountname" -Alias $samaccountname -PrimarySMTPAddress $email.tolower() -Confirm:$False -ea stop
					}catch{
						write-host "Error: Couldn't create mailbox for $samaccountname`n$_" -foregroundcolor yellow;continue
					}
				}
				
				if(!$nohome){
					write-verbose "Create user's homedirectory & assign permissions"
					createhomedrive $homepath $samaccountname
				}
			}
			1{
				write-verbose "Skip user"
			}
		}
}

write-verbose "Cleanup Exchange remoting session"
Remove-PSSession $Session

write-output $result

write-verbose "Processing Complete"