Monday 16 July 2018

Confused about deprecated O365 commands?

 

 

I was getting pretty confused with the various options around powershell commands to use with Exchange online.  For example, to add a user to a distribution group in O365, I had come across 4 different commands:

 

 

Add-AzureADGroupMember

Add-AzureRMADGroupMember

Add-DistributionGroupMember

Add-MsolGroupMember

 

 

So after some digging I realised that the *-AzureRM* are powershell cmdlets to modify general Azure resources using the Azure Resource Manager model – read more here (first couple of links are most useful)

 

Furthermore, the current way to manipulate Azure AD is to use the V2 cmdlets:  *-AzureAD* read more here 

 

The older *MSOL* cmdlets have been completely replaced by the *-azureAD* cmdlets.  Although the older cmdlets still work, they have been marked as deprecated so at some point they will stop but that might not be for a while. Read more here.

 

The Add-DistributionGroupMember cmdlet applies to Exchange and Exchange Online.  Given that Microsoft haven’t given any indication that they are likely to remove support for hybrid environments it is likely these will be around for a while.

 

 

 

 

Friday 13 July 2018

Powershell script for creating an O365 cloud mailbox within a hybrid exchange environment

 

 

I recently wrote this script that creates an O365 mailbox within a hybrid exchange environment, creating all the necessary attributes etc in exchange and AD


Log all output to a local logfile, that is unique each time and won't get overwritten

 

 

Start-Transcript -Path $env:LOCALAPPDATA"\Cloudwyse\Logs\"$(get-date -Format ddMMyy_HHmmss)".log" -NoClobber

 

 

Clear output from the screen to prevent previous command being sent as first name

 

 

Clear-Host

 

 

Prompt user to enter the details of the new account

 

 

$FirstName = Read-Host -Prompt "Carefully type the user`'s First name"

$SecondName = Read-Host -Prompt "Carefully type the user`'s Second name"

 

 

Format the AD fields in the right way

 

 

$UserName = $FirstName.ToLower() + "." + $SecondName.ToLower()

$DisplayName = (Get-Culture).TextInfo.ToTitleCase($FirstName.ToLower() + " " + $SecondName.ToLower())

$ProperFName = (Get-Culture).TextInfo.ToTitleCase($FirstName.ToLower())

$ProperSName = (Get-Culture).TextInfo.ToTitleCase($SecondName.ToLower())

$UPN = $UserName + "@contoso.com"

write-host -ForegroundColor Green "Your User`'s DisplayName is $($DisplayName)"

write-host -ForegroundColor Green "Your User`'s Username is $($UserName)"

 

 

Get credentials for the new user account and the connection to the on-prem exchange server

 

 

$UserCreds = Get-Credential -UserName "DO NOT EDIT THIS FIELD" -Message "Please set the password for the new user"

$ExchangeCreds = Get-Credential -UserName "CONTOSO`\" -Message "Please enter your credentials which are required to connect to CONEXCH01"

write-host -ForegroundColor Green "Your User`'s UPN is $($UPN)"

 

 

Connect to on-prem exchange and create mailbox

 

 

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://CONEXCH01.contoso.com/PowerShell/ -Authentication Kerberos -Credential $ExchangeCreds

Import-PSSession $Session

New-RemoteMailbox -Name $DisplayName -FirstName $ProperFName -LastName $ProperSName -Password $UserCreds.Password -UserPrincipalName $UPN -OnPremisesOrganizationalUnit "contoso.com/CONTOSO Users/Swap"

 

 

Disconnect from exchange and stop logging

 

 

Remove-PSSession $Session

write-host -ForegroundColor Green "The script completed, any errors will appear in the log file"

Stop-Transcript

 

 

 

Thursday 12 July 2018

Adding Users to O365 Distribution List

 

A script I recently used to add members to an office 365 distribution group using a remote exchange session in a hybrid setup (covered at the end). 

 

$SourceFile = "<path to file>"

Import-CSV $SourceFile | ForEach `

{Add-DistributionGroupMember -Identity "Group Name" -Member $_.UPN

Write-Host -ForegroundColor Green "Processed the record for $($_.UPN)"

}

 

 

CSV file contains UPNs of all users to be added.

 

I also found it useful to see who had permissions to send to this group using

 

 

(Get-DistributionGroup -Identity "Group Name").AcceptMessagesOnlyFrom | ForEach {Get-User -Identity $_}

 

 

To open remote exchange shell:

 

 

$UserCredential = Get-Credential

 

 

A prompt will appear for your login credentials then,

 

 

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection

Import-PSSession $Session

 

 

 

Tuesday 10 July 2018

Add New Users using Exchange Admin Center (Exchange 2016)

This only applies to new Active Directory users.  To look at how to use SMTP matching to link an on-prem user to an existing O365 mailbox in a hybrid environment follow this guide.
1. Log into the Exchange Admin Center: https://mail.contoso.com/ecp
2. In the EAC console of your on-premises hybrid server, go to Recipients > Mailboxes and click on the plus sign above the “Display Name” column and choose “Office 365 mailbox.”


3. Complete all the fields as required and click save. You can edit the user’s mailbox properties afterwards to add information such as title, manager, address and phone number if you wish.  Exchange will automatically create the AD account for you.

4. Sync using AD Connect. 
You can either wait for the next sync cycle or force it.  The user will appear in Office 365 and an Exchange Online mailbox will be provisioned not long afterwards. Once everything is synced you can add a license.
5. License the User.
1. Go to https://portal.office.com
2. Select the Admin tile
3. Go to Users and choose Active users
4. Select the user in question, go to the Product Licenses field and click Edit
5. Choose a location then click the slider to activate an available license
At the bottom of the Product licenses pane, choose Save

O365 hybrid setup - how to use SMTP matching to match an on-prem user to an O365 account

 

 

The scenario is that a user account has been created in Office 365 in a hybrid setup. This scenario is actually ok and is supported by Microsoft. However, it causes problems for an Office 365 user when they require access to public folders on the on-premises Exchange server.

 

First make sure you have the correct UPN for the online account by running the following (you'll have to have the msonline module by following this guide but please note some of these commands are now deprecated so would need to be manually added to powershell).

 

 

Get-MsolUser -SearchString "foo" | select-object Displayname, UserPrincipalName, ProxyAddresses

 

 

DisplayName

-----------

Foo Bar      

UserPrincipalName

----------------- 

foo@contoso.com

ProxyAddresses

--------------

{smtp:foo@contoso.com, SMTP:foobar@contoso.com, smtp:foo@contoso.net}

 

 

 

Create a user object in your local AD with the same attributes as the one in O365 (first name, last name, UPN, etc.).

 

Set up the primary SMTP address for the AD object so that it is the same as the capitalised SMTP address in the previous step eg SMTP:foobar@contoso.com.

 

You can do this in Active Directory either by adding the address into the email field on the general tab or by adding it to the proxyAddresses attribute directly (you will need to enable advanced features from the view settings in active directory to be able to see the Attributes tab).  The second option is probably better as we need to add the other email aliases anyway.  Add them in this format (the capitalised address will be your primary SMTP address):

 

smtp:foo@contoso.com

SMTP:foobar@contoso.com

smtp:foo@contoso.net

 

Force a manual sync of AD

 

repadmin /syncall /APed

 

 

Force a manual sync of AAD Connect

 

Start-ADSyncSyncCycle -PolicyType Delta

 

 

Result

------

Success

 

 

 

In the exchange admin centre you should see the status change from "Cloud" to "Synced with Active Directory"

 

Don’t forget the online account password will have changed to the one you specified when you created the AD account.

 

 

 

Set O365 Password to never expire for just one user

 

 

Recently I needed to do this for our PRTG alerting account which was failing to send notifications as the O365 password had expired.  I did this from Powershell within Windows 10 as follows:

Launch powershell as Administrator then run

 

Install-Module MsOnline

 

 

Then run

 

Connect-MsOlService

 

 

at this point an O365 authentication box pops up - enter your credentials. Once connected run:

 

Set-MsolUser -UserPrincipalName user@contoso.com -PasswordNeverExpires $true

 

 

Some of these commands have since been deprecated. For an explanation look at this post.

 

 

Thursday 5 July 2018

Add AD security group to local administrators on Hyper-V server running core

 

 

First connect to the remote server with powershell

 

 

Enter-PSSession -ComputerName contosohv01

 

 

Next run the command to add the group:

 

 

Add-LocalGroupMember -Group "Administrators" -Member "CONTOSO\Hyper-V Admins"

 

 

If you're paranoid (like me) and want to check this worked you can use:

 

 

Get-LocalGroupMember "Administrators"

 

 

 

Wednesday 4 July 2018

Configuring log-on scripts to run via powershell from the "Run" key in Windows registry

 

If you’ve tried to add a powershell script to a registry run key, you’ve probably discovered that it doesn’t run with powershell.  Instead, Windows just opens the script in Notepad and leaves it sitting there all naked and exposed!  So in order to launch the powershell scripts we’re going to need to use a .bat or .cmd file launched from the run key in the registry.  So we’re going to add a string (REG_SZ) to

 

 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 

 

 

When you create the key you can call it whatever you like but the value has to be exactly right – and point to the script you want to launch.  In my case this is:

 

 

Cloudwyse Scripts

REG_SZ

cmd /c START /MIN "Cloudwyse Env Execution" cmd /c "C:\Cloudwyse\Scripts\lch_powershell.cmd"

 

 

So I’m telling windows to launch a minimised command prompt, and then I’m passing the command I want running within that command prompt which means that users won’t have a big black box pop up on their screen everytime they log in.  Within that .cmd script, I need to launch Powershell but if I just go ahead and use the “powershell -File” command then I will hit issues with the execution policy within Windows which is disabled by default.  So we need the scripts to bypass the Powershell execution policy, but we don’t necessarily want to change the execution policy for the whole server for good.  So we can use this within the .cmd file:

 

 

@ECHO OFF SET CloudwyseScriptsDIR=C:\Cloudwyse\Scripts\

SET PSScriptPath=%CloudwyseScriptsDIR%wrapper.ps1

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%PSScriptPath%""' -WindowStyle Hidden}";

 

 

So we’re asking Windows to launch powershell, temporarily bypassing the execution policy for the context of this command only.  Then we pass the command which also bypasses the execution policy, but this time within the context of the file we’re about to launch which is “wrapper.ps1”.

So now we have our Powershell wrapper script running automatically everytime a user logs in.  We can now nest within that script all the other powershell scripts we would also like to run by doing the following:

 

 

$ScriptPath = Split-Path $MyInvocation.MyCommand.Path

. "$ScriptPath\date_check.ps1"

. "$ScriptPath\vmcheck.ps1"

. "$ScriptPath\IE_ESC.ps1"

 

 

Simply add a new line to this script for every logon script you want to run for users.

And if you’re wondering why the “$MyInvocation” variable doesn’t seem to be used anywhere, that’s because it’s an automatic variable.  There’s a great article on it here if you’re interested in learning more.