PowerShell scripts can be used to perform various tasks during a migration.
To add and execute a PowerShell script:
- If you have a pre-created script, open the PowerShell script in Notepad++ and copy the entire script,
- Select the PowerShell option from the Navigation column in CloudM Migrate Self Hosted,
- Select the Edit button,
- Paste the script into the field (or write the script in the field if creating one),
- Select Execute.
Step-by-step guide
Replacement variables can be seen in the default PowerShell scripts and provide a way to pass information from the CloudM Migrate configuration to the scripts. Replacement variables have the following format [!variable-name]
. Before a script is run, these variables are replaced with their values. Several values are included with the tool and it is also possible to define your own.
The included variables and their values are:
-
[!admin-email]
– The email address of the admin user -
[!admin-password]
– The password of the admin user -
[!admin-domain]
– The domain name being migrated to -
[!user-exportname]
– The export name of the user being migrated -
[!user-importname]
– The import name of the user being migrated -
[!user-password]
– The password of the user being migrated -
[!user-givenname]
– The given name of the user being migrated -
[!user-familyname]
-The family name of the user being migrated -
[!ps-url]
– https://ps.outlook.com/powershell
For example, the following is the default init PowerShell script:
1 # Open the connection 2 $sesh = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri [!ps-url] -credential (New-Object -TypeName System.Management.Automation.PSCredential -argumentlist '[!admin-email]',(ConvertTo-SecureString '[!admin-password]' -AsPlainText -Force)) -Authentication Basic -AllowRedirection 3 # Import the session 4 $imp = Import-PSSession -Session $sesh
This contains the replacement variables [!ps-url]
, [!admin-email]
and [!admin-password]
. Before the script is run, these values will be replaced with the corresponding values from the configuration, giving a final script something like:
1 # Open the connection 2 $sesh = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -credential (New-Object -TypeName System.Management.Automation.PSCredential -argumentlist 'admin@cloudsolutions.co.uk',(ConvertTo-SecureString 'myR34llyG00dP@55w0rd' -AsPlainText -Force)) -Authentication Basic -AllowRedirection 3 # Import the session 4 $imp = Import-PSSession -Session $sesh
To define your own replacement variables use the setting ‘PowerShell Variables’ in the Office 365 / Exchange destination migration settings.
To setup a remote PowerShell session, two PowerShell commands must be run
If you are running PowerShell on the same machine as the Exchange installation then you do not need to setup a remote PowerShell session. You should be able to run the Exchange cmdlets directly in the Exchange Management Shell on the server.
PowerShell scripts and Microsoft 365
Step-by-step guide
- Open PowerShell on your workstation.
- Run the following command.
$sesh = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -credential (New-Object -TypeName System.Management.Automation.PSCredential -argumentlist 'ADMIN_EMAIL',(ConvertTo-SecureString 'ADMIN_PASSWORD' -AsPlainText -Force)) -Authentication Basic -AllowRedirection
- When the PowerShell session has been started, run the following command to import the Exchange cmdlets into the current session.
$imp = Import-PSSession -Session $sesh
Common Issues
- WinRM errors – When connecting to an Exchange 2010, the most common errors that can be seen are related to the WinRM framework. Carefully examine any errors returned and check the Microsoft KB articles for resolutions.
- Execution policy – If errors are obtained when running Import-PSSession, you may need to set the local script execution policy by running
Set-ExecutionPolicy RemoteSigned
. - Connecting via a proxy – If you connect via a proxy to the Internet you may need to setup proxy access using session options on the command. There are various ways this can be done but if you can use the same proxy as the default system proxy run the following command before running
New-PSSession
:$ProxyOptions = New-PSSessionOption –ProxyAccessType IEConfig
New-PSSession
command:-SessionOption $ProxyOptions
- Session options – If you need to perform authentication to the proxy or you need to connect to a proxy other than the default system proxy, please see the Microsoft help topic about
New-PSSessionOption
here. If you need to use extra session options then you will also need to modify the PowerShell scripts that the tool runs as part of the migration process.
Using Office 365 Deployment Powershell Modules with CloudM Migrate
It is possible to use the Office 365 PowerShell Modules with CloudM Migrate.
Step-by-step guide
Install the PowerShell Module available from:
It can take some time before a mailbox is fully allocated after called New-MsolUser and until the mailbox exists, migrations will fail with InvalidUser. Using the default scripts, which call New-Mailbox usually allows migration to commence immediately after running the script.
When these have been installed the PowerShell scripts within the CloudM Migrate need to be edited to use the newly available MSOnline cmdlets.
Edit the ‘PowerShell Init Script’ to be as follows. This script opens a connection to the Office 365 servers.
# Set this so that errors are thrown from Cmdlets $ErrorActionPreference = 'Stop' # Import the Office 365 Module Import-Module MSOnline # Open the connection Connect-MsolService -credential (New-Object -TypeName System.Management.Automation.PSCredential -argumentlist '[!admin-email]',(ConvertTo-SecureString '[!admin-password]' -AsPlainText -Force))
Edit the ‘PowerShell Before Script’ to be as follows. This script checks a user exists and creates one with the provided details if not. Note the script below sets the ‘Usage Location’ to be the US – change this if required.
# Set this so that errors are thrown from Cmdlets $ErrorActionPreference = 'Stop' # Check if a user exists Function UserExists() { trap { return $false } Get-MsolUser -UserPrincipalName '[!user-importname]@[!admin-domain]' return $true; } # Create a user if it doesn't exist Function CreateUser() { $ret = UserExists if ($ret -eq $false) { New-MsolUser -UserPrincipalName '[!user-importname]@[!admin-domain]' -DisplayName '[!user-givenname] [!user-familyname]' -FirstName '[!user-givenname]' -LastName '[!user-familyname]' -UsageLocation US -Password '[!user-password]' Start-Sleep 30; } } CreateUser
PowerShell scripts and Exchange 2010
Step-by-step guide
The default PowerShell scripts included with the migration tool are for migrations to Microsoft 365. If you are migrating to Exchange 2010, you need to update the scripts, or disable them if they are not needed. The same changes to the Init script can also be made to the ‘Get User’ Init script when migrating from Exchange 2010. These scripts make use of PowerShell replacement variables
Init Script
The init script initializes a remote PowerShell session with the Exchange 2010 server. You should change the value of [!ps-url]
in the default script to the URL for your Exchange 2010 PowerShell endpoint. For example:
# Set this so that errors are thrown from Cmdlets $ErrorActionPreference = 'Stop' # Open the connection $sesh = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://myserver.com/powershell -credential (New-Object -TypeName System.Management.Automation.PSCredential -argumentlist '[!admin-email]',(ConvertTo-SecureString '[!admin-password]' -AsPlainText -Force)) -Authentication Basic -AllowRedirection # Import the session $imp = Import-PSSession -Session $sesh
Running Locally
It is also possible to run CloudM Migrate directly on an Exchange server. In this case you do not need to setup a remote session and can set the ‘Init Script’ to ‘Never’ run in the tool configuration. The same also applies to the ‘Get User Init Script’ when migrating from Exchange 2010 and you have installed the tool directly on an Exchange server.
Before Script
The before script checks that the specified user exists in Exchange 2010, and creates it if not. An example script for Exchange 2010 is shown below. You should edit the default script (which is for Microsoft 365) to specify UserPrincipalName
rather than MicrosoftOnlineServicesID
. Note that if migrating to Live@Edu, it should be replaced with WindowsLiveID
.
# Set this so that errors are thrown from Cmdlets $ErrorActionPreference = 'Stop' # Check if a user exists Function UserExists() { trap { return $false } Get-User -Identity [!user-importname]@[!admin-domain] return $true } # Create a user if it doesn't exist Function CreateUser() { $ret = UserExists if ($ret -eq $false) { New-Mailbox -Name '[!user-givenname] [!user-familyname]' -UserPrincipalName [!user-importname]@[!admin-domain] -Password (ConvertTo-SecureString -String '[!user-password]' -AsPlainText -Force) # Allow some time for the account to become active Start-Sleep –s 15 } } CreateUser
Error Messages
The tool determines whether a script has run successfully if no exception is thrown from the script. In PowerShell, internal cmdlets handle their own errors unless instructed to do so in the script. It is usually important to include the global statement $ErrorActionPreference = 'Stop'
, in the script.
You can also throw your own custom exception from scripts if required which will then be displayed in the user interface and trace files.