# createNewHybridUser_v0.0.1.ps1
# .Description: this script automates the creation of a user account in a hybrid environment of on-premise AD and Office 365
# if there are more than a few users being created (aka batch), then there is another script that can efficiently complete such tasks.

# User variables
$firstName="Bruce";
$lastName="Lee";
$domain="kimconnect.com";
$ou="OU=Users,DC=kimconnect,DC=com"
$manager="Mike Tyson"
$company="Kim Connect, LLC"
$department="Kung Fu Fighting"
$baseGroups = 'Domain Users','VpnUsers'
$specialGroups='ServerAdmins','DesktopAdmins'
$o365License="kimconnect:STANDARDWOFFPACK" # Get this label from O365 Admin console or via PowerShell

# Office 365 Global Admin Credential
$username="O365globalAdmin"
$password = Read-Host -Prompt "Please type in the password for user $userName" -AsSecureString;
#$plainTextPassword=[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,$password

function createNewHybridUser{
Function includeActiveDirectoryModule{
if (!(get-module -Name "ActiveDirectory") -or !(get-command dsquery) ){
$osType=switch ((Get-CimInstance -ClassName Win32_OperatingSystem).ProductType){
1 {'client'}
2 {'domaincontroller'}
3 {'memberserver'}
}
try{
Install-WindowsFeature ActiveDirectory -ErrorAction Stop | out-null;
Import-Module ActiveDirectory -ErrorAction Stop | out-null;
Add-WindowsFeature RSAT-AD-PowerShell | out-null;
return $true;
}catch{
$rsatFailoverClusterInstalled=(Get-WindowsCapability -name Rsat.ActiveDirectory* -online).State;
$wuRegistryHive="REGISTRY::HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$wuKey="UseWUServer"
$currentWu = Get-ItemProperty -Path $wuRegistryHive -Name $wuKey -ErrorAction SilentlyContinue | select -ExpandProperty UseWUServer
if($currentWu){
Set-ItemProperty -Path $wuRegistryHive -Name $wuKey -Value 0;
Restart-Service wuauserv;
}
if($osType -eq 'memberserver'){
Install-WindowsFeature -Name "RSAT"
}elseif ('client'){
Get-WindowsCapability -Name Rsat.ActiveDirectory* –Online|Add-WindowsCapability –Online
}
if($currentWu){
Set-ItemProperty -Path $wuRegistryHive -Name $wuKey -Value $currentWu;
Restart-Service wuauserv;
}
try {Import-Module ActiveDirectory}catch{
return $false;
};
}
}else{
write-host "ActiveDirectory Module is available on this computer.";
return $true;
}

}
includeActiveDirectoryModule;

# Autogen variables
$i=0;
$username=.{ # Initially try to use First letter of firstname + lastname
$testId="$($firstName[0])$lastName";
if (dsquery user -samid $testId){
$testId+=$i++; # Increment userId by 1 if current id already exists, then repeats
}else{
$testId;
break;
}
}
$email="$username@$domain";
$groups=$baseGroups+$specialGroups
$defaultPassword=Read-Host -AsSecureString "Set default password";

write-host "Creating user $userName in Active Directory...";
New-ADUser -Name "$firstName $lastName" -GivenName $firstName -Surname $lastName -SamAccountName $username `
-UserPrincipalName $email -DisplayName "$lastName $firstName" -Path $ou -AccountPassword $defaultPassword `
-Department $department -Company $company -Manager $manager -Enabled $true

write-host "Setting primary email address for user $username..."
$primaryEmail = "SMTP:" + $email
Set-ADUser -Identity $username -EmailAddress $primaryEmail
Set-ADUser $username -Add @{proxyAddresses = ($primaryEmail)}
get-aduser $username -properties proxyaddresses

write-host "Adding user $username to groups..."
$groups|%{Add-ADGroupMember -Identity $group -Members $userName}

write-host "Syncing user $userName to Office 365...";
# Query Active Directory to obtain the Azure AD Connect servername
function triggerAdSync{
$adConnectServers=(Get-ADUser -filter 'name -like "Msol*"' -Properties Description).Description|%{[void]($_ -match "computer\s(.*)\sconfigured");$matches[1]}
foreach ($serverName in $adConnectServers){
"Invoking command on $serverName`r`nStart-ADSyncSyncCycle -PolicyType Delta...";

$result=Invoke-Command -computername $serverName -scriptblock {
$value=Start-ADSyncSyncCycle -PolicyType Delta;
return $value.Result;
} -credential $cred

if ($result.Value -like 'Success'){
write-host "AD Sync has been successfully triggered on $serverName.";
break;
}
}
}
triggerAdSync;

write-host "Connecting to Office 365...";
# Install-Module AzureAD -Confirm:$false -Force # Azure AD may not be necessary for managing O365
if (!(Get-Module -ListAvailable -Name MSOnline)){Install-Module MSOnline -Confirm:$false -Force;}
$O365Session=New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection -ea SilentlyContinue
if ($session){
Write-Output 'Logon Successful';
Import-PSSession $O365Session -AllowClobber
Connect-MsolService -Credential $cred
}else{
$success=$false;
while ($success -eq $false) {
try {
$O365Cred = Get-Credential -message "Please enter your Office365 Admin credentials"
$O365Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $O365Cred -Authentication Basic -AllowRedirection -ea Stop
Write-Output 'Logon Successful';
$success = $True;
Import-PSSession $O365Session -AllowClobber
Connect-MsolService –Credential $O365Cred
}catch {
Write-Output 'Your username or password was incorrect, please try again'
}

}
}

write-host "Checking Office 365 to verify that user Principal user $primaryEmail has been uploaded...";
$userPrincipleName=$email
$dots=0;
$maxDots=90; # each dot represents 10 seconds
do{
$userObject = Get-MsolUser -UserPrincipalName $userPrincipleName -ErrorAction SilentlyContinue
If ($userObject -ne $Null) {
write-host "User now exists on Office 365 / Azure AD!";
break;
} Else {
$nulloutput=ping -n 10 127.0.0.1 2>&1;
if ($dots++%20){
write-host '.' -NoNewline;
}else{
write-host '.';
}
}
}while ($dots -lt $maxDots)

write-host "Adding Office 365 licences to User Principle Name $email...";
Set-MSOLUser -UserPrincipalName $userPrincipleName –UsageLocation "US";
Set-MSOLUserLicense -UserPrincipalName $userPrincipleName –AddLicenses $o365License;
Set-CASMailbox -Identity $userPrincipleName -POPEnabled $true -IMAPEnabled $true; # Enabling POP/IMAP
}

createNewHybridUser;