Tuesday, 27 October 2015

How to add and license users in bulk on Office 365

PowerShell becomes a tool of choice for a growing number of Office 365 administrators. The main reason is that they can leverage all benefits of the scripting environment in repetitive, everyday tasks.
Even mass creation of users and licenses assignment is not a problem – below you’ll find a step by step guide describing the process.

Connect to Office 365 with PowerShell

Follow this short tutorial to learn how to remotely connect to your Office 365 with PowerShell.


Create a CSV file

Next step is to create a list of all users you want to create in CSV format. It will contain all necessary details, such as email addresses, first and last names, passwords etc. Below you can find an example CSV file syntax.
UserPrincipalName,DisplayName,FirstName,LastName,password
clark.kent@remoteps.onmicrosoft.com,Clark Kent,Clark,Kent,Asik12
bruce.wayne@remoteps.onmicrosoft.com,Bruce Wayne,Bruce,Wayne,Poiy32
peter.parker@remoteps.onmicrosoft.com,Peter Parker,Peter,Parker,Rujk99
Make sure to replace the “remoteps.onmicrosoft.com” domain with your own.

Environment variables

In this example two variables are set:
$path = c:\new_users.csv 
$server = remoteps:enterprisepack
$path contains the path to your CSV file. Replace “c:\new_users.csv” with your own path.
$server contains your license package name. Use the following command to check what license you have (it is listed in the AccountSkuId column):
Get-MsolAccountSku | out-gridview

Create users

The command below loops trough each line of your CSV file and creates an account based on details provided.
import-csv $path | foreach {

New-Msoluser -userPrincipalName $_.UserPrincipalName -displayname 
$_.displayname -firstname $_.firstname -lastname $_.lastname -password 
$_.Password -usagelocation "us"

}
The -usagelocation parameter is required for license assignment. You can change it to the standard country code of your choice.

Licenses assignment

Without the assigned license the Office 365 account cannot send/receive emails. The command below works similarly to the previous one – it works through each line of your CSV file and enables the license for each newly created user.
import-csv $path | foreach { 
set-msoluserlicense -addlicenses "$server" 
}
To make sure that licenses were assigned correctly run the code below.
import-csv $path | Get-MSOLUser | out-gridview
The process is complete. All users from the CSV file list are now present in your Office 365 environment, with licenses assigned and ready to send and receive messages.
All described steps are also attached below as a single script. You can save it as a PS1 file. Additionally it includes a small code that pops up a file picking window which helps to set the $path variable.
#CSV file picker module start
Function Get-FileName($initialDirectory)
{  
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
 Out-Null

 $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
 $OpenFileDialog.initialDirectory = $initialDirectory
 $OpenFileDialog.filter = "All files (*.*)| *.*"
 $OpenFileDialog.ShowDialog() | Out-Null
 $OpenFileDialog.filename
} 

#CSV file picker module end

#Variable that holds CSV file location from file picker
$path = Get-FileName -initialDirectory "c:\" 

#Window with list of available 365 licenses and their names
Get-MsolAccountSku | out-gridview 

#Input window where you provide the license package's name 
$server = read-host 'Provide licensename (AccountSkuId)' 

#CSV import command and mailbox creation loop
import-csv $path | foreach {
New-Msoluser -userPrincipalName $_.UserPrincipalName -displayname $_.displayname -firstname $_.firstname -lastname $_.lastname -password $_.Password -usagelocation "us" | set-msoluserlicense -addlicenses "$server"
}

#Result report on licenses assigned to imported users
import-csv $path | Get-MSOLUser | out-gridview

How to connect and remotely manage Office 365 with PowerShell

Office 365 web interface was designed to make it easier to use right down to its administrative bowels. On the one hand it really is quick and simple to navigate, on the other it definitely lacks some advanced configuration options so loved by sysadmins.
Luckily there is the mighty PowerShell coming to the rescue! You should already know its potential, which can also be utilized in Office 365. Below you’ll find out how.

System Requirements

To remotely manage Office 365 with PowerShell your machine must meet the following requirements:
Once you have all the components installed you are ready to connect to Office 365.

Connecting to Office 365 with PowerShell

First you need to import all the relevant cmdlets. To do so in PowerShell command window run
Import-Module MSOnline
Next run the code below and enter your logon credentials (your Office 365 administrative user email and password).
$365Logon = get-credential
Now configure your remote PowerShell session variables.
$365PSSession = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $365Logon -Authentication Basic -AllowRedirection
Run the code below to connect.
Import-PSSession $365PSSession -AllowClobber
If you encounter any runtime errors at this point, it is most probably because of the disabled script execution policy. You can enable it running the command below:
Set-ExecutionPolicy RemoteSigned
The final step is to connect to your Office 365 online service
Connect-MsolService –Credential $365Logon
That’s it! You are now ready to run PowerShell commands.
Below you can find the whole process in one script, which you can save to the PS1 file.
Import-Module MSOnline
$365Logon = get-credential
$365PSSession = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $365Logon -Authentication Basic -AllowRedirection
Import-PSSession $365PSSession -AllowClobber
Set-ExecutionPolicy RemoteSigned
Connect-MsolService –Credential $365Logon
Whenever you need to remotely administer your Office 365 with PowerShell simply run the PS1 script with the code above. Alternatively, you can add it to your PowerShell profile so you are ready to rock automatically right after launching PS or PowerShell ISE.

Exchange 2013/2010 mailbox backup by export to PST (PowerShell)

An email organization lives and dies by mailbox backups. Unfortunately, all Microsoft Exchange versions, including Exchange 2013, come with limited brick-level backup capabilities. Basically, the only available granular option is an export to PST files. This can be done via Outlook (obviously), PowerShell and in some cases also via Exchange Management Console / Control Panel. In this article I discuss the options available via PowerShell in: Exchange 2013 and Exchange 2010.

Export to PST


Single mailbox export to PST file

Exporting mailbox contents to a PST file is achieved using the MailboxExportRequest cmdlet. It has only 2 obligatory parameters: FilePath – defines the network share path of the PST file to which you want to export the data; and Mailbox – defines the Alias, SMTP address or Display name of the mailbox you will export.Requirements:
  • The user performing the export must be a member of a role group which has the Mailbox Import Export role added. The easiest way of achieving this is running this script:
    New-ManagementRoleAssignment -Role "Mailbox Import Export" -User "<user name or alias>"
    To learn more see the “Add a role to a role group” section of this TechNet article.
  • The location to which you will export the PST file must be a shared folder.

Syntax

Here is an example of a mailbox export request, which backs up an entire mailbox to a PST file:
New-MailboxExportRequest -Mailbox <user> -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst
Limiting the scope of exported contents is possible using additional parameters, e.g.:

-ContentFilter

Specifies what conditions the contents of a mailbox have to match to be exported into the PST file. The conditions are provided in the form of standard PowerShell logical clauses with several item properties available for filtering (wildcards are supported). Example of a script that exports items received prior to 2013-01-01 with subjects beginning with fwd:
New-MailboxExportRequest -Mailbox <user> -ContentFilter {(Received -lt '01/01/2013') -and (Subject -like 'fwd*')} -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst

-ExcludeFolders and -IncludeFolders

Just what it sounds like. You can choose from all Exchange mailbox folders. There are also two interesting features available:
  • The capability to filter personal folders located under root folders using the <FolderName>/* syntax.
  • The capability to filter well known Exchange mailbox folders regardless of their name in a local language using the #<FolderName>#/* syntax.
Here is an example of a script that exports only the Inbox and Sent Items folders:
New-MailboxExportRequest -IncludeFolders "#Inbox#/*","#SentItems#" -Mailbox <user> -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst

-IsArchive

A switch parameter, which defines the archive as the only source of the export. Example:
New-MailboxExportRequest -Mailbox <user> -IsArchive -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst

-Name

Sets the name of an export request. Useful for tracking or if you want to set more than 10 export requests per a single mailbox. This is because by default Exchange assigns only 10 consecutive names to export requests related to a single mailbox (starting with MailboxExport through MailboxExport9) and then stops. To proceed when all 10 default export request names have been taken, you have to either flush your export requests or start assigning your own names using the Name parameter. Example:
New-MailboxExportRequest -Name <unique name> -Mailbox <user> -IsArchive -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst

Additional information

A single MailboxExportRequest script can, of course, contain multiple parameters, including ones I didn’t mention. For a full list of available parameters, as well as syntax information and other details, consult the link below. TechNet: single mailbox exports to PST details

Bulk mailbox export to PST file


The requirements here are identical as in the case of single mailbox exports:
  • The user performing the export must be a member of a role group which has the Mailbox Import Export role added (see previous section for more).
  • The location to which you will export the PST file must be a shared folder.

Method 1

Save all mailboxes to a variable (in my case it’s AllMailboxes):
$AllMailboxes = Get-Mailbox
Export all mailboxes to PST files with names based on mailbox aliases (to use a different mailbox propertyreplace the phrase “Alias” with its name):
$AllMailboxes|%{$_|New-MailboxExportRequest -FilePath \\<server FQDN>\<shared folder name>\$($_.Alias).pst}
Additional parameters can be used just as in single mailbox exports (see the first section of this article).

Method 2

Run the below script for the same effect as in Method 1 (the only difference is the use of the foreach command instead of piping):
foreach ($AllMailboxes in (Get-Mailbox)) { New-MailboxExportRequest -Mailbox $AllMailboxes -FilePath "\\<server FQDN>\<shared folder name>\$($AllMailboxes.Alias).pst" }

Limiting the scope of exported mailboxes

You will notice that the methods I describe result in exporting all mailboxes located on your servers. If you want to limit the scope of exported mailboxes, you can do so e.g. using the Get-Mailbox -Filter parameter. Here is an example of a script which lists mailboxes belonging to a security group called export1.
Get-Mailbox -Filter {MemberOfGroup -ne $export1}
NOTE: Using the -Filter parameter with the Get-Mailbox cmdlet results in excluding mailboxes that are defined in the parameter. This is why, to limit the scope of exported mailboxes to e.g. Batch1, you have to use the -Filterparameter to exclude all mailboxes that are not part of Batch1 – hence the use of the -ne (not equals) operator. Adding the -Filter parameter to the Get-Mailbox cmdlets in Method 1 and Method 2 scripts will result in limiting the scope of exported mailboxes. View the full list of filterable Get-Mailbox properties Get-Mailbox cmdlet explained

Mailbox backups to PST file: The bright and the dark side

All in all the drawbacks seem to outweigh the advantages, mainly due to clunky PST handling options and due to the files themselves being rather unstable:
ProsCons
  • Brick-level backups with (low) granularity
  • Support for mass mailbox backups
  • Customizability
  • Available for free
  • Fragility and corruptibility of PST files
  • No full database search for all mailboxes
  • No central management for backup jobs, storages, etc.
  • Lack of backup statistics
  • Increased execution difficulty due to PowerShell usage
  • Risk of data loss
  • Backup content preview only via Outlook
  • No versioning or incremental backup options (high disk space consumption)
  • Scheduling possible only via Windows Task Manager

Office 365 shared mailbox vs. public folders – what’s the difference?

Office 365 stands for collaboration. The very idea of work in the cloud stems from the need of data sharing any time we want and wherever we want. Therefore Microsoft developed features in Office 365 such as public folders and shared mailbox.


At first they might look identical, with just different names – both, shared mailbox and public folders can store all types of Outlook items, both can receive and send emails, both can be accessed by many users simultaneously etc. However, when digging deeper into Office 365, differences start to emerge. Public folders are known from previous versions of Exchange. They appear in Outlook as a separate structure with the folder hierarchy supporting all types of items. They can also store files, documents etc. With Exchange 2013 and Office 365 they were redesigned slightly and now are stored in the same database as mailboxes.

Public folders

Public folders are best used as a project collaboration tool,  or data archiving entity. They can be mail enabled to receive message flow, serve as main appointment calendar or elaborate task management structure. Their main feature is its distribution – once the admin enables public folders they are automatically shown in users’ Outlooks.

Shared mailbox

Shared mailbox is a mailbox without a user. In other words – it is a mailbox to which many users have access and can send/receive messages. It serves best as a common contact mailbox, such as support team email or sales representatives general address. Therefore it is very often that each company department has its own shared mailbox with designated users or groups that have access to them.
Main differences are confronted in the table below.
Shared MailboxPublic Folders
Targeted number of usersSmall/MediumLarge
Who can access by defaultDesignated users/groupsAnyone in organization
Accessibility in OutlookEach user has to add shared mailbox to their
Outlook manually
Once enabled – appears automatically in all
Outlook clients
Accessibility in OWAYesYes (limited to mail folders only, marked in
Outlook as favorites)
Accessibility from mobile devices (Active Sync)NoNo
Storage limits in Office 36510GB50GB
.

SAN certificates and Split-brain DNS in Exchange 2013

After a successful Exchange Server upgrade or completely new deployment, many administrators decide to purchase a SAN (Subject Alternative Names) certificate for their organization. These certificates are perfect for securing Exchange services such as OWA, ActiveSync, POP3 and IMAP, because they allow for multiple domain names in a single SSL certificate.
Creating a self-signed certificate within your own domain is also an option, but, without a certificate issued by a certificate authority, users accessing your services from outside of the domain will receive a security warning like the one below:
Standard warning displayed in browsers when entering a non-certified namespace

Certificate planning

Before you purchase a certificate, it’s worth taking a moment to find out which type best fits your needs.
A SAN certificate is a good choice if you want to use multiple names or domains, e.g.: www.example.com, www.different-domain.com, mail.example.com, etc. It’s also relatively low priced – including 4 domains in it costs circa $250 per year.
Wildcard certificates are the way to go if you want to cover an unlimited number of subdomains within one domain (*.example.com). However, their cost is significantly higher. For an annual subscription your may end up paying around $500.
infoIn this article I will use example.com as the external domain’s name and example.local as the internal domain’s name.
In a small Exchange 2013 deployment these two namespaces should be included in the certificate request first and foremost:
  • autodiscover.example.com – for the Autodiscover service, which is necessary to find users’ settings;
  • mail.example.com – for OWA, Active Sync and Outlook Anywhere.
To have your mail encrypted using TLS, you will also have to include the FQDN of your send connector in the certificate:
  • smtp.example.com
If users in your organization utilize POP3 and IMAP protocols, the following names should also be included in the certificate request:
  • imap.example.com
  • pop3.example.com
Apart from Exchange services, you may also want to use the certificate for multiple web applications. In this case you should consider purchasing a wildcard certificate.

Creating a certificate request in Exchange 2013

The first step to obtaining a digital certificate is creating a new certificate request in the Exchange admin center on your Exchange 2013 server. To do this you have to log in to EAC, and go to serverscertificates.
Exchange admin ceneter: Certificate management menu
Click the plus button to open a new Exchange certificate request creation wizard. Select the first option: Create a request for a certificate from a certification authority.
Exchange admin center: The first step of the certificate request wizard
Type in a „Friendly name” for the certificate (this will be the certificate’s display name):
Exchange admin center: The second step of the certificate request wizard
After clicking next you will get an option to request a wildcard certificate. In this example we’re only interested in SAN certificates, so proceed to the next step by clicking next. In the subsequent window select the server on which the certificate request will be stored and click next:
Exchange admin center: The fourth step of the certificate request wizard
The next window contains a list of suggestions of service related domains you may want to certify. You can skip this step, because the final list of domains which will be included in the request can be edited and confirmed in the next window:
Exchange admin center: The sixth step of the certificate request wizard
The subsequent window is very important – this is where you provide your organization’s details. Certificate providers often check these details against information in WHOIS databases – irregularities may impede the certification process. Another thing to remember is that certification centers often send verification emails to typical domain administrator email addresses such as administrator@example.com or webmaster@example.com.
Exchange admin center: The seventh step of the certificate request wizard
The last window of the wizard requires you to specify the path of a file where the certificate will be saved. The path has to be provided in the UNC format and the Exchange Trusted Subsystem group must have permissions to write in this location.
Exchange admin center: The final step of the certificate request wizard
After clicking finish a new entry with the status “Pending request” should appear in the list of certificates in your Exchange admin center and a new file with a .reg extension should be created on your C: drive.
Exchange admin center: A 'Pending request' entry in the certificate management menu

Sending the certificate request to an external CA

Once you have the certificate request ready, you can send it to an external Certificate Authority (CA) of your choosing. When comparing options, remember that important criteria (other than the cost) include: compatibility with Exchange 2013, availability of support, and the right to repair potential errors in a certificate.
In many cases, order forms on CA’s websites allow for pasting/uploading CSR files. A CSR file is nothing more than a text file formatted like this:
—–BEGIN CERTIFICATE REQUEST—-
(string of characters)
—–END CERTIFICATE REQUEST—-.
The string of characters in the CSR file is the same string of characters that you will see when you open your .reg certificate request file (the one saved to the UNC path) in Notepad. Copying its contents into the certificate order form will result in displaying the domain names you entered earlier.
The process of verification of the domain owner depends on the CA. Typically, the CA will contact you by sending emails to standard addresses I mentioned before. To complete the verification, they may e.g. request that you include certain text records in your public DNS.

Completing a pending request

Once you have met all the certification requirements and paid for the requested certificate, you should receive an email from the CA with an attached zip file. The zip file will contain installation instructions and a .cer certificate file. After saving the .cer file to your disk, follow these steps:
In Exchange admin center go to serverscertificates and click the pending certificate request. In the bar on the right click Complete.
Exchange admin center: Completing a 'Pending request' for a certificate
A new window will pop up. In it, you will be prompted to provide the UNC path to the .cer certificate file your received from the CA.
Exchange admin center: Providing the path where the certificate .cer file is saved
After the certificate is uploaded, its status should change from Pending request to Valid.
Exchange admin center: A newly installed certificate visible in the certificate management menu

Assigning services to a certificate

Now that you have a valid SSL certificate installed on your Exchange server, you can proceed to assign specific services to it. To do this, in Exchange admin center go to serverscertificates, select the newly installed certificate and click the pen button above the certificate list. In the resulting window select the services tab and assign the certificate to services of your choosing (in my example it’s SMTP, IMAP, POP and IIS).
Exchange admin center: Assigning services to a new certificate
All that’s left now is configuring external access domains for all necessary virtual directories. This has to be done separately for each directory*, but is very simple – in the Exchange admin center go to serversvirtual directories, select a server, highlight the entry you want to configure and click the wrench button. In the resulting window select a client access server and type in your external domain.
* To configure access to the Autodiscover service you have to use PowerShell. More on the subject in the ‘Split-brain DNS method’ section below.
Exchange admin center: Providing external access domains for virtual directories
Time to finish up. Set the cname or A record on your DNS server so that the external domain points to your organization’s external IP address. Next, remember to redirect port 443 in your firewall/router to your Exchange 2013 server’s internal IP address.
The easiest way of verifying that the certificate has been installed correctly, is by accessing your external OWA address (e.g. https://mail.example.com/owa) from outside of your domain. With everything set correctly, the OWA login page will load without warnings.OWA log in screen without a certificate warninig
The address bar will include a lock icon indicating that the connection is secure:
A lock icon visible in browser address bars when entering a certified namespace
The color of the icon depends on your browser. The important thing is that, upon clicking the icon a window will expand with information about the installed certificate and connection status.

Split-brain DNS method

This method lets you set up your internal DNS server so that your internal users can access virtual directory resources using external domain names, without receiving security warnings or their queries being routed via external servers. In this example, we will use split-brain DNS in my Exchange 2013 infrastructure, so that the mail.example.com domain becomes available for internal users and they don’t receive a certificate error warning when accessing it.
The first thing we have to do is provide an internal URL for every Exchange 2013 virtual directory. The process is similar to setting external access domains, which I explained in the previous section.
In the Exchange admin center go to serversvirtual directories and select our server in the select serverdropdown menu. Next, highlight a directory and click the edit button (pen icon) above the directory list. In the resulting window change the Internal URL to https://Your External Domain/Directory (e.g. https://mail.example.com/ecp).
Exchange admin center: Configuring an internal URL for a virtual directory
Important! The internal URL of the Autodiscover virtual directory can only be changed via Exchange Management Shell using the below command:
set-clientaccessserver –autodiscoverserviceinternaluri “https://Your External Domain/autodiscover/autodiscover.xml”
After changing the virtual directories’ internal URLs, you have to change the DNS setting so that it points to your Exchange 2013 server’s local network IP address. To do this, open DNS Manager, in the console tree right-clickForward Lookup Zones and select New Zone…
DNS Manager: Creating a new Forward Lookup zone
Select Primary zone and click Next:
DNS Manager: First step of creating new zone
Select the option to replicate the zone To all DNS servers running on domain controllers in this domain:
DNS Manager: Second step of creating new zone
Important! If the server that hosts your company www or ftp site is located outside your local network (e.g. at an external webhost) it’s best to create separate zones for each domain (autodiscover.example.com, mail. example.com) used by your Exchange 2013. Otherwise you run the risk of blocking access to the company website for internal users, in which case you would have to modify the newly create zone by adding A or CNAME records for external services.
In the next step, type in the name of the zone (e.g. the domain for which it is created):
DNS Manager: Third step of creating new zone
Next, select the Do not allow dynamic updates option:
DNS Manager: Fourth step of creating new zone
The last window will contain a summary of the new zone.
In the newly created DNS zone, create an A record pointing at your Exchange 2013 server’s local IP address.
Repeat the above steps for all necessary virtual directories.

Verification

To verify that the settings are correct check if your DNS server resolves external domains, such as mail.example.com, to your local Exchange 2013 server’s address. To do this, in cmd console run the ping command for all domains which now have newly created lookup zones:
Ping mail.example.com
Ping autodiscover.example.com
Etc.
If in all instances you receive a reply from the same IP address, this will mean that the DNS setting is correct.
For further verification, delete your mail profile in Windows and run Outlook to confirm that Autodiscover correctly finds your mailbox’s configuration data.