Categories
Office 365 PowerShell

Connecting to Office 365 with automation

In order to automate management activities for Office 365, it’s imperative to connect to the remote environments without human interaction. Typically this type of automated job will be run with Task Scheduler. However, due to differences between Windows authentication and Office 365 authentication, this is not quite as straightforward as running a Task Scheduler job with a service account in a pure Windows Server environment.

Fortunately there is a method of creating a file-based credential that securely associates an Office 365 user account with a local or Active Directory user account. We can then provide that credential file to the Office 365 connection string in our scripts. This allows us to schedule our scripts in Task Scheduler, run them as the local or Active Directory user account, and gain access to Office 365 resources.

  1. First, it’s important to logon to the server where the Task Scheduler will run, and to logon there as the user account that will be running the Task Scheduler job (i.e., domain\userA). This can be either a local user account or an Active Directory user account.
  2. Now we create the credential file using the Export-Clixml cmdlet. We must specify the Office 365 user account we plan to use in our scripts (i.e., cloudUser@tenant.onmicrosoft.com), and we’ll be prompted for the password on that cloud account when we execute the following command. An XML credential file will be produced in the path we specify in the Export-Clixml cmdlet.
    Get-Credential "cloudUser@tenant.onmicrosoft.com" | Export-Clixml C:\credentials\office365_credential.xml

    1. Note that the credential file we create here is tied to this account on this machine, and can only be used on this machine.
  3. Now that the credential file has been created, we can log out of the server and log back in with our standard administrative account if desired.

Now that we have the credential file, we can use it in our scripts to gain access to any Office 365 resource where this Office 365 user account (i.e., cloudUser@tenant.onmicrosoft.com) has permissions as long as we run those scripts as the associated user account (i.e., domain\userA). Keep in mind that the credential file will be unusable if it is copied to another computer, or even if it is used by any other user account on the computer where it was created!

Here is a sample connection string to connect to Exchange Online using our credential file as long as it’s run by the domain\userA account.

$credential = Import-Clixml C:\credentials\office365_credential.xml
$Session = New-PSSession `
-ConfigurationName Microsoft.Exchange `
-ConnectionUri https://outlook.office365.com/PowerShell-LiveID?PSVersion=4.0 `
-Credential $credential `
-Authentication Basic `
-AllowRedirection
Import-PSSession $Session

Here is a sample connection string to connect to Microsoft Online using our credential file.

Import-Module MSOnline
$credential = Import-Clixml C:\credentials\office365_credential.xml
Connect-MsolService –Credential $credential

Categories
Office 365

Office 365: removing Litigation Hold mailboxes in an Exchange Hybrid environment

In our hybrid Exchange 2010 / Exchange Online environment, we occasionally need to place an Exchange 2010 mailbox on Litigation Hold. In some cases, that user’s mailbox will need to be removed but the Active Directory account will need to be retained. Exchange 2010 will not allow a mailbox on Litigation Hold to be removed, so our practice has been to simply export the mailbox to PST for retention, manually remove the Litigation Hold, and then remove the mailbox. However, we’ve learned that Exchange Online requires a slight change to that procedure.

Exchange Online was reporting an error regarding a few such users.
Exchange: An unknown error has occurred. Refer to correlation ID:

Referencing this article to help determine the problem, I ran some code against MSOL to look at a more detailed error report.
http://support2.microsoft.com/kb/2741233

$errors = (Get-MsolUser –UserPrincipalName user@domain.edu).Errors
$errors | foreach-object {"`nService: " + $_.ErrorDetail.Name.split("/")[0]; "Error Message: " + $_.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription}

The output provided the details need to understand the problem.

Service: exchange
Error Message: Exchange can't disable the mail user "NAMPRXXXXXX.prod.outlook.com/Microsoft Exchange Hosted Organizations/tenant.onmicrosoft.com/user" because it is on litigation hold.

First I tried to simply remove the MsolUser using this command.
Remove-MailUser –Identity name@domain.com –IgnoreLegalHold

However, that returned an error.

The following error occurred during validation in agent 'Windows LiveId Agent': 'Unable to perform the save operation. 'user' is not within a valid server write scope.'

After engaging Microsoft on the problem, we determined there are two options to address the error:

  1. If the MSOL account is not actually required in Azure Active Directory (AAD), we can simply delete it and purge it from the AAD recycle bin. At the next DirSync cycle, a new MsolUser will be created and the error will be resolved. (See the important NOTE below.)
  2. An Exchange Online license could be assigned temporarily to the MsolUser to create a new Exchange Online mailbox. After allowing time for the mailbox to be created plus additional time for a DirSync cycle, remove the Exchange Online license again, and the mailbox will be deleted. This should allow the backend processing to occur and resolve the error.

In most cases, Option 1 is probably most palatable. I issued these two commands, and after the regular DirSync scheduled sync, the error has been resolved. Of course you can add the -Force parameter to quickly execute the commands without having to confirm.

NOTE: If the AAD account is removed, this will also remove the user’s access to other Office 365 data such as OneDrive for Business.

Remove-MsolUser -UserPrincipalName user@domain.edu
Remove-MsolUser -UserPrincipalName user@domain.edu -RemoveFromRecycleBin

In summary, the way to avoid the problem is to remove the Litigation Hold from the Exchange 2010 mailbox, then wait for a DirSync cycle, and then remove the Exchange 2010 mailbox. If both actions are taken quickly together and an error is reported in the Office 365 Admin Center, just purge the AAD account as described above to resolve the error.

Categories
Office 365 PowerShell

Rotate images in ADFS 3.0

ADFS 3.0 is otherwise known as ADFS 2012 R2 since it is available only on Server 2012 R2. As I gain some experience with it, one of the nice configuration options is the ability to use PowerShell to customize the sign-in page.

Among the customizations we’ve made is one to help keep our sign-in page from looking stale over time. I wrote this simple PowerShell script to rotate the large “illustration” image occasionally. It runs as a Scheduled Task, and pulls approved images randomly from a file system folder. The script also logs which image was in place at any given time in case that happens to be interesting to someone at some point.

cd X:\path\images
$RandomImage = Get-ChildItem | Get-Random | %{((Get-Item $_).VersionInfo).FileName}
(Get-Date -format G) + " $RandomImage" | Out-File X:\path\Logs\IllustrationRandomizer.log -Append
Set-AdfsWebTheme -TargetName Custom_Theme -Illustration @{path=$RandomImage}