Guest User

Vondrakenstorm_UserCreationScript

a guest
Aug 24th, 2018
1,296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #########################################################################
  2. #
  3. # Author : VonDrakenstorm
  4. #   File name : New-User.ps1
  5. #   Date : 2017-12-27
  6. #   Version : 1.0
  7. #           1.1 : + data are now stored in an xml file
  8. #           1.2 : + Users are created in a temp OU and moved if the creation returned no error
  9. #                 + Composed firstname are properly capitalized
  10. #                 + Added the Department, site and country (HR was using it w/out our knowledge)
  11. #                 + Randomness added to the temporary password
  12. #                 + Added a function to add AD groups and manage if they are not found
  13. #
  14. # TODO : Better handle when the AD groups are not found rather than just not adding them
  15. # TODO : Use AD Sites and Services for the sites name
  16. # TODO : Graphic error hangling
  17. #* TODO : Add comment to paste in GLPI
  18. #
  19. #########################################################################
  20.  
  21. <#
  22. .SYNOPSIS
  23. Creates a new user from the input specifications in the AD
  24.  
  25. .DESCRIPTION
  26. Based on the first name, last name, site, department and the request of a mailbox, VPN access or external address,
  27. creates a user.
  28. First the names are parsed to render them AD worthy (no accents, no spaces, correctly capitalied)
  29. Then the infos on the site and department are checked
  30. The existence of the shortname and email address are checked in the whole AD forest before creation.
  31. The user is created in the Laboratory Domain User/New Users OU so it can be found easily in case of problem during the creation
  32.  
  33. If the user has no mailbox, a account is created with the ActiveDirectory module
  34. If the user has a mailbox, one is created via a PSSession on the Exchange API. Same action with Skype
  35.  
  36. Then the default AD groups are added, mailing list, site.
  37. If VPN is requested, the default AD groups are added
  38.  
  39. If the user is correctly created, it is moved to its destination OU and the log file is removed
  40. Otherwise, it stays in the Laboratory Domain User/New Users OU and the log file is kept in c:\temp
  41.  
  42.  
  43. .EXAMPLE
  44. New-User -FirstName "Username" -LastName "userlastname" -Site "Site1" -Department "Marketing" -email -VPN
  45.  
  46. #>
  47.  
  48.  
  49. [CmdletBinding()]
  50. Param(
  51.   [Parameter(Mandatory=$true)][string] $FirstName,
  52.   [Parameter(Mandatory=$true)][string] $LastName,
  53.   [Parameter(Mandatory=$true)][string] $Site,
  54.   [Parameter(Mandatory=$true)][string] $Department,
  55.   [Parameter(Mandatory=$false)][switch] $email,
  56.   [Parameter(Mandatory=$false)][switch] $VPN,
  57.   [Parameter(Mandatory=$false)][switch] $external,
  58.   [Parameter(Mandatory=$false)][switch] $test
  59.  
  60. )
  61.  
  62. $Now = Get-Date -Format yyyy-MM-dd_HH-mm-ss
  63. $Password = ConvertTo-SecureString "$(Get-Random)!$Now" -AsPlainText -Force # Password is temporary and is reset by the helpdesk before giving it to the user
  64. $LogFile = "C:\Temp\$Now-$LastName-$FirstName.log"
  65.  
  66. [xml] $XMLData = Get-Content $PSScriptRoot\data.xml
  67.  
  68. $DepartmentsList = $XMLData.Data.Departments.department
  69.  
  70. $SitesList = $XMLData.Data.Sites.site
  71.  
  72. $ExchangeServer = ($XMLData.Data.Servers.Server | Where-Object {$_.role -eq "Exchange"}).hostname
  73. $ExchangeDatabases = @("Standard-A-B";"Standard-C-D";"Standard-E-J";"Standard-K-M";"Standard-N-R";"Standard-S-Z+";"Advanced";"No-Limit")
  74.  
  75. $SkypeServer = ($XMLData.Data.Servers.Server | Where-Object {$_.role -eq "Skype"}).hostname
  76.  
  77. $NoErrorDuringCreation = $true
  78.  
  79.  
  80. <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
  81. <# ----------------------------------------------------------- FUNCTIONS START ------------------------------------------------------------ #>
  82. <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
  83.  
  84. function Remove-Accents{
  85.   param([string]$src)
  86.   $src = ($src -creplace "à|â|ä|à","a")
  87.   $src = ($src -creplace "é|è|ê|ë","e")
  88.   $src = ($src -creplace "ï|î|ì","i")
  89.   $src = ($src -creplace "ö|ô|ò","o")
  90.   $src = ($src -creplace "ü|û|ù","u")
  91.   $src = ($src -creplace "ÿ","y")
  92.  
  93.   $src = ($src -creplace "ç","c")
  94.   $src = ($src -creplace "ñ","n")
  95.  
  96.   return $src
  97. }
  98.  
  99. # Add the AD group with error handling and logging id the group if not found
  100. function Add-ADgroup{
  101.   param(
  102.     [string] $groupName,
  103.     $ADUser
  104.   )
  105.  
  106.   try {
  107.     $ADGroup = Get-ADGroup -Filter {name -like $groupName}
  108.     if($Null -ne $ADGroup){
  109.       Add-ADGroupMember -Identity $ADGroup -Members $user -ea stop
  110.       Write-Verbose "User added to $groupName"
  111.     }else{
  112.       Add-Content -Path $LogFile -Value "Group $groupName not found"
  113.       Write-Error "AD group $ADGroup not found" -ErrorAction Stop
  114.     }
  115.   }catch{    
  116.     Write-Verbose "Failed to add site group $groupName"
  117.     Add-Content -Path $LogFile -Value "Failed to add site group $groupName"
  118.     return $false
  119.   }
  120.   return $NoErrorDuringCreation
  121. }
  122.  
  123.  
  124. <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
  125. <# ------------------------------------------------------------- Script START ------------------------------------------------------------- #>
  126. <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
  127.  
  128. #* Input Control
  129.  
  130. # FirstName, LastName, Site and Department length >= 2
  131. if( ($FirstName.Length -ge 2) -and ($LastName.Length -ge 2) -and ($Site.Length -ge 2) -and ($Department.Length -ge 2) ){
  132.   Write-Verbose "All parameters have correct Length"
  133. }else{ Write-Verbose "Input too short" ; exit -1 }
  134.  
  135.  
  136. # Surname must be scrubbed of accents and spaces
  137. $FirstName = Remove-Accents $FirstName
  138. $FirstName = $FirstName -replace " ","-"
  139. $FirstName = $Firstname[0].ToString().ToUpper()+$Firstname.Substring(1,$Firstname.Length-1).ToLower()
  140. $FirstName = (Get-Culture).TextInfo.ToTitleCase($FirstName)
  141.  
  142. # LASTNAME IS ALL CAPS
  143. $LastName = $LastName -replace " ","-"
  144. $LastName = $LastName.toUpper()
  145.  
  146. # Are the name including forbidden symbols Ïa! Ïa!
  147. if( ($FirstName -match "^[A-Za-z- ]+$") -and ($LastName -match "^[A-Za-z- ]+$") ){
  148.   Write-Verbose "Names are made of letters"
  149. }else{ Write-Verbose "Names contain forbidden characters"; exit -1 }
  150.  
  151. # Is the site in the list of sites
  152. if($SitesList.name -contains $Site){
  153.   Write-Verbose "Site in site list"
  154. }else{ Write-Verbose "Site not in site list"; exit -1 }
  155. $SiteTrigram = ($SitesList | Where-Object {$_.name -eq $Site}).trigram
  156. $SiteCountry = ($SitesList | Where-Object {$_.name -eq $Site}).country
  157.  
  158. # Is the department in the list of departments
  159. if($DepartmentsList.name -contains $Department){
  160.   Write-Verbose "Department in site list"
  161. }else{ Write-Verbose "Department not in site list"; exit -1 }
  162. $DepartmentTrigram = ($DepartmentsList | Where-Object {$_.name -eq $Department}).trigram
  163.  
  164.  
  165. #* Calculation
  166. # Create the email addresse
  167. if($external){
  168.   # If external, add .ext
  169.   $emailAddress = "$FirstName.$LastName.ext@contoso.com"
  170. }else{
  171.     $emailAddress = "$FirstName.$LastName@contoso.com"
  172. }
  173.  
  174. # Create the shortname
  175. if(($LastName -replace '-','').length -ge 7){
  176.   $shortname = ("$(($LastName -replace '-','').Substring(0,7))$($FirstName.Substring(0,1))").ToLower()
  177. }else{
  178.   $shortname = ("$(($LastName -replace '-','').Substring(0,($LastName -replace '-','').length))$($FirstName.Substring(0,1))").ToLower()
  179. }
  180. Write-Verbose "Formating done"
  181.  
  182. $EndMessage = @"
  183. User name : $LastName $FirstName
  184. SamAccountname : $shortname
  185. email : $emailAddress
  186. Skype : $email
  187. "@
  188.  
  189. # Test if the email and shortname already exist on the 4 sub-domains
  190. $existInEMEA = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "emea.contoso.com" -ErrorAction SilentlyContinue
  191. $existInNOAM = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "noam.contoso.com" -ErrorAction SilentlyContinue
  192. $existInSOAM = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "noam.contoso.com" -ErrorAction SilentlyContinue
  193. $existInASIA = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "asia.contoso.com" -ErrorAction SilentlyContinue
  194.  
  195.  
  196. if($existInEMEA -or $existInNOAM -or -$existInSOAM -or $existInASIA){
  197.   Write-Error "Shortname or email already in use"
  198.   Add-Content -Path $LogFile -Value "Shortname or email already in use"
  199.   exit -1
  200. }
  201. Write-Verbose "User can be created"
  202.  
  203. # Selecting the excahnge DB to store the mailbox
  204. switch -regex ($shortname.Substring(0,1)){
  205.   "[a-b]" {$exchangeDB = $ExchangeDatabases[0]}
  206.   "[c-d]" {$exchangeDB = $ExchangeDatabases[1]}
  207.   "[e-j]" {$exchangeDB = $ExchangeDatabases[2]}
  208.   "[k-m]" {$exchangeDB = $ExchangeDatabases[3]}
  209.   "[n-r]" {$exchangeDB = $ExchangeDatabases[4]}
  210.   "[s-z0-9]" {$exchangeDB = $ExchangeDatabases[5]}
  211.   Default {Write-Verbose "Somehow not a letter or a nb"; return -1}
  212. }
  213.  
  214. # The user is created in a LAB OU to be easier to find if something goes wrong
  215. # If the user has a mailbox
  216. if($email){
  217.     Add-Content -path $logfile -value "New-Mailbox -Name '$LastName $FirstName' -Alias '$shortname' -OrganizationalUnit 'emea.contoso.com/Laboratory Domain Users/New Users'
  218.    -UserPrincipalName '$emailAddress' -SamAccountName '$shortname' -FirstName '$FirstName' -Initials '' -LastName '$LastName'
  219.    -Password $Password -ResetPasswordOnNextLogon $true -Database '$exchangeDB'"
  220.  
  221.   $parameters = @{"Name" = "$LastName $FirstName";
  222.                   "Alias" = $shortname;
  223.                   "FirstName" = $FirstName;
  224.                   "LastName" = $LastName;
  225.                   "SamAccountName" = $shortname;
  226.                   "UserPrincipalName" = $emailAddress;
  227.                   "PrimarySmtpAddress" = $emailAddress;
  228.                   "Database" = $exchangeDB
  229.                   "OrganizationalUnit" = "OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com";
  230.                   "Password" = $Password;
  231.                   "ResetPasswordOnNextLogon" = $true;
  232.   }
  233.   try { $SessionExch = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServer/PowerShell/ -Authentication Kerberos -ea Stop}
  234.   catch {
  235.     Write-error "Unable to open Exchange session with $ExchangeServer"
  236.       Remove-PSSession $SessionExch
  237.     exit -1
  238.   }
  239.   try { Invoke-Command -Session $SessionExch -ScriptBlock { param($UserParameters) New-Mailbox @UserParameters } -arg $parameters -ea Stop}
  240.   catch {
  241.     Write-Error "Unable to create user through Exchange on $ExchangeServer"
  242.     exit -1
  243.   }
  244.   Remove-PSSession $SessionExch
  245.   Start-Sleep -Seconds 10
  246.  
  247.   Write-Verbose "New-Mailbox -Name '$LastName $FirstName' -Alias '$shortname' -OrganizationalUnit 'emea.contoso.com/Laboratory Domain Users/New Users'
  248.    -UserPrincipalName '$emailAddress' -SamAccountName '$shortname' -FirstName '$FirstName' -Initials '' -LastName '$LastName'
  249.    -Password $Password -ResetPasswordOnNextLogon $true -Database '$exchangeDB'"
  250.  
  251.  
  252.   # Create the skype account
  253.   try { $SessionSkype = New-PSSession -ConnectionUri https://$SkypeServer/OcsPowershell -ConfigurationName Microsoft.Powershell -Authentication Negotiate -ea Stop }
  254.   catch { Write-Error "Unable to open Skype session"; Add-Content -Path $LogFile -Value "Unable to open Skype session"; $NoErrorDuringCreation = $false }
  255.   $SkypeParameters = @{ "Identity" = $shortname;
  256.                         "RegistrarPool" = $SkypeServer;
  257.                         "SipAddressType" = "EmailAddress"
  258.   }
  259.   try { Invoke-Command -Session $SessionSkype -ScriptBlock { param($UserSkypeParameters) Enable-CsUser @UserSkypeParameters} -ArgumentList $SkypeParameters }
  260.   catch { Write-Error "Unable to create Skype user"; Add-Content -Path $LogFile -Value "Unable to create Skype user"; $NoErrorDuringCreation = $false }
  261.   Remove-PSSession $SessionSkype
  262.  
  263. }else{
  264.   # If the user is just an AD account
  265.   $parameters = @{'Name' = "$LastName $FirstName";
  266.                   'Department' = $Department;
  267.                   'GivenName' = $FirstName;
  268.                   "Surname" = $LastName;
  269.                   "UserPrincipalName" = $emailAddress;
  270.                   "SamAccountName" = $shortname;
  271.                   "Path" = "OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com";
  272.                   "AccountPassword" = $Password;
  273.                   "Enabled" = $True;
  274.     }
  275.   try { New-ADUser @parameters -ea Stop}
  276.   catch {
  277.     Write-Error "Unable to create AD User"
  278.     exit -1
  279.   }Start-Sleep -Seconds 10
  280.  
  281.   Write-Verbose "New-ADUser -Name '$LastName $FirstName' -Surname '$LastName' -GivenName '$FirstName' -UserPrincipalName '$emailAddress'
  282.    -SamAccountName '$shortname' -Department '$Department' -Path 'OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com' -Enabled $True
  283.    -AccountPassword $Password -ChangePasswordAtLogon $True "
  284. }
  285.  
  286. # Get newly created AD user if well created
  287. try { $user = Get-ADUser $shortname -ea Stop }
  288. catch{
  289.   Write-Error "User not found in AD - test 1"
  290.   Start-Sleep -Seconds 10
  291.   try { $user = Get-ADUser $shortname -ea Stop }
  292.   catch{ Write-Error "User not found in AD - test 2"; exit -1 }
  293. }
  294.  
  295. # Set the country and site
  296. try{Set-ADUser $user -City $Site -Country $SiteCountry -ea stop}
  297. catch{Add-Content -Path $LogFile -Value "Failed to set the country or department"; $NoErrorDuringCreation = $false}
  298. # Set the Department
  299. try {Set-ADUser $user -Department $Department  -ea stop}catch{Add-Content -Path $LogFile -Value "Failed to set the department"; $NoErrorDuringCreation = $false}
  300.  
  301. #* Add AD groups
  302. # Add Site groups
  303. $NoErrorDuringCreation = Add-ADgroup -groupName "$SiteTrigram - $DepartmentTrigram" -ADUser $user
  304.  
  305. # Add Site mailing list
  306. if($email){
  307.   $NoErrorDuringCreation = Add-ADgroup -groupName "# $SiteCountry-$Site List - E-mail" -ADUser $user
  308. }else{
  309.   $NoErrorDuringCreation = Add-ADgroup -groupName "# $SiteCountry-$SiteTrigram List" -ADUser $user
  310. }
  311.  
  312. # Add VPN Groups
  313. if($VPN){
  314.   if($email){
  315.     # Add outlook VPN group
  316.     $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA Outlook" -ADUser $user
  317.   }
  318.   # Add VPN mailing list
  319.   $NoErrorDuringCreation = Add-ADgroup -groupName "#  List - VPN Users" -ADUser $user
  320.  
  321.   # Add Sharepoint, common  
  322.   $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA Common" -ADUser $user
  323.   $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA SharePoint Web Portal" -ADUser $user
  324. }
  325.  
  326.  
  327.  
  328. Write-Host $EndMessage
  329.  
  330. # If every went right, move the user to its OU
  331. if($NoErrorDuringCreation){
  332.   try {
  333.     # $test allows us to not add test users with the real ones
  334.     if($test){Move-ADObject $user.DistinguishedName -Targetpath "OU=Fake Site,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com"}
  335.     else{Move-ADObject $user.DistinguishedName -Targetpath "OU=$Site,OU=Domain Users,DC=emea,DC=contoso,DC=com"}
  336.   }catch { Write-Error "Failed to move user"; exit -1}
  337.   # TODO : Once in prod and stable enough, remove the log file for creation that went well
  338.   #Remove-Item -Path $LogFile
  339.  
  340.   Write-Verbose "Creation finished"
  341. }else{
  342.   Write-Verbose "Creation finished with errors. User is still in the Laboratory Domain User/New Users OU"
  343. }
  344. exit 0
Add Comment
Please, Sign In to add comment