Wednesday, April 26, 2017

Must Run O365 Hybrid Wizard with IE

Today I made the mistake of downloading and attempting to run the Office 365 Hybrid Deployment Wizard by using Firefox. When you do, the app starts to launch and the fails. When you click on the Details button to open the log file, you see this under the error summary:
Deployment and application do not have matching security zones.
Download the app from within IE and no problems.

Link to download the wizard:
UPDATE: Also worth noting that a similar error with the wizard not running occurs if the .application file extension is not associated with Internet Explorer.

Tuesday, April 18, 2017

Script to Synchronize Primary Email Address with UPN

When planning an Office 365 implementation, it is best practice to start by assuming that UPN for signing in to Office 365 should match the user email address. If you don't configure it this way, then users have two separate items (their UPN for signing in and their email address) that look very similar. In many cases users are confused by the similarity.

If you are synchronizing  your on-premises Active Directory with Office 365 (in most cases you do) then you need to set the UPN for the on-premises user accounts with the correct UPN. The UPN from on-premises user accounts is synchronized to Office 365 to create the ID for signing in.

Most organizations are not using the UPN on user accounts for authentication on-premises. The option has been there since Windows 2000, but most organizations still use the domainname\username format for authentication. However, you need to verify if any user accounts are using the UPN for authentication before making this change. At minimum, you should communicate with your application and system administrators to see if they are aware of anything that might use UPNs. If your organization has issued certificates to users, they might be using UPN as the unique identifier for the certificate.

The script below does the following:
  • Obtains a list of all users where the proxyAddresses attribute has a value. This is done so that the result include only user accounts with an Exchange attributes configured.
  • Identifies the primary email address based on the all caps "SMTP:" text.
  • Strips out the "SMTP:" text from the primary SMTP address.
  • If the new UPN and the existing UPN do not match the user account is updated and the change is logged.
The location and name of the log file are configured in $logfile. You need to manually configure this variable and verify that the necessary folders exist.

  
 #Log folder must already exist  
 $logfile = "C:\Scripts\SyncUPN.txt"  
   
 #Adds timestamp to log file  
 Get-Date | Out-File -FilePath $logfile -Append  
   
 #Obtains only users with valid proxyAddresses attribute   
 $users = Get-ADUser -Properties proxyAddresses -Filter {proxyAddresses -like "*"}  
   
 #Prepare variables for processing status  
 $total = $users.count  
 $current = 0  
   
 Foreach ($u in $users) {  
   #Find primary SMTP address for user  
   $primarySMTP = $u.proxyAddresses | Where-Object {$_ -clike "SMTP:*"}  
       
   #Remove "SMTP:" to create the new UPN value  
   $newUPN = $primarySMTP.Substring(5)  
       
   #Set the new UPN value only if required  
   If ($u.UserPrincipalName -ne $newUPN) {  
     $u.DistinguishedName + " Old UPN: " + $u.UserPrincipalName | Out-File -FilePath $logfile -Append  
     $u.DistinguishedName + " New UPN: " + $newUPN | Out-File -FilePath $logfile -Append  
     Set-ADUser $u -UserPrincipalName $newUPN      
   } #end if  
   
   #Processing status  
   $current += 1  
   Write-Progress -Activity "Processing users to update UPN to primary email address" -Status "Progress: $current" -PercentComplete ($current/$total*100)   
        
 } #end foreach  

Script to Remove Old Domains from User Email Addresses

When managing email addresses and domains in Exchange Server, old email addresses are never removed automatically. This is good because it ensures that email addresses on a mailbox are never accidentally lost. However, you may want to clean up old domains or address formats that are no longer in use.

Some common scenarios where you might want to remove an old domain:
  • An SMB deployment of Exchange Server where a .local domain was added as the first domain for email addresses.
  • Old GroupWise addresses are left in place from an older migration.
  • Obsolete domain left over from a company merger many years ago
I often find that obsolete domains are identified when I run IDFix as part of preparing to migrate to Office 365. To simplify the removal of obsolete domains, I have created the following script.

A few things to note:
  • You need to set $RemovePattern to identify the domain to be removed. Any email addresses matching this pattern will be removed from proxyAddresses attribute in Active Directory objects.
  • The script uses Get-ADObject rather than Get-ADUser to make sure that the domain is removed from distribution groups too.
  • This version of the script is capable of removing multiple instances of a matching email address. So, if a user has several email addresses in the old domain, all of them are removed.
  • At the end of the script, I use Write-Progress to display a status bar. It's not necessary, but if there is a large number of users it's nice to see activity on the screen instead of just waiting and hoping it's doing something.

 #This pattern is used to match the email addresses being removed.  
 #Test that this pattern finds the correct users and email addresses  
 #before running this script.  
 #Example: $pattern = "smtp:*@olddomain.com"  
 $RemovePattern = "smtp:*@olddomain.local"  
   
 Import-Module ActiveDirectory #only required for 2008 R2  
   
 #Get the users that have an email address that matches the pattern  
 Clear-Host  
 Write-Host "Querying objects...This may take a moment"  
 Write-Host ""  
 $objects = Get-ADObject -Filter {ProxyAddresses -like $RemovePattern} -Properties ProxyAddresses  
   
 #Identify address being removed from first user for warning  
 [String]$proxyexample = $objects[0].proxyaddresses -like $RemovePattern  
   
 #Display warning and get confirmation  
 Write-Host "You are going to remove email addresses that match the following pattern:"  
 Write-Host -ForegroundColor Red "$RemovePattern"  
 Write-Host ""  
 Write-Host "This is an example from the first object:"  
 Write-Host -ForegroundColor Red "$proxyexample"  
 Write-Host ""  
 Write-Host "This will modify $($objects.count) objects"  
 Write-Host ""  
   
 $confirm = Read-Host "Enter Y to continue"  
 If ($confirm -ne "Y") {Break}  
   
 #Prepare variables for processing status  
 $total = $objects.count  
 $current = 0  
   
 #Processing users to remove addresses  
 Foreach ($o in $objects) {  
     
   #Build list of addresses to remove for object  
   #required because there might be multiple that match  
   $proxy= New-Object System.Collections.ArrayList  
   
   Foreach ($a in ($o.ProxyAddresses)) {  
     If ($a -like $RemovePattern) {  
       $proxy.add($a) | Out-Null  
     } #end if  
   } #end foreach  
     
   #Remove each bad address  
   Foreach ($p in $proxy) {  
     Set-ADObject $o -Remove @{'proxyAddresses'=$p}  
   }  
     
   #Pause  
   
   #Processing status  
   $current += 1  
   Write-Progress -Activity "Removing email addresses that match pattern" -Status "Progress: $current" -PercentComplete ($current/$total*100)   
 } #end foreach  

Thursday, April 13, 2017

Change All UPNs in a Domain

I needed to update all UPNs in a domain today. It was pretty quick to figure out, but here is one line to take care of it for you.

Get-ADUser -Filter * | ForEach-Object { Set-ADUser $_ -UserPrincipalName ($_.UserPrincipalName).Replace("OldDomain","NewDomain")}
Remember to make the pattern in the OldDomain unique enough that you don't accidentally change things you don't intend to. For example, if you are changing from a .local domain in the UPN to a .com, make sure that you replace ".local" and not "local" on the off chance one of the user IDs includes "local" in the name.

If there are any user accounts without a UPN, then an error is generated for those accounts. My domain had 4 accounts without a UPN:
  • krbtgt - default account used for kerberos
  • IWAM_ServerName - Old IIS account from Windows 2003
  • IUSR_ServerName - Old IIS account from Windows 2003
  • support_XXXXXXX - Used by Help and Support service

Suppress Results when Adding Items to an ArrayList

I ran into a mildly annoying feature when adding items to an array list when using PowerShell today. An array list is an expandable array of items with better performance than a normal array when working with large data sets.

Each time I added an item to the array list, it echoed back the index number of the list item. When I added the first item in the list, the number 0 was displayed on the screen. Adding a second item would echo back the number 1. For example:
$proxylist.add($a)
0

I would prefer my script to be silent when running except when there is data that I want to display. However, there is no option obviously available for that purpose. Instead, you need to redirect the output to $null. There are a few ways to do this and any one will work:
$proxylist.add($a) > $null
$proxylist.add($a) | Out-Null
[void]$proxylist.add($a)

Sunday, April 2, 2017

Dell Open Manage System Administrator Hangs (or Unavailable)

Just ran into an issue on Dell servers using the Dell Open Manage System Administrator software. This software runs on the server to let you see hardware details such as failed components and RAID configuration.

My first issue was when running the System Administrator icon from the desktop. This icon opens up and web page to access System Administrator. However, when Internet Explorer was launched, it came up with the error:
This page can't be displayed
So, I did the standard stuff:
  • restart services
  • verify DNS resolution
  • verify port 1311 is not blocked by firewalls and is listening
Everything looked good, but it wasn't working. One person on a discussion group indicated that they found it was because the older versions of System Administrator used older encryption algorithms for TLS and so the browser was blocking connectivity.

I attempted to resolve it first by updating the existing installation of Server Administrator. This changed the problem to hanging while trying to access the app, but didn't fix it.

The final fix was to remove older versions of System Administrator and install the latest version fresh. It seems that upgrading kept some older incorrect settings. The new install wiped out the older settings and all was good.

So, if Server Administrator is reporting "This page can't be displayed" or hanging when you attempt to access it, try an uninstall and reinstall. You don't need to reboot.