Wednesday, January 24, 2018

Exchange - Changing from ForwardingAddress to ForwardingSMTPAddress for multiple mailboxes

Whoa, has it really been almost TWO YEARS since I've posted?  Well, if you still follow over here, be sure to follow me on twitter at https://twitter.com/chrislehratx - I tend to share out articles, blogs, and oneliners related to the Microsoft Exchange and/or Skype products over there.  Far more frequent updates than here.  But today, my script went from a one-liner to a multiliner, so I figured I would blog.

I had a weird need arise where users that were using ForwardingAddress were moved to the cloud, and the mail contact object that was selected for them was NOT synchronized to Azure AD, so it got stripped from the mailbox configuration.  The fix was to reference the mail contact per mailbox, get the SMTP address and then post a set-mailbox command with this data.

Script below - enjoy.

A few notes:

  1. In the get-mailbox, you can change the OU to a | where { $_.something -match ""} in order to capture your target list of mailboxes for your own situation.  I happened to have them all in an OU together.
  2. In the set-mailbox, this currently has a -whatif - you should NEVER ever do bulk AD updates without this first, so I left it in the script.

 # Get all the target mailboxes and assign to $x - change below to match your target audience as needed!
$x = get-mailbox -resultsize unlimited -organizationalunit "OU=TargetOU,OU=Users,OU=Mailboxes,DC=contoso,DC=com"
foreach ($mailbox in $x) {
# capture their SMTP address in the contact in a string
$SMTPforwardingaddress = ((get-mailcontact -Identity (((get-mailbox $mailbox).forwardingaddress).distinguishedname)).emailaddresses | where { ($_.isprimaryaddress -eq $true) -and ( $_.prefixstring -eq "SMTP")}).addressstring
# Null out their forwarding and replace with SMTPforwarding
write-host "Setting $mailbox to forward to $SMTPForwardingaddress"
set-mailbox -identity $mailbox -whatif -forwardingaddress $null -ForwardingSmtpAddress $SMTPforwardingaddress
}


If you like to understand Shell that one beast mode line broken out:

$SMTPforwardingaddress = ((get-mailcontact -Identity 
(((get-mailbox $mailbox).forwardingaddress).distinguishedname)).emailaddresses 


This does a get-mailbox, references the existing forwarding address object's DN, then the EmailAddresses, which is a ProxyAddresses format

| where { ($_.isprimaryaddress -eq $true) -and ( $_.prefixstring -eq "SMTP")}).addressstring


This captures what should be THE ONE address that is the primary and SMTP address (as opposed to X400)

And then once we have the string, the set-mailbox command nulls the ForwardingAddress and sets the string for ForwardingSMTPAddress

Finally - here's what it looks like (heavily redacted) when run (at least with -whatif still in there!)

Wednesday, March 16, 2016

Configuring Skype for Business CDR and QoE Reporting services to be highly available

Frequently I see customers successfully implement CDR and QoE reporting on two SQL reporting servers, but find that their reporting services web URL only works on the SQL server that is the primary node for these databases.   When you attempt a connection to the SQL Reporting server that the databases are not mounted on, you receive an error similar to the below:



An error has occurred during report processing. (rsProcessingAborted)
Cannot create a connection to data source 'CDRDB'. (rsErrorOpeningConnection)
For more information about this error navigate to the report server on the local server machine, or enable remote errors


In order to make Reporting services truly highly available, you need to complete the steps below from this Microsoft TechNet article Associating Monitoring Reports with a mirror database in Skype for Business Server 2015.

"To get Monitoring Reports to automatically failover to the mirror database, you must add the mirror database as a "failover partner" to the two databases that are used by Monitoring Reports (one database for Call Detail Record data, and the other for Quality of Experience (QoE) data). (Note that this step should be performed after you have installed Monitoring Reports.) You can add the failover partner information by manually editing the connection string values used by these two databases."

So on each http://SQLreportingServer01/Reports URL, click into the Reporting Instance:


Click into Reports_Content:


Click into CDRDB:


In the "Connection String" dialog you will see something similar to:
data source=(local);initial catalog=LcsCDR

Edit this content to add the following (in bold)
data source=(local);Failover Partner=SQLREportNode02;initial catalog=LcsCDR

If you had a configuration where you specified an instance name, this would look more like this:
data source=(local\CDRReporting);Failover Partner=SQLREportNode02\CDRReporting;initial catalog=LcsCDR


Note:  If you have security set to use credential stored securely, you will need to retype the password to make this change!

Once you complete these tasks for the CDRDB, repeat these steps on the QMSDB.

Once you complete these tasks on both CDRDB and QMSDB, repeat the process on your second SQL reporting node.

Once these tasks are completed, both of your reporting URLs should work regardless of where your S4B backend SQL CDR/QoE databases are mounted.


Monday, November 09, 2015

Find all Exchange mailboxes missing an Office 365 license in one line of code



Hybrid scenario – customer moved mailboxes and didn’t license them.

Pre-req of MSOL and EXO shell loaded in the same instance - super easy with my script!

$msol = get-msoluser -all | where { $_.isLicensed -eq $true }; $mbox = get-mailbox -ResultSize 5555555; Compare-Object -ReferenceObject $msol.userprincipalname -DifferenceObject $mbox.userprincipalname

Output options:

-excludedifferent
-includeequal

See more on Compare-Object here, here and here.

Sample output (neither output option shows just the delta items)

InputObject                                SideIndicator
-----------                                -------------
user1@contoso.com                               =>
user2@contoso.com                               =>
user3@contoso.com                               =>

Wednesday, October 28, 2015

Setting permissions for AADSync and password write-back

I love scripting things to save time, so when I found this article a while back on using PowerShell to configure the AADSync service account permissions, I bookmarked it, retweeted it and used it several times since then.

Today, I implemented Password Writeback, and the article only had two permissions set for it.   In testing, I found users received an error, but their password was still being reset correctly.

In the AADSync Event log, I noticed there was two failures followed by a success.  The error looked like this:

An unexpected error has occurred during a password set operation.
 "ERR_: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(58): Failed getting registry value 'ADMADoNormalization', 0x2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(59): 0x80070002 (The system cannot find the file specified.): Win32 API failure: 2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(114): 0x80070002 (The system cannot find the file specified.)
ERR_: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(58): Failed getting registry value 'ADMARecursiveUserDelete', 0x2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(59): 0x80070002 (The system cannot find the file specified.): Win32 API failure: 2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(114): 0x80070002 (The system cannot find the file specified.)
ERR_: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(58): Failed getting registry value 'ADMARecursiveComputerDelete', 0x2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(59): 0x80070002 (The system cannot find the file specified.): Win32 API failure: 2
BAIL: MMS(3188): D:\bt\40256\sources\dev\Sync\ma\shared\inc\MAUtils.h(114): 0x80070002 (The system cannot find the file specified.)
ERR_: MMS(3188): ..\session.cpp(2114): Asynchronous modify result (dn=) failed
WARNING: MMS(3188): ..\session.cpp(2115): Asynchronous modify result (dn=) failed
BAIL: MMS(3188): ..\session.cpp(2121): 0x80070005 (Access is denied.)
ERR_: MMS(3188): admaexport.cpp(4253): The password change operation failed: ERR_: MMS(3188): admaexport.cpp(4259): Insufficient Rights 0x32
BAIL: MMS(3188): admaexport.cpp(3516): 0x80004005 (Unspecified error)
ERR_: MMS(3188): ..\ma.cpp(8322): ExportPasswordSet failed with 0x80004005
Azure AD Sync 1.0.0494.0501"


This turned up a good TechNet forum post where someone highlighted the exact issue.  According to the TechNet article, two additional permissions are required.  I have documented these below, and have commented on the source article to add them (and added the powershell to technet) - hopefully more people can find the help they need now.

So for password writeback, two additional invocations of DSACLS are required:

$DN = "DC=domain,DC=com"
$Account = "domain\aadsync"

$cmd = "dsacls '$DN' /I:S /G '`"$Account`":CA;`"Reset Password`";user'"
Invoke-Expression $cmd
$cmd = "dsacls '$DN' /I:S /G '`"$Account`":CA;`"Change Password`";user'"
Invoke-Expression $cmd
$cmd = "dsacls '$DN' /I:S /G '`"$Account`":WP;pwdLastSet;user'"
Invoke-Expression $cmd
$cmd = "dsacls '$DN' /I:S /G '`"$Account`":WP;lockoutTime;user'"
Invoke-Expression $cmd


To check that the permissions are set:
dsacls “\\dc1.domain.com\DC=domain,DC=com” | findstr serviceaccountname

You should see something similar to this:

Thursday, October 15, 2015

Skype for Business for iOS released

This week, Microsoft announced the availability of the Skype for Business client as an update to the existing Lync 2013 client in the app store.

There has been a lot of feedback on social media regarding some of the changes and the issues being found so I have decided to try and collect some and post workarounds here.

  1. I updated my apps, but I don't see Skype for Business.  Yes, for some reason it's named "Business" - not sure if this is a nod to the Microsoft Garage apps of "Invite" and "Send" but it has made for some humor in app sorting.
  2. Dial pad preloads all numbers with +1 in the US.  If you go to the dial pad, it will prefill the e164 prefix for your region as determined by your device's regional settings.  If I change my location to the UK, this is +44.  However this is something many admins don't like.  We tend to account for our users dialing patterns in our dial plans and by adding these in the client we now have to instruct users to expect or remove this.  It's generally just an unwelcome change in behavior.
  3. Crashing on joining meetings.  Many users reporting this.  If you click the icon on the left or the text of your "upcoming meetings" the client crashes.  Workaround - click the icon on the RIGHT of the meeting and it works!  Not sure if this is a UI bug, but had many reports of crashing on joining.
If you or your organization is not able to use MDM or advise your users to not upgrade until some of these issues are addressed.  Another option might be to block the S4B iOS client using a client version policy.  Below are the User Agents in use:

UCWA/6.0.0.0 iPhoneLync/6.0.1445.0000
UCWA/6.0.0.0 iPadLync/6.0.1445.0000

Wednesday, October 07, 2015

Porting numbers in Skype for Business Online

Today, Microsoft announced additional preview options in S4B Online.  One of which is number portability.  This is a huge step towards adoption - we can now tell customers we can port existing PSTN numbers to the Microsoft cloud.

Here's how it works:
  1. Log into your Skype for Business Admin portal in office 365
  2. Click on Voice, then "Port Orders (preview)"
  3. Note the text - you will need a list of numbers, 999 maximum per order, your account info, your letter of authorization, and a PIN if applicable.
  4. Click on + to add a new port order
  5. Note the text warning here
    To minimize delay in your transfer:
    - Please remove any features (i.e. Hunt Group) associated with your numbers before submitting your order.
    - Please do not place any new service orders with your current provider.
    - All numbers must be from the same carrier and under the same account.
    - You cannot transfer toll free numbers or numbers used for data (i.e. DSL lines).
    - Make sure the account information matches exactly what your carrier has on record. Mismatched information is the most common cause of errors.
  6. Complete your account info
  7. Enter your phone numbers, one per line - these need to be in E164 format!
  8. Select your transfer date.  Not sure if they will really get it done in 5 days, but that's was the choice I made.
  9. Digitally sign your letter of authorization
  10. Submit your port order!

I will be working on porting some numbers for real sometime very soon, but wanted to get this post up to show how it's done.  I will update this post as we gain more experience.

More technical details are available at the below links:



            Topic title
URL
What is number porting?


Port existing phone numbers over to your organization

What phone service providers are supported for number porting?

What if my phone carrier isn't listed here? 
What to do after you port your phone numbers?

What's the status of my port orders?
How should I enter the phone numbers?
What phone service providers or carriers are supported?
Port order account information
Port order overview
Submitting a service request for number porting