Tuesday, September 12, 2017

Office 365 Mailbox Statistics

Ok, I have run into this so many times, I don't think I am the only one that has been having this issue. When you have a tenant with thousands of mailboxes, getting information on the mailboxes using PowerShell will almost certainly timeout in the middle.

To avoid this, I have written a script that will cut the mailboxes up into blocks of 1000 (by default), you can change this via command line. It will then disconnect and re-connect again to help avoid the connection time-out.

v.0.1 - 2017-09-13 - Get-MailboxRecursive.v.0.1.zip

Tuesday, July 4, 2017

The dreaded DCOM error

This one took weeks from me to figure out, and a little help from our friends at Microsoft. After upgrading a customer's SBA fron 2013 to SfB (and following the correct process):
  1. Move users to Front-End
  2. Remove SBA from topology
  3. Add SBA back into topology with the same name but under the SfB node
  4. Re-install SBA software using 2015 image
  5. Move users back to SBA
Number five is where the issue happened; the users would not move back with a DCOM error:

Interestingly enough, the error in the event log is even more confusing, talking about RoutingGroup already assigned to a different pool (EventID:32209):

Since this is a weird error, the fix will have to be even more weird; this fix is from MS internal documentation :-) (DISCLAIMER: I take no responsibility for doing this on your own environment)
You will need to run the below command to find the users that have a conflicting routing group ID with the one in the Error message:
(Get-CsPool FE01.contoso.com).Computers | `
    % {Sqlcmd.exe -E -S $_\rtclocal -d rtc -Q `
    "select UserAtHost,* from dbo.RoutingGroupAssignment as rga `
    inner join dbo.ServiceCluster as sc on (sc.ServiceClusterId = rga.ServiceClusterId) `
    inner join dbo.ServiceAssignment as sa on (sa.ServiceTagId = sc.ServiceTagId) `
    inner join dbo.Pool as p on (p.PoolId = sa.UscClusterId) `
    inner join dbo.ResourceDirectory as ResD on (ResD.RoutingGroupId = rga.RoutingGroupId) `
    inner join Resource as Res on (Res.ResourceId = ResD.ResourceId) `
    where rga.RoutingGroupName = '<BAD ROUTING GROUP ID>'" -W -s "," -o $_-dumpuserinRG.csv}

The output file will have several users for that routing group ID that are considered "defective"; you will need to run the next command from the RTC database on ALL FE servers in the pool:
use rtc
exec [RtcDeleteResource] 'user@domain.com'

Rinse and Repeat ... for all Routing Group IDs that show up in the error message.
Now the move user works !!!

Tuesday, April 4, 2017

Running Sonus SWe Lite "To-Go"

Finally, the Sonus SWe Lite is out, and its exciting times. This is a great VM to use in your environment, but it also means that you can have your very own SBC to test configs, and play with any time you like.

If you are like me, I use Oracle VirtualBox for all my VMs on my machine. I am not going to go into the reasoning as to why I use VirtualBox, I am sure many out there can explain it better than I can.

However, the SWe Lite VM only comes in 3 flavours, Hyper-V, VMWare, and KVM hypervisors. I took the VMWare package and imported it into VirtualBox, but it failed straight off the bat. After several trials, I have finally found the tweaks to make this work...

First, create your own virtual machine, and do not import the OVF (or OVA) file...

After creating the VM (with no disks attached); copy the VMDK files from the OVA file to their new home...

Next attach the disks to the VM using the Oracle VBox GUI (or the CLI if you like that sort of thing)...

Now for the trick that took me a few hours to figure out. You need to have 5 NICs and not 4 (the maximum you can see in the GUI). The only way to do this, is via the command line interface

N.B. If you are feeling brave, you can add it manually by editing the vbox file (Yes ... it says don't edit it .. but you can .. as long as you have VBox closed while you do it). Just in case you are, here is a screenshot of what mine looks like now...

 Once you have set this up correctly, you should now see in your GUI, the 5 interfaces...

Now you are ready to start the SWe Lite and configure the SBC. I recommend you have a read of Greig's well written post on the subject.

Tuesday, March 21, 2017

Upload AD Photos to Office 365

So, an interesting issue I came across the other day. My customer wanted to copy all photos from AD to Office 365. Since I hate doing manual labor, or leaving it to each user to re-upload their pictures, I came up with this simple script.

All you have to do is enter your Office 365 admin credentials into the script, and run it from a Domain Admin account within your environment.

# Set Credentials
$Username = "admin@tenant.onmicrosoft.com"
$Password = ConvertTo-SecureString 'MyPassword' -AsPlainText -Force
$UserCredential = New-Object System.Management.Automation.PSCredential $Username, $Password

#Connect to O365 Exchange Online
$ConnectionURI = "https://outlook.office365.com/powershell-liveid/?proxymethod=rps"
$EXSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionURI -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $EXSession -AllowClobber

#Get Mailboxes
$Mailboxes = (Get-MailBox -ResultSize Unlimited |?{$_.IsDirSynced -eq "True"})

foreach($Mailbox in $Mailboxes){
  $ADPhoto = $Null
  $ADPhoto = (Get-AdUser -Identity $Mailbox.Alias -Properties thumbnailPhoto).thumbnailPhoto
  If($ADPhoto.Length -ne 0){
    Write-Host -ForegroundColor Green "Uploading Picture for $($Mailbox.Name)"
    Set-UserPhoto -Identity $Mailbox.Alias -PictureData ([byte[]]$ADPhoto) -Confirm:$False

Remove-PSSession $EXSession

Please let me know if you find a better way of doing this.

P.S. don't worry about the errors, as I have not put any error checking into this script.

Monday, February 6, 2017

Office 365 Wizards

I have recently been looking at the different wizards that Microsoft provide in their Office 365 tenancy, and thought it might help some people to see them all in one place...

If anyone finds any discrepancies or new ones that I haven't added, please let me know.

Tuesday, August 2, 2016

Moving from On-Premises to Skype for Business Online

This is a gotcha which took me two days to figure out. I was moving a customer from a broken Skype for Business on-premises to O365 Skype for Business Online.

Why go through the pain of hybrid, if the users never used the system in the first place. What I found is there is a lack of documentation on what are the steps to move in a big-bang scenario. So here goes....

  1. Remove all users from your on-prem deployment
  2. Make sure the users are not licensed for Skype for Business Online yet (if they are, remove it)
  3. Make sure that "ALL" msRTCSIP-* attributes are null, and have propagated to all your DCs
  4. Do another directory sync to O365 using your ADDConnect server
  5. Assign License on O365
  6. Test User Connectivity
What got me here was step "3" .. All attributes were Null except for msRTCSIP-DeploymentLocator which was set to "SRV:" ... in a normal deployment this would be good because it means automatically detect the server. In O365 world, this means the user is On-Prem and don't enable them for Skype for Busienss.

Powershell Command to remove it..

Get-ADUser -SearchBase "OU=Users,DC=contoso,DC=local" -Filter * |Set-ADUser -Clear "msRTCSIP-DeploymentLocator"

Sunday, July 17, 2016

Phone Number Mismatch

I have been at many sites where the phone numbers on the AD contact is not the same as what is configured on Lync/SfB (Skype for Business).

Since SfB is the single source of truth when it comes to which number the user will ultimately answer on; I have devised a quick script that will match those two numbers up, and make sure that all AD contacts that have a Lync/SfB account have the correct phone number associated with them.

Hope this helps a few people out there...

P.S. This script can be easily modified to make other changes to contacts as required.

v.0.1 - 2016-07-18 -Invoke-CsNumberMatch.v.0.1.zip