Hybrid Modern Public Folders not working for some users

November 4, 2016 Comments off

Hey! Ran into a strange issue where certain users were not able to access modern public folders on-premise and some users had no issues at all.
The users that had no issues were users that had a mailbox on-premise and then later migrated to the cloud.
The users that had issues were users that were created via the New-RemoteMailbox PowerShell cmdlet.

I was familiar with this issue on Legacy Public Folders but not on Modern Public Folders.

The fix for Legacy Public Folders is that it’s missing the cloud LegacyExchangeDN as an X500 address on-premise
Solution in a simple 1 liner PowerShell script:

Get-Mailbox user@domain.com | foreach {Set-ADUser -Identity $_.Alias -Add @{Proxyaddresses="X500:"+$_.LegacyExchangeDN}}

So after some digging around and talking to the product engineering team and other peers we came to this conclusion:

The issue for the Modern Public Folders is that it’s missing the ExchangeGUID attribute. And how O365 does a lookup for the modern public folders on-premise.
This seems to have been fixed in Exchange 2013 SP1 CU14 (CU 13 and below are still affected) Additionally there were Free/Busy issues as well due to it looking for a non-existing ExchangeGUID.

So there are two solutions here either upgrade all your Exchange 2013 servers to CU14 or run the following PowerShell cmdlet to add the ExchangeGUID property to the users:

$cred = get-credential
$session = New-PSsession -configurationname microsoft.exchange -connectionuri https://outlook.office365.com/powershell -allowredirection -authentication basic -credential $cred -verbose
Import-PSSession $Session -Prefix EXO
$formatenumerationlimit = -1

Get-RemoteMailbox -ResultSize Unlimited -filter {ExchangeGuid -eq "00000000-0000-0000-0000-000000000000"} | foreach {Get-EXOMailbox -Identity $_.Alias} | foreach {Set-RemoteMailbox -Identity $_.Alias -ExchangeGuid $_.ExchangeGuid}

Or if you don’t like one liners and like an output into CSV:

$cred = get-credential
$session = New-PSsession -configurationname microsoft.exchange -connectionuri https://outlook.office365.com/powershell -allowredirection -authentication basic -credential $cred -verbose
Import-PSSession $Session -Prefix EXO
$formatenumerationlimit = -1

Get-RemoteMailbox -ResultSize Unlimited -filter {ExchangeGuid -eq "00000000-0000-0000-0000-000000000000"} | Export-CSV C:\temp\RemoteMailboxesWithNoGUIDS.csv
$i = Import-CSV C:\temp\RemoteMailboxesWithNoGUIDS.csv
$i | foreach {Get-EXOMailbox -Identity $_.Alias} | foreach {Set-RemoteMailbox -Identity $_.Alias -ExchangeGuid $_.ExchangeGuid}

Advertisements
Categories: Microsoft, Office 365

How to find all the ADFS servers in your environment and run diagnostics against them

July 1, 2016 Comments off

Hey everyone!

It has been a hot minute since I’ve posted something here huh?! Life has been busy and that’s a good thing 🙂 Hope you all are well too!

I’ve been real busy here at Microsoft, talking to customers and fixing their issues, most of which I should have blogged about, but hind sight is 20/20 and a bunch of other folks beat me to the punch, so on to the matter at hand.

How to find all the ADFS servers in your environment and run diagnostics against them.

I am by no means a PowerShell pro, but practice makes perfect and this is the first part of a script that I’m really proud of that I made since it fixed a real world issue I and many co-workers in Exchange Online land were dealing with.

In the blurb below it will do the following:

  1. Ask for your domain administrator credentials
  2. Grab your logon server from the user that you’re logged on with
  3. Create a session to that logon server (assuming WinRM is enabled on it, if you see a sea of red after this part, do a “WinRM qc” on that server)
  4. Set variable for finding all servers in your environment
  5. Set variable for finding all ADFS servers
  6. Executing variable $adfsservers to output your ADFS servers (excluding your WAP servers since those should be in your DMZ, right?!)


$cred = Get-Credential
$dc = $env:Logonserver -replace "\\", ""
$s = New-PSSession -ComputerName $dc -Credential $cred
Invoke-Command -Session $s {Import-Module ActiveDirectory}
Import-PSSession -Session $s -Module ActiveDirectory -Prefix dc
$services = "adfssrv","MSSQL$MICROSOFT%"
$servers = Get-dcADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))"
$value = 1
if ($servers.count -lt "100") {$adfsservers = ForEach-Object {Get-WmiObject Win32_Service -ComputerName $servers.dnshostname -Filter "Name Like 'adfssrv'" -Credential $cred | select-object PSComputerName -ExpandProperty PSComputerName}}`
else {$adfsservers = @()
do {
$input = (Read-Host "Please enter ADFS server #$value (enter if last one)")
if ($input -ne '') {$adfsservers += $input}
$value++
}
until ($input -eq '')}

$adfsservers

 

Ok great! Now that we have this information what else can we do with it? Well we can run the ADFS diagnostics script created by the ADFS team against it.

One problem, we would have to login to each ADFS server individually and run the script. How 90’s… So since we’re messing around in PowerShell, let’s leverage it!

Building on the script above we’re going to add the following:

$services = "adfssrv","MSSQL$MICROSOFT%"
$services | ForEach-Object {Get-WmiObject Win32_Service -ComputerName $servers.dnshostname -Filter "Name Like '$_'" -Credential $cred | Format-Table Name, DisplayName, State, StartMode, StartName, SystemName -auto}
$ips = $adfsservers | foreach {Resolve-DNSName $_ | Select-Object IPAddress -ExpandProperty IPAddress}
$adfssrvs = $adfsservers | ForEach {Get-dcADComputer "$_" | Select-Object DnsHostName -ExpandProperty DnsHostName}
$adfssessions = New-PSSession -ComputerName $adfssrvs -Credential $cred
Start-TranScript c:\temp\ADFS-TESTS.TXT -force
Write-host Number of ADFS Servers: ($adfsservers).count
$adfssrvs
$f = "c:\temp\ADFSDiagnostics.psm1"
$c = Get-Content $f
icm -Session $adfssessions -ScriptBlock {mkdir c:\temp -force -erroraction silentlycontinue}
icm -Session $adfssessions -ScriptBlock {param($filename,$contents) `
Set-Content -Path $filename -Value $contents} -ArgumentList $f,$c
icm -Session $adfssessions -ScriptBlock {
C:
cd \temp
Import-Module .\ADFSDiagnostics.psm1
Write-Host -foregroundcolor "Green" Running cmdlet Get-AdfsSystemInformation on $env:computername
Get-AdfsSystemInformation
Write-Host -foregroundcolor "Green" Running cmdlet Get-AdfsServerConfiguration on $env:computername
Get-AdfsServerConfiguration
Write-Host -foregroundcolor "Green" Running cmdlet Test-AdfsServerHealth on $env:computername
Test-AdfsServerHealth | ft Name,Result -AutoSize
Write-Host -foregroundcolor "Green" Running cmdlet Test-AdfsServerHealth showing failures on $env:computername
Test-AdfsServerHealth | where {$_.Result -eq "Fail"} | fl
}

To give a little bit of explanation of what the blurb above does:

  1. Set variables for the IP addresses of the ADFS servers, variables for the ADFS servers FQDN, variables for creating a PSsession to all ADFS servers at once.
  2. Set variables for the ADFS service and Windows Internal Database service and check their status on the ADFS servers.
  3. Copy the ADFSDiagnostics.psm1 from your local c:\temp to the remote session’s c:\temp
  4. Execute a number of diagnostics on the remote server and output them on the screen.


How to find all the ADFS servers in your environment and run diagnostics against them.

But wait, we have more! There are more tests that we can kick off, we’ll need to run these on the local machine though since it leverages the invoke-webrequest cmdlet which needs Internet Explorer (if IE has never been opened it will error out, just an FYI)

In order to get the next part working I had to make use of Jeremy Jameson awesome hostnames scripts. I crammed all the .ps1 files into a .psm1 and turned them into functions.

Some more explanation on the code below:

  1. We ask for your ADFS endpoint name
  2. We import both .psm1 files
  3. Foreach ADFS server IP address we add it the hosts file one at a time and run code against it and running additional certificate checks.
  4. We do this because there’s no tool out there yet that checks against internal ADFS servers, only external host names via the SSO test on testconnectivity.microsoft.com
  5. After the certificate checks, it will check for any services on the ADFS servers marked in an AUTO state that’s currently in a STOPPED state and attempt to start them.


$adfs = Read-Host -Prompt 'Please type in your adfs endpoint hostname (i.e. adfs.contoso.com)'
Import-Module .\ADFSDiagnostics.psm1
Import-Module .\Hostnames.psm1
foreach ($ip in $ips)
{
Add-Hostnames $ip $adfs
Test-AdfsServerToken -federationServer $adfs -appliesTo urn:federation:MicrosoftOnline
Test-AdfsServerToken -federationServer $adfs -appliesTo urn:federation:MicrosoftOnline -credential $cred
$token = [Xml](Test-AdfsServerToken -federationServer $adfs -appliesTo urn:federation:MicrosoftOnline)
$token.Envelope.Body.RequestSecurityTokenResponse.RequestedSecurityToken.Assertion.AttributeStatement.Attribute | ft
Remove-Hostnames $adfs}
Write-Host -foregroundcolor "Green" Starting services marked as AUTO that are now marked as STOPPED
icm -Session $adfssessions -ScriptBlock {get-wmiobject win32_service | where-object {$_.Startmode -eq "auto" -and $_.State -ne "running"}| Start-Service -Verbose}

Stop-TranScript
Get-PSSession | Remove-PSSession

You can download the entire 3 piece script from https://github.com/michaeldeblok/Get-ADFSservers

Once downloaded place them in your c:\temp folder.
Keep in mind that you need to run PowerShell as an Administrator.
Per the ADFSDiagnostics.psm1 script you will need to have PowerShell v4 on all the ADFS servers prior to running the diagnostics script.
The diagnostics script works with ADFS versions 2.0, 2.1 and 3.0

New IOS issue on Exchange Active Sync

April 22, 2013 5 comments

iOS device users locked out of Active Directory accounts

When a user changes their Active Directory account password, iOS devices prompt for the new password. The user enters in the new password. However, the device does NOT use the new password and continues to use the OLD password, which causes the account to be locked out.

 

STATUS

Apple is aware of this issue, and customers should open an Enterprise level support case with Apple to pursue a fix in iOS.

 

WORKAROUND

On the device, open the Settings panel and edit the profile to force the new password to be used by the iOS device on the next connection.

 

Microsoft’s main Known ActiveSync Issues KB (http://support.microsoft.com/kb/2563324) has been updated to include this issue as issue 2.10.

Exchange Server high cpu usage

April 4, 2013 2 comments

Ever notice that your w3wp.exe is using up all your cpu and pegging at above 90%-99%?
Good chances that iOS devices are hammering it like crazy.
After dealing with this a number of times (thanks Apple) here is a little trick to quarantine device until they are remediated.

in the Exchange Management Shell type the following:

New-ActiveSyncDeviceAccessRule -QueryString “lOS 6.1 10B141” -Characteristic DeviceOS -AccessLevel Quarantine
New-ActiveSyncDeviceAccessRule -QueryString “los 6.1 10142” -Characteristic DeviceOS -AccessLevel Quarantine
New-ActiveSyncDeviceAccessRule -QueryString “lOS 6.1 108143” -Characteristic DeviceOS -AccessLevel Quarantine
New-ActiveSyncDeviceAccessRule -QueryString “los 6.1 10B144” -Characteristic DeviceOS -AccessLevel Quarantine
New-ActiveSyncDeviceAccessRule -QueryString “lOS 6.1.1 108145” -Characteristic DeviceOS -AccessLevel Quarantine

This will effectively put those versions into Quarantine and take them out automatically once they upgrade to a newer firmware version.

Also setting up a recycling schedule or certain limits in IIS before it recycles would also be a good thing to do after this.

 

Another cause could be the following:

W3wp.exe process consumes excessive CPU and memory resources on an Exchange Client Access server after you apply Update Rollup 5 version 2 for Exchange Server 2010 SP2 which is re-mediated with Exchange SP3

 

 

Hide federated user from GAL on Office 365 with no Exchange server On-premises

January 26, 2012 2 comments

While working on a clients environment a RFC came in to hide certain users from the Global Address List as they were no longer working for the company.
Which brings us to a minor set back within full cloud environments; since there was no local exchange server how do I change the attribute for hiding a user?

First thing I tried off the bat was since I do have an Exchange environment running, is add their Exchange Online environment into my management console.
Which works perfectly and if they weren’t federated users (dirsync running locally for SSO) I would not have had this error:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

So this brings me to a challenge on how to solve this, which is actually quite simple, I’ll break it down into 8 simple steps for you:

1. Logon to a local DC and make sure you are an Enterprise & Schema Admin.
2. On the same server insert the Exchange 2010 CD (or download Exchange 2010 SP2 and unpack it).
3. Open up a CMD prompt and browse to the CD/SP2 directory.
4. Extend the schema by executing the following command: setup.exe /ps (if this is not sufficient you can also do “setup.exe /PrepareAD” and “setup.exe /pl“)
5. After this is done open up adsiedit.msc and connect to the “Default Nameing Context”
6. Drill down to the user that needs to be hidden and select properties.
7. Find the Attribute called “MsExchHideFromAddressLists” and set it to “TRUE” (if the Attribute is not there yet, wait a few minutes as it may still be being populated/synced over other DC’s)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
8. After the setting is made, connect to your dirsync server and start the DirSyncConfigShell.psc1 to force a manual sync by executing the command “Start-OnlineCoexistenceSync

After this you will find that the user is not longer visible in the GAL.

Good luck!

Getting Lync mobile to work on your cell phone with Office 365

December 12, 2011 Comments off

Microsoft has released the new Lync Mobile Client for IPhone, iPad and Windows Phone!

Here’s how to make it work with Office 365:

You need to add two CNAME entries:
sip.YOURDOMAIN points to sipdir.online.lync.com and
lyncdiscover.YOURDOMAIN points to webdir.online.lync.com

replace YOURDOMAIN with your own domain and it will work.

Good luck!

Categories: Uncategorized

Migrating from Google Apps to Office 365 in 6 steps

August 14, 2011 3 comments

Hi everybody!

I would like to start off with saying that I will keep this as straightforward as I can, I do not want to get into all the details of pro’s and con’s of Google Apps or Office 365, there are many other sites that can help you out with this.

These are my 6 steps for migrating from Google Apps to Office 365:
Step 1 – Sign up for the trial
Step 2 – Add a domain
Step 3 – Add users
Step 4 – Email Migration
Step 5 – User setup
Step 6 – Finalizing the migration process

There will be a followup on how transfer your Google Docs to SharePoint Online in the near future as well.