ExchangeNerd

Powered by Ed Buford and Coffee

Office 365 Public Folder Migration

I was working in a Hybrid Exchange Deployment of Office 365 this past week and came across a few issues with the documentation from Microsoft so I thought I’d point out a couple of issues.

The first issue I ran into was locating the correct scripts to make it work. When you look at this documentation on Public Folder Migration you’ll be hard pressed to actually find a link that will help you download anything: http://technet.microsoft.com/en-us/library/jj983799(v=exchg.150).aspx

But all in all that document is what you MUST work out of to make this public folder migration work.

If you go out to the Download center and search for the Public Folder Migration Scripts you’ll find that the download is missing a couple of the scripts you need to make this work but download these anyway because you will need these anyway: http://www.microsoft.com/en-us/download/details.aspx?id=38407

You’ll also want to download these scripts because these include the ones missing from the above scripts link: http://www.microsoft.com/en-us/download/details.aspx?id=38408

As I worked through a couple other issues I had with the documentation I stumbled on a couple of other things – first this:
“PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99”
From the code below left me scratching my head – However in the end it does work even though I could not find out what boilerplate the code is form. 
Make certain when you run this you use the DomainName.OnMicrosoft.com and not just your DomainName.Com

New-AcceptedDomain -Name "PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99" -DomainName contoso.onmicrosoft.com -DomainType InternalRelay 

During the Start the Migration Request phase of the process I collected all the information and ran the request in Step 6 and started getting errors with this heading:
MapiExceptionNoAccess: Unable to make connection to the server. (hr=0x80070005, ec=-2147024891)
At first I started to despair and then while I stared it I realized the command

New-PublicFolderMigrationRequest -OutlookAnywhereHostName: $source_OutlookAnywhereExternalHostName -CSVData (Get-Content <folder_mapping.csv> -Encoding Byte) -RemoteCredential: $source_credential -RemoteMailboxLegacyDN: $source_remoteMailboxLegacyDN -RemoteMailboxServerLegacyDN: $source_remotePublicFolderServerLegacyDN -AuthenticationMethod Basic

While looking at this I began to realize the -AuthenticationMethod Basic was the cause and although the documentation didn’t give me a good clue it did hit me that the Auth was for Outlook Anywhere which was part of the collection of information to build the request. Since OA was NTLM not Basic I reran the request with NTLM at the end and it worked.

Once I got it kicked off I wanted to be able to see the percent complete when looking at the request so I ran this command to see that:

Get-PublicFolderMigrationRequest | Get-PublicFolderMigrationRequestStatistics -IncludeReport | FL Statusdetail,percentcomplete

The final thing I ran into was an error after I started the finalization  where the Status Detail was the StatusDetail was StalledDueToMailboxLock
StatusDetail    : StalledDueToMailboxLock
PercentComplete : 95

After some searching I came up with the solution of restarting the information store on the Legacy Exchange server. Once I did that shortly afterwards the Status moved to Completion and then finished.

One resource which helped me a considerable amount was the Microsoft Exchange 2013 Cookbook from  Michael Van Horenbeeck. Although it is not aimed at Office 365 I’ve used this to migrate Public Folders to Exchange 2013 servers and was able to glean enough from it to ease the pain of the unclear Microsoft Documentation.

Mailbox Migration quick view

Frequently I start mailbox migrations on a Friday night and then babysit the moves all weekend long (or longer). Clients like to know some basic info about the move just to check to make certain things are going as expected.

Now when you’re moving hundreds of users at a time the last thing you want to do is try to count all the users that are completed so you can give an update to your clients. So I created a simple powershell script to tell me how many users are Queued, completed, failed or moving.  Hope this is helpful:
get-movestats

# Simple script to Display Mailbox migration stats
# 1.0 Ed Buford AKA ExchangeNerd (or just Nerd for short)

$queued=Get-MoveRequest | Where {$_.status -eq "Queued"}
$comp=Get-MoveRequest | Where {$_.status -eq "Completed"}
$Failed=Get-MoveRequest | Where {$_.status -eq "Failed"}
$move=Get-MoveRequest | Where {$_.status -eq "Inprogress"}

write-host There are $queued.count mailboxes Queued -foregroundcolor Green
Write-host There are $move.count Mailboxes moving -foregroundcolor Green
Write-host there are $comp.count Mailboxes Completed -foregroundcolor Green
Write-host there are $failed.count Mailboxes Failed -foregroundcolor Green
[Top]

Simplifying Exchange 2013 URL

Thanks to a great Script from Pat Richard at Ehlo World I was able to do an HTTP Redirect to HTTPS without much effort for Exchange 2010 CAS servers.

Exchange 2013 is not as easy to do http redirection as 2010. It took a lot of trolling the forums to find a process that works for me and I thought I’d share it with you.

The process is three easy steps – make sure you do all three!

Step 1. Locate the Web.Config file it should be in your inetpub folder.  For most of us that’s  C:\inetpub\wwwroot but for many of you it could be located on another drive.

Open the Web.config file as an administrator file and open it with Notepad.

*Note Lines 2 and 4 I have added the <!–    –> comments to keep from loading the Modules. Add these comment brackets and save the file.

<system.webServer>
<!-- <modules>
<add name="OwaUrlModule" type="Microsoft.Exchange.HttpProxy.OwaUrlModule,Microsoft.Exchange.OwaUrlModule,Version=15.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="" />
</modules> -->
</system.webServer>

 

 

Step 2.  While you’re still working out of the Inetpub\wwwroot folder you’ll want to create a new file called Default.htm  and paste the code into it and save it.

<html><meta http-equiv="REFRESH" content="0;url=/owa"></HEAD></html>

 

 

Step 3.  Open IIS Manager and Highlight the Default Website.  In the Center pane under IIS choose Error Pages. In the Actions Pane choose Add and create a new Custom Error Page.

In the Status code box Type: 403.4  then choose the Respond with a 302 redirect and type the complete path to OWA

 

Redirect

Once you’ve finished click ok and then Do an IISReset to start using the changes.

 

 

[Top]

Multi Mailbox search in Office 365

I’ve was asked to do a Multi-Mailbox search in Office 365 to gather some email when their Journal somehow stopped Journaling.

Now In Exchange I could do this without much thought but doing anything in Office 365 takes me a lot longer as there just don’t seem to be great blogs written on the mundane things I want to do as of yet so I thought I’d add my own.

The Task:
Gather together all the email (undeleted) over the past month and export it to a PST.
Discovery:

  • The user creating this request must have an SMTP address the same as the mailboxes you’re searching (this means the user must be a mailbox user).
  • The user creating this request must be a member of the Discovery Management role group.
  • You need to use the User Principal Name in the of the Discovery Mailbox in order to send the mailbox to create the Powershell Request.

The Solution:

Find your Discovery Mailbox

Get-Mailbox -Resultsize unlimited -Filter {RecipientTypeDetails -eq “DiscoveryMailbox”

Find the User Principal Name for the Mailbox:

Get-Mailbox -Resultsize unlimited -Filter {RecipientTypeDetails -eq “DiscoveryMailbox”} |FL UserPrincipalName

Get Discovery management Group Members:
Get-RoleGroupMember -Identity “Discovery Management”

Add User to Discovery Management
Add-RoleGroupMember -Identity “Discovery Management” -Member USERNAME

Create the search:
New-MailboxSearch “SearchName” -StartDate “1/1/2014” -EndDate “1/22/2014″ -TargetMailbox ” Discovery Mailbox UPN” -MessageTypes Email -IncludeUnsearchableItems -LogLevel Full

Start the Search:
Start-MailboxSearch “SearchName”

Get-MailboxSearch |FL

[Top]

Quick Weather

A script a co-worker wrote to grab weather

$url = "http://w1.weather.gov/xml/current_obs/KSBN.xml"
$data = Invoke-RestMethod $url
$temp = $data.current_observation.temp_f -as [decimal]
$wind = $data.current_observation.wind_mph -as [decimal]
$weather = $data.current_observation.weather

$temp_desc = $null
$wind_desc = $null

switch($temp)
{
    { $_ -le 15 } { $temp_desc = "stupidly cold outside" }
    { $_ -le 40 -and $_ -gt 15 } {$temp_desc = "cold outside"}
    { $_ -le 60 -and $_ -gt 40 } {$temp_desc = "a little chilly outside"}
    { $_ -le 80 -and $_ -gt 60 } {$temp_desc = "warm and comfortable outside"}
    { $_ -le 90 -and $_ -gt 80 } {$temp_desc = "quite warm outside"}
    { $_ -le 100 -and $_ -gt 90 } {$temp_desc = "hot outside"}
    { $_ -gt 100 } {$temp_desc = "stupidly hot outside"}
}

switch($wind)
{
    { $_ -le 0 } {$wind_desc = "quiet, a little too quiet...."}
    { $_ -le 5 -and $_ -gt 0 } {$wind_desc = "a gental breeze."}
    { $_ -le 10 -and $_ -gt 5 } {$wind_desc = "a brisk draft."}
    { $_ -le 15 -and $_ -gt 10 } {$wind_desc = "quite a bit windy."}
    { $_ -le 20 -and $_ -gt 15 } {$wind_desc = "blowing more than you would like."}
    { $_ -le 25 -and $_ -gt 20 } {$wind_desc = "frustratingly powerful."}
    { $_ -ge 26 } {$wind_desc = "an unstopable hurricane!"}

}
"The weather is currently $temp_desc with winds that are $wind_desc You might also notice it's $weather."

Save the script and then execute it like this:

./Get-QuickWeather.ps1

Another one-line example:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri&nbsp;&nbsp;-Credential $LiveCred -Authentication Basic –AllowRedirection

 

[Top]