Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #########################################################################
- #
- # Author : VonDrakenstorm
- # File name : New-User.ps1
- # Date : 2017-12-27
- # Version : 1.0
- # 1.1 : + data are now stored in an xml file
- # 1.2 : + Users are created in a temp OU and moved if the creation returned no error
- # + Composed firstname are properly capitalized
- # + Added the Department, site and country (HR was using it w/out our knowledge)
- # + Randomness added to the temporary password
- # + Added a function to add AD groups and manage if they are not found
- #
- # TODO : Better handle when the AD groups are not found rather than just not adding them
- # TODO : Use AD Sites and Services for the sites name
- # TODO : Graphic error hangling
- #* TODO : Add comment to paste in GLPI
- #
- #########################################################################
- <#
- .SYNOPSIS
- Creates a new user from the input specifications in the AD
- .DESCRIPTION
- Based on the first name, last name, site, department and the request of a mailbox, VPN access or external address,
- creates a user.
- First the names are parsed to render them AD worthy (no accents, no spaces, correctly capitalied)
- Then the infos on the site and department are checked
- The existence of the shortname and email address are checked in the whole AD forest before creation.
- 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
- If the user has no mailbox, a account is created with the ActiveDirectory module
- If the user has a mailbox, one is created via a PSSession on the Exchange API. Same action with Skype
- Then the default AD groups are added, mailing list, site.
- If VPN is requested, the default AD groups are added
- If the user is correctly created, it is moved to its destination OU and the log file is removed
- Otherwise, it stays in the Laboratory Domain User/New Users OU and the log file is kept in c:\temp
- .EXAMPLE
- New-User -FirstName "Username" -LastName "userlastname" -Site "Site1" -Department "Marketing" -email -VPN
- #>
- [CmdletBinding()]
- Param(
- [Parameter(Mandatory=$true)][string] $FirstName,
- [Parameter(Mandatory=$true)][string] $LastName,
- [Parameter(Mandatory=$true)][string] $Site,
- [Parameter(Mandatory=$true)][string] $Department,
- [Parameter(Mandatory=$false)][switch] $email,
- [Parameter(Mandatory=$false)][switch] $VPN,
- [Parameter(Mandatory=$false)][switch] $external,
- [Parameter(Mandatory=$false)][switch] $test
- )
- $Now = Get-Date -Format yyyy-MM-dd_HH-mm-ss
- $Password = ConvertTo-SecureString "$(Get-Random)!$Now" -AsPlainText -Force # Password is temporary and is reset by the helpdesk before giving it to the user
- $LogFile = "C:\Temp\$Now-$LastName-$FirstName.log"
- [xml] $XMLData = Get-Content $PSScriptRoot\data.xml
- $DepartmentsList = $XMLData.Data.Departments.department
- $SitesList = $XMLData.Data.Sites.site
- $ExchangeServer = ($XMLData.Data.Servers.Server | Where-Object {$_.role -eq "Exchange"}).hostname
- $ExchangeDatabases = @("Standard-A-B";"Standard-C-D";"Standard-E-J";"Standard-K-M";"Standard-N-R";"Standard-S-Z+";"Advanced";"No-Limit")
- $SkypeServer = ($XMLData.Data.Servers.Server | Where-Object {$_.role -eq "Skype"}).hostname
- $NoErrorDuringCreation = $true
- <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
- <# ----------------------------------------------------------- FUNCTIONS START ------------------------------------------------------------ #>
- <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
- function Remove-Accents{
- param([string]$src)
- $src = ($src -creplace "à|â|ä|à","a")
- $src = ($src -creplace "é|è|ê|ë","e")
- $src = ($src -creplace "ï|î|ì","i")
- $src = ($src -creplace "ö|ô|ò","o")
- $src = ($src -creplace "ü|û|ù","u")
- $src = ($src -creplace "ÿ","y")
- $src = ($src -creplace "ç","c")
- $src = ($src -creplace "ñ","n")
- return $src
- }
- # Add the AD group with error handling and logging id the group if not found
- function Add-ADgroup{
- param(
- [string] $groupName,
- $ADUser
- )
- try {
- $ADGroup = Get-ADGroup -Filter {name -like $groupName}
- if($Null -ne $ADGroup){
- Add-ADGroupMember -Identity $ADGroup -Members $user -ea stop
- Write-Verbose "User added to $groupName"
- }else{
- Add-Content -Path $LogFile -Value "Group $groupName not found"
- Write-Error "AD group $ADGroup not found" -ErrorAction Stop
- }
- }catch{
- Write-Verbose "Failed to add site group $groupName"
- Add-Content -Path $LogFile -Value "Failed to add site group $groupName"
- return $false
- }
- return $NoErrorDuringCreation
- }
- <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
- <# ------------------------------------------------------------- Script START ------------------------------------------------------------- #>
- <# ---------------------------------------------------------------------------------------------------------------------------------------- #>
- #* Input Control
- # FirstName, LastName, Site and Department length >= 2
- if( ($FirstName.Length -ge 2) -and ($LastName.Length -ge 2) -and ($Site.Length -ge 2) -and ($Department.Length -ge 2) ){
- Write-Verbose "All parameters have correct Length"
- }else{ Write-Verbose "Input too short" ; exit -1 }
- # Surname must be scrubbed of accents and spaces
- $FirstName = Remove-Accents $FirstName
- $FirstName = $FirstName -replace " ","-"
- $FirstName = $Firstname[0].ToString().ToUpper()+$Firstname.Substring(1,$Firstname.Length-1).ToLower()
- $FirstName = (Get-Culture).TextInfo.ToTitleCase($FirstName)
- # LASTNAME IS ALL CAPS
- $LastName = $LastName -replace " ","-"
- $LastName = $LastName.toUpper()
- # Are the name including forbidden symbols Ïa! Ïa!
- if( ($FirstName -match "^[A-Za-z- ]+$") -and ($LastName -match "^[A-Za-z- ]+$") ){
- Write-Verbose "Names are made of letters"
- }else{ Write-Verbose "Names contain forbidden characters"; exit -1 }
- # Is the site in the list of sites
- if($SitesList.name -contains $Site){
- Write-Verbose "Site in site list"
- }else{ Write-Verbose "Site not in site list"; exit -1 }
- $SiteTrigram = ($SitesList | Where-Object {$_.name -eq $Site}).trigram
- $SiteCountry = ($SitesList | Where-Object {$_.name -eq $Site}).country
- # Is the department in the list of departments
- if($DepartmentsList.name -contains $Department){
- Write-Verbose "Department in site list"
- }else{ Write-Verbose "Department not in site list"; exit -1 }
- $DepartmentTrigram = ($DepartmentsList | Where-Object {$_.name -eq $Department}).trigram
- #* Calculation
- # Create the email addresse
- if($external){
- # If external, add .ext
- $emailAddress = "$FirstName.$LastName.ext@contoso.com"
- }else{
- $emailAddress = "$FirstName.$LastName@contoso.com"
- }
- # Create the shortname
- if(($LastName -replace '-','').length -ge 7){
- $shortname = ("$(($LastName -replace '-','').Substring(0,7))$($FirstName.Substring(0,1))").ToLower()
- }else{
- $shortname = ("$(($LastName -replace '-','').Substring(0,($LastName -replace '-','').length))$($FirstName.Substring(0,1))").ToLower()
- }
- Write-Verbose "Formating done"
- $EndMessage = @"
- User name : $LastName $FirstName
- SamAccountname : $shortname
- email : $emailAddress
- Skype : $email
- "@
- # Test if the email and shortname already exist on the 4 sub-domains
- $existInEMEA = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "emea.contoso.com" -ErrorAction SilentlyContinue
- $existInNOAM = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "noam.contoso.com" -ErrorAction SilentlyContinue
- $existInSOAM = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "noam.contoso.com" -ErrorAction SilentlyContinue
- $existInASIA = Get-ADUser -f {(SamAccountname -like $shortname) -or (UserPrincipalName -like $emailAddress) } -server "asia.contoso.com" -ErrorAction SilentlyContinue
- if($existInEMEA -or $existInNOAM -or -$existInSOAM -or $existInASIA){
- Write-Error "Shortname or email already in use"
- Add-Content -Path $LogFile -Value "Shortname or email already in use"
- exit -1
- }
- Write-Verbose "User can be created"
- # Selecting the excahnge DB to store the mailbox
- switch -regex ($shortname.Substring(0,1)){
- "[a-b]" {$exchangeDB = $ExchangeDatabases[0]}
- "[c-d]" {$exchangeDB = $ExchangeDatabases[1]}
- "[e-j]" {$exchangeDB = $ExchangeDatabases[2]}
- "[k-m]" {$exchangeDB = $ExchangeDatabases[3]}
- "[n-r]" {$exchangeDB = $ExchangeDatabases[4]}
- "[s-z0-9]" {$exchangeDB = $ExchangeDatabases[5]}
- Default {Write-Verbose "Somehow not a letter or a nb"; return -1}
- }
- # The user is created in a LAB OU to be easier to find if something goes wrong
- # If the user has a mailbox
- if($email){
- Add-Content -path $logfile -value "New-Mailbox -Name '$LastName $FirstName' -Alias '$shortname' -OrganizationalUnit 'emea.contoso.com/Laboratory Domain Users/New Users'
- -UserPrincipalName '$emailAddress' -SamAccountName '$shortname' -FirstName '$FirstName' -Initials '' -LastName '$LastName'
- -Password $Password -ResetPasswordOnNextLogon $true -Database '$exchangeDB'"
- $parameters = @{"Name" = "$LastName $FirstName";
- "Alias" = $shortname;
- "FirstName" = $FirstName;
- "LastName" = $LastName;
- "SamAccountName" = $shortname;
- "UserPrincipalName" = $emailAddress;
- "PrimarySmtpAddress" = $emailAddress;
- "Database" = $exchangeDB
- "OrganizationalUnit" = "OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com";
- "Password" = $Password;
- "ResetPasswordOnNextLogon" = $true;
- }
- try { $SessionExch = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServer/PowerShell/ -Authentication Kerberos -ea Stop}
- catch {
- Write-error "Unable to open Exchange session with $ExchangeServer"
- Remove-PSSession $SessionExch
- exit -1
- }
- try { Invoke-Command -Session $SessionExch -ScriptBlock { param($UserParameters) New-Mailbox @UserParameters } -arg $parameters -ea Stop}
- catch {
- Write-Error "Unable to create user through Exchange on $ExchangeServer"
- exit -1
- }
- Remove-PSSession $SessionExch
- Start-Sleep -Seconds 10
- Write-Verbose "New-Mailbox -Name '$LastName $FirstName' -Alias '$shortname' -OrganizationalUnit 'emea.contoso.com/Laboratory Domain Users/New Users'
- -UserPrincipalName '$emailAddress' -SamAccountName '$shortname' -FirstName '$FirstName' -Initials '' -LastName '$LastName'
- -Password $Password -ResetPasswordOnNextLogon $true -Database '$exchangeDB'"
- # Create the skype account
- try { $SessionSkype = New-PSSession -ConnectionUri https://$SkypeServer/OcsPowershell -ConfigurationName Microsoft.Powershell -Authentication Negotiate -ea Stop }
- catch { Write-Error "Unable to open Skype session"; Add-Content -Path $LogFile -Value "Unable to open Skype session"; $NoErrorDuringCreation = $false }
- $SkypeParameters = @{ "Identity" = $shortname;
- "RegistrarPool" = $SkypeServer;
- "SipAddressType" = "EmailAddress"
- }
- try { Invoke-Command -Session $SessionSkype -ScriptBlock { param($UserSkypeParameters) Enable-CsUser @UserSkypeParameters} -ArgumentList $SkypeParameters }
- catch { Write-Error "Unable to create Skype user"; Add-Content -Path $LogFile -Value "Unable to create Skype user"; $NoErrorDuringCreation = $false }
- Remove-PSSession $SessionSkype
- }else{
- # If the user is just an AD account
- $parameters = @{'Name' = "$LastName $FirstName";
- 'Department' = $Department;
- 'GivenName' = $FirstName;
- "Surname" = $LastName;
- "UserPrincipalName" = $emailAddress;
- "SamAccountName" = $shortname;
- "Path" = "OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com";
- "AccountPassword" = $Password;
- "Enabled" = $True;
- }
- try { New-ADUser @parameters -ea Stop}
- catch {
- Write-Error "Unable to create AD User"
- exit -1
- }Start-Sleep -Seconds 10
- Write-Verbose "New-ADUser -Name '$LastName $FirstName' -Surname '$LastName' -GivenName '$FirstName' -UserPrincipalName '$emailAddress'
- -SamAccountName '$shortname' -Department '$Department' -Path 'OU=New Users,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com' -Enabled $True
- -AccountPassword $Password -ChangePasswordAtLogon $True "
- }
- # Get newly created AD user if well created
- try { $user = Get-ADUser $shortname -ea Stop }
- catch{
- Write-Error "User not found in AD - test 1"
- Start-Sleep -Seconds 10
- try { $user = Get-ADUser $shortname -ea Stop }
- catch{ Write-Error "User not found in AD - test 2"; exit -1 }
- }
- # Set the country and site
- try{Set-ADUser $user -City $Site -Country $SiteCountry -ea stop}
- catch{Add-Content -Path $LogFile -Value "Failed to set the country or department"; $NoErrorDuringCreation = $false}
- # Set the Department
- try {Set-ADUser $user -Department $Department -ea stop}catch{Add-Content -Path $LogFile -Value "Failed to set the department"; $NoErrorDuringCreation = $false}
- #* Add AD groups
- # Add Site groups
- $NoErrorDuringCreation = Add-ADgroup -groupName "$SiteTrigram - $DepartmentTrigram" -ADUser $user
- # Add Site mailing list
- if($email){
- $NoErrorDuringCreation = Add-ADgroup -groupName "# $SiteCountry-$Site List - E-mail" -ADUser $user
- }else{
- $NoErrorDuringCreation = Add-ADgroup -groupName "# $SiteCountry-$SiteTrigram List" -ADUser $user
- }
- # Add VPN Groups
- if($VPN){
- if($email){
- # Add outlook VPN group
- $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA Outlook" -ADUser $user
- }
- # Add VPN mailing list
- $NoErrorDuringCreation = Add-ADgroup -groupName "# List - VPN Users" -ADUser $user
- # Add Sharepoint, common
- $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA Common" -ADUser $user
- $NoErrorDuringCreation = Add-ADgroup -groupName "VPN - EMEA SharePoint Web Portal" -ADUser $user
- }
- Write-Host $EndMessage
- # If every went right, move the user to its OU
- if($NoErrorDuringCreation){
- try {
- # $test allows us to not add test users with the real ones
- if($test){Move-ADObject $user.DistinguishedName -Targetpath "OU=Fake Site,OU=Laboratory Domain Users,DC=emea,DC=contoso,DC=com"}
- else{Move-ADObject $user.DistinguishedName -Targetpath "OU=$Site,OU=Domain Users,DC=emea,DC=contoso,DC=com"}
- }catch { Write-Error "Failed to move user"; exit -1}
- # TODO : Once in prod and stable enough, remove the log file for creation that went well
- #Remove-Item -Path $LogFile
- Write-Verbose "Creation finished"
- }else{
- Write-Verbose "Creation finished with errors. User is still in the Laboratory Domain User/New Users OU"
- }
- exit 0
Add Comment
Please, Sign In to add comment