Find me in different places
Sunday
May052013

Exchange 2013 OWA Review

Let me start this way, I absolutely love the new OWA in 2013. I am a user that is on a bunch of different devices. I have an iPhone 5, iPad 2, Surface RT, MacBook Pro Retina, iMac at home and a PC desktop at work.

For my mail I use EAS on the iOS devices, I have beta tested some new mail replacements but they aren't very reliable, I will review them when they are released. On the Surface I use OWA, the built in Mail client really bugs me, I don't know why but I hate using it so I found OWA to work great. At work its Outlook 2013 and on the macs its OWA, I have been using Fluid to keep OWA in its own icon on my dock so I can always find my mail and not dig through tabs.

I like the Lync integration in OWA, I hope that Microsoft works to make it fully featured in future CUs becuase its a little awkward on the Surface in full screen IE; a new IM opens in a new window and it is annoying to switch back and fourth, it would be nice if it was embedded in the same window. Also starting a new IM isn't intuitive, searching for the user and then clicking the IM button is a little backwards.

The downside of just using OWA is notifications, yes the new mail sound does play but I don't always have my speakers on. My work around is having my phone on the table next to the device I am using (Mac or Surface) and when I see the notification of new mail I switch to OWA to read and reply to it or when the Lync mobile app shows a new IM I switch to reply. This problem isn't the fault of OWA, just of browsers in general. I had a user come to me two weeks ago and say that they loved OWA on their phone but didn't like how it was slow to refresh between looking at messages, again its not the fault of OWA but of the browser that needs to reload between pages. 

Upgrading Exchange is also a social experiment, there are some remote users that I don't hear from until the Exchange upgrade who send me long emails on why they hate the new version because some of the navigation moved from the left to the top and now its blue instead of orange and emails from others who love the change.

The most interesting thing is that many Mac users have said how much they like the new interface, which is ironic. 

Overall OWA in 2013 CU1 is a great upgrade over 2010. As the only user visible side to Exchange its important for Microsoft to keep improving it, I hope they add more features in future CUs and not make us wait until the next full version. I think that the new OWA is worth the migration to Exchange 2013 and that the other features on the backend are just a bonus for the admins.

I know some Exchange admins don't like the Exchange Admin Center, I have to admit I have only been in it a few times I mostly use Powershell for all of the administration.

I welcome your thoughts, what do you think about the new OWA?

Tuesday
Apr022013

Configuring Exchange 2013 with Powershell- Part 4: Kemp Load Balancer

I have been a little delayed in posting lately, I am hoping to finish all of the posts for Exchange 2013 now that CU 1 has been released and we can now actually deploy it.

I won't spend too much time talking about the load balancer themselves, but they are highly recomended by me, they are a small company and are quckly becoming the standard for Lync and Exchange.

To do the setup its really easy. Lets first setup our arrays

$kempurl = "https://hlb.contoso.com"
[array]$kempVSIP = "10.0.0.25", "10.0.0.26", "10.0.0.27"
[array]$kempVSPort = "443", "443", "25"
[array]$kempVSProt = "tcp", "tcp","tcp"
[array]$kempCheckPort = "https", "https", "smtp"
[array]$kempServiceType = "http", "http","gen"
[array]$kempVsDefaultGateway = "10.0.0.1", "10.0.0.1"
[array]$kempRealServerPort = "443", "443", "25"
[array]$kempcheckURL ="mail.contoso.com/OWA","mail-OA.contoso.com/rpc/rpcproxy.dll","" #Make sure this has the same number of URLs as services being created, for SMTP leave null

and then another array of the IPs of our CAS

[array]$kempRealServers = "10.0.0.35", "10.0.0.36"

For this example I am just creating 3 virtual services, 1 for OWA, EAC, EWS, AS; 1 for Outlook Anywhere; and finally 1 for SMTP. Note that this is an example, There are definaly reasons to create seperate services for each directory. If you want to learn more I highly recommend listening to this epsoide of the UC Architects podcast with Greg Taylor.

Now lets get back to configuring, Before we continue, make sure you have already configured your load balancer and can get a simple connection first, look at this post for help connecting. Now lets add our new virtual services.

        $c = Get-Credential
        for($i = 0; $i -lt $kempVsIP.Length; $i ++) {

        $vs = $kempVsIP[$i]
        $port = $kempVsPort[$i]
        $name = $kempVsName[$i]
        $checkType = $kempCheckPort[$i]
        $defaultGateway = $kempVsDefaultGateway[$i]
        $servicetype = $kempServiceType[$i]
        $realserverport = $kempRealServerPort[$i]
        $checkurl = $kempcheckURL[$i]

            $uri = $kempurl+"/access/addvs?vs=$vs&port=$port&prot=$prot&NickName=""$name""&checktype=$checktype&checkport=$port&DefaultGW=$defaultgateway&VStype=$servicetype&ForceL7=yes&transparent=no"

            if($checkurl -ne ""){
                $uri += "&checkURL=$checkurl"
                }

            $returnXML = Invoke-RestMethod -Uri $uri -Credential $c

            foreach($r in $kempRealServers){
                $uri = $kempurl+"/access/addrs?vs=$vs&port=$port&prot=$prot&rs=$r&rsport=$realserverport"

                Invoke-RestMethod -Uri $uri -Credential $c
            }
            $uri = $kempurl+"/access/showvs?vs=$vs&port=$port&prot=$prot"
   
            $returnXML = Invoke-RestMethod $uri -Credential $c
            $status = $ReturnXML.Response| Select -ExpandProperty code
            if($status -eq "ok"){
                $returnXML.Response.Success.Data
            }

So lets talk through this FOR loop, First, I found that trying to build the long string using the indexes of the arrays to cause inconsistant results, so I just set them to local variables then build the string. Next we just build the string and create the VS, add the check URL and the servers and thats it. Note that in this example we set Layer 7 transparency to off, there are many times where using L7 transparency will benifit your organization.

Thats it, the Kemp Technologies solution is pretty awesome and decently priced. If you haven't checked it out go download the demo here. Up next we will install Exchange 2013!

Tuesday
Apr022013

Setting up your Kemp Load Balancer for PowerShell

This is going to be a quick post about how to setup your Kemp Load Balancer to accept PowerShell commands.
In PowerShell V3 Microsoft added a new cmdlet called Invoke-RestMethod This command will make an HTTP post to whatever URL and then pass back the data. This lines up perfectly with Kemp releasing its RESTful API, To get the API documentation visit Kemp's site here

The first step is to upgrade your load balancer to the latest version. Kemp has been adding some new features recently so its helpful to be on the latest version. However 6.0-38 is the minimum version required

The main issue I ran into is that Kemp is requiring a https connection to make API calls. This cmdlet has an issue with self signed certs. Looking around I found a few posts of people having trouble, see here. One person here recommends creating a x509 cert but I was unable to get that to work. My workaround was using my third party wildcard cert and giving the load balancer an internal dns record instead of accessing it through the IP like the documentation suggests. My LB now has an internal dns pointer from hlb.contoso.com to the management IP. Now I can make https REST calls to the dns name and it works like a charm.

So enough of talking lets get some data.
First lets set some variables

$kempurl = "https://hlb.contoso.com"
$kempVSIP = "10.0.0.25" #use a VIP of an existing service
$kempVSPort = "443" #the assigned port to the above VIP
$kempVSProt = "tcp" #the protocol of the Virtual Service
$c = Get-Credential # This is the credential to your load balancer


Now that we have our variables lets create a variable for the URL

$uri = $kempurl+"/access/showvs?vs=$kempVSIP&port=$kempVSPort&prot=$kempVSProt"

Now that we have our string created lets make the call

$returnXML = Invoke-RestMethod $uri -Credential $c

We use this command to see what we got back

$status = $ReturnXML.Response| Select -ExpandProperty code
 if($status -eq "ok"){ #Makes sure the post succeeded
     $returnXML.Response.Success.Data
 }

If you want to see what the raw data looks like in your browser just type in $uri to show the URL and paste it in your browser so you can see all of the data in raw XML form.

To dig a little further you can just keep going down the tree, For example to get the Real Server IP addresses for a service just modify line 3 above to this:

$returnXML.Response.Success.Data.Rs | Select Addr


Or to get the Name of the Virtual Service:

$returnXML.Response.Success.Data | Select NickName


If you want to learn more about XML data in PowerShell I recommend reading through this

 

In the next post I will talk about how to create the Virtual Services we need for Exchange. But having this setup is critical to the next step

NOTE: PowerShell doesn't handle errors very well, mostly by throwing 503 errors. If you run into this type: $URI to get the URL and paste it into your browser, you will get a better explaination of what is going wrong, normally it is either an authentication issue, or it cannot find the virtual service.

Wednesday
Feb202013

Configuring Exchange 2013 with PowerShell- Part 3: Storage

So we are doing really good, we have our networking configured and the Prereqs installed, lets get to the storage.

NOTE: This is designed around using Equallogic storage, if you are using a different kind of storage you can take some of the principals and apply them to your environment.
First lets setup our variables:

$ServerName = "EX2013-01"
$lUNNames = "$serverName-DB1", "$serverName-DB2", "$serverName-Logs"
$lUNSizes = "700000","700000","100000" # Size in MB
$driveNames = "DB1", "DB2", "Logs"
$driveLetters = "K", "L","M"
$eqlGroupIP = "10.1.0.25"
$eqlDiscoveryIP = "10.200.0.1"
$storagePoolName = "default"

Just like when we configured our networking, make sure everything is in the right order and that the same number of items are in each array.

For this next section, make sure you have either used the default HIT Kit install directory or change the first line to the install location. Dell has a really good PowerShell tutorial that can be downloaded alongside the HIT kit.

First we need to import the module:

import-module -name "C:\Program Files\EqualLogic\bin\EqlPSTools.dll"


Next lets connect to the group. NOTE: This requires you know the credentails for the group.

Connect-EqlGroup -GroupAddress $eqlGroupIP -Credential (Get-Credential)


Now that we are connected lets make some volumes, do note that this sets the server that the script is running on with read and write access. If this doesn't follow your organization settings change the New-EqlVolumeAcl cmdlet.

        $iqn = (Get-InitiatorPort).NodeAddress

        for($i = 0; $i -lt $lUNNames.Length; $i++)
        {
                New-EqlVolume -VolumeName $LunNames[$i] -VolumeSizeMB $lUNSizes[$i] -StoragePoolName $storagePoolName -SnapshotReservePercent 100
       
                New-EqlVolumeAcl -VolumeName $LunNames[$i] -InitiatorName $iqn -AclTargetType volume_and_snapshot
        }

Now lets enable iSCSI Initiator and refresh the group to discover our newly created volumes.

        Start-Service msiscsi
        Set-Service msiscsi -StartupType Automatic

        New-IscsiTargetPortal -TargetPortalAddress $eqlDiscoveryIP
        Start-sleep -Seconds 3
        Get-iscsiTargetPortal | Update-IscsiTargetPortal
        Start-sleep -Seconds 8


Here is the fun part, This can be a little confusing so I will first explain what these 17 lines does.
First we will connect the first volume in the $LUNNames variable then initalize the disk as GPT style, bring it online, format it assign the drive letter, use 64kb allocation size and name it, then go on to the next volume until it has configured all of the volumes in the array. This step took a decent amount of time to perfect, it is only designed to run once, if you have an error you will need to delete the volumes from the SAN and start over. Disks don't like getting initalized twice.

        for($i = 0; $i -lt $lUNNames.Length; $i++)
        {
            $volume = $lUNNames[$i]
            Get-IscsiTarget | where{$_.NodeAddress -like "*$volume"} | Connect-IscsiTarget -IsMultipathEnabled:$true -IsPersistent:$true
          
          [int]$disknumber =  Get-Disk| Where {$_.BusType -match "iSCSI" -and $_.OperationalStatus -eq "Offline"}| Select -ExpandProperty Number

           start-sleep -Seconds 1

            Initialize-Disk -Number $disknumber -PartitionStyle GPT
            Set-Disk -number $disknumber  -IsOffline:$false

            start-sleep -Seconds 1

            New-Partition -DiskNumber $disknumber -UseMaximumSize -DriveLetter $driveLetters[$i]  | Format-Volume -AllocationUnitSize 64kb  -FileSystem NTFS -NewFileSystemLabel $driveNames[$i] -Confirm:$false
        start-sleep -Seconds 1
        }

 

So thats it, this step will create, connect and configure the storage for your Exchange server. Each piece of this can be pasted together in order and run as one script which is the way I designed it. Next up we will configure a Kemp Load Balancer.

Thursday
Feb142013

Configuring Exchange 2013 with Powershell- Part 2: Prerequisites

Now that we have our networking configured lets get the prereqs installed. I originally followed this guide to make sure I got everything in the right order. Thanks @ExchServPro

NOTE: This is for Server 2012 only, for Server 2008 R2 go here

When doing this I also wanted to run the installers for the filter packs, the UC runtime, and the Equallogic Host Integration Tools. The first step is easy, just open an elevated PowerShell prompt and paste this in:

 

Install-WindowsFeature AS-HTTP-Activation, Desktop-Experience, NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, Web-Mgmt-Console, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation, Multipath-IO -IncludeAllSubFeature -IncludeManagementTools

 

 After these complete a restart is required.

Next download the installers:
UC Runtime

Office 2010 Filter Packs
Office 2010 Filter Packs SP1

If you are using storage from Dell Equallogic login to download the HIT Kit

Now you could just kick off the installers in that order, but where is the fun in that.
First put all of those installers in the same directory. For my example I am going to go with C:\Prereqs
Now assign that location to a variable:

$prereqDirectory = "C:\Prereqs"

Now execute the following lines and they will run all of the installers. Do note that when the Equallogic HIT kit gets done installing, the server will automatically restart. The Equallogic HIT Kit will install all features, to customize the install see the installation guide.

    #UM intergration
    $install = $prereqDirectory+"\UcmaRuntimeSetup.exe /passive /norestart"
    Invoke-Expression $install
    Start-Sleep -Seconds 10
    #Filter Packs
    $install = $prereqDirectory+"\filterPack64bit.exe /passive /norestart"
    Invoke-Expression $install
    Start-Sleep -Seconds 10
    $install = $prereqDirectory+"\filterpack2010sp1.exe /passive /norestart"
    Invoke-Expression $install

    Start-Sleep -Seconds 6


    #Installs Equallogic Host Tools in the default directory 
    #***** WARNING CAUSES RESTART *****
    $install = $prereqDirectory+"\Setup64.exe /s /v/qn /V'/q ADDLOCAL=ALL'"
    Invoke-Expression $install

 That is it for the Prerequisites. Next up we need to configure the storage.