Friday, September 16, 2016

Tips for Microsoft Ignite Attendees

A few years ago the first blog post on this blog was Tips for Teched Attendees. Now that Teched North America is now Microsoft Ignite, we offer an updated list of some helpful tips for Microsoft Ignite Attendees.

Tips for #MSIgnite Attendees 
  1. Take some Chewing gum for the flight. Years ago someone told me about chewing gum during takeoff and landing helps with air pressure in your inner ear (known as airplane ear) when ascending and descending. I always pack some gum in my carry-on just for this purpose.  
  2. Do not to pack too many clothes. You can get free T-shirts from most vendors and some usually have incentives for wearing their shirt on the Expo Floor. You will not have time to wear all the extra clothes if you bring them but you will have room in your bag to take home all the T-shirts you will get.
  3. Bring comfortable shoes (not new shoes) for all the walking you will have to do to get to sessions and meals (breakfast and lunch are provided at Ignite) and maybe back to your hotel.
  4. You will most likely get a backpack as an Ignite Attendee so unless you really like yours or it is a road warrior type or laptop bag, one is not needed.
  5. Bring your cell phone charger(s), portable battery packs and/or power strip. There should be outlets available in sessions in the convention center and in the lounges. If you bring a power strip you can make some new friends as you network in the lounges. 
  6. Try to arrive early for breakfast and lunch times at Ignite. Lines can be long but they move quickly. Vegetarian is included in the regular food offerings this time around. There are separate areas for pre-registered dietary needs only (Vegan, Dairy-Free/Lactose Intolerant, Gluten-Free, Halaal or Kosher).
  7. Plan to arrive for your sessions early. Rooms can fill up for some of the more popular speakers and topics. Try to attend the second session of a topic if there is one available. Use the Schedule Builder to know what will be available. If you are above a 101 level skip those sessions and attend the ones that will be more beneficial to you and your company. Also add multiple sessions to the same timeslot on your schedule, it can help if a session is full and there is only that one for the entire conference.
  8. If you really want to attend the early morning sessions, try not to stay up too late at night. Keep in mind most sessions will be recorded and available later for attendees to download after the conference.
  9. Get to registration early with your final confirmation email(on paper or on your mobile device) and Government Issued ID. In past years, there is a self-checkin process that was really efficient. This year they are offering check-in at the Atlanta Airport and other places including some hotels.
  10. Do NOT lose your badge. This is needed to get into sessions, events and will be scanned by the vendors on the Expo Floor so they can contact you after the show.(it's a business card without walking around with 500 cards).
  11. Use the My Ignite Site . It contains all the latest changes including room swaps, cancellations and other updated information during the conference.
  12. If you are on Twitter, follow the @MS_Ignite Account for great information and find posts from other attendees, vendors and Microsoft Ignite account with the official hashtag #msignite.  Also another helpful account to follow is @TheKrewe and search hashtag #thekrewe to make your Ignite experience better. 
  13. Pack a fleece or light jacket or long sleeved shirt that you can remove when you go outside. The air conditioning units may be on blast in some of the rooms.
  14. Use the Interactive Labs formerly Hands-On Labs. Those are great opportunities to get familiar with the Microsoft products and there usually very helpful staff nearby that can help with technical issues. Add them to your schedule in the Schedule Builder. Tip: Get to these early since they are usually in high demand throughout the conference.
  15. Remember to recycle your unwanted papers etc. from the Ignite backpack. There is usually a recycle station at the booth for THE CODE PROJECT.
  16. Save your wristband for the Ignite Attendee Celebration on Thursday evening. It is usually a tear-off perforated strip on the side of the flyer announcing the Attendee celebration. Do not throw it away without removing the wristband first. You may have to purchase another one.
  17. Schedule some break time to recover from the walking around the convention center and the food. There are plenty of lounge areas at Ignite this year. I'll see you there.
  18. Provide feedback about the sessions you attend using the surveys. Microsoft is listening and you can help shape the next Ignite by just filling out the surveys.
  19. Ice-cream bars come out at around 3 pm. Be on the lookout for the coolers. They disappear fast. There are usually frozen fruit bars available too. A few years ago when Ignite was TechEd, these were not there but Microsoft is bringing them back.
  20. For you coffee and tea drinkers, you should bring a travel mug with you or if you get one as swag from a vendor, you can use that since it will hold more liquid and keep your drink hot longer than the paper cup at the coffee and tea stations.
  21. Put Ignite in your pocket and download the Microsoft Ignite App. It is available for Windows, Android and iOS. Learn more at
Enjoy Microsoft Ignite and go back to your jobs and share what you have learned! Comments are welcomed.

Wednesday, August 17, 2016

5 More Tips for Exchange Server 2013 Administrators

Are you thinking about deploying Exchange Server 2103 or have you already done it? Microsoft released the Exchange Server 2103 Preview  in July 2012 and the Release to Manufacturing (RTM) build for Exchange Server 2013 in October 2012. Exchange Server 2013 is now up to cumulative Update (CU) 13 released in June 2016 at the time of this blog post.  In this blog series, we share some helpful tips that will help you as an Exchange Server 2013 Administrator. Here is a link to the first post titled 5 Tips for Exchange 2013 Administrators. Now on to the next post in the series:"5 More Tips for Exchange Server 2013 Administrators"
5 More Tips for Exchange Server 2013 Administrators
  1. Learn how to search in the Exchange Admin Center
    Searching in the Exchange Admin Center is different than the Exchange Management Console in Exchange 2007. In older versions of Exchange using the Exchange Management Console (EMC) or the Exchange Control Panel (ECP), you were able to find mailboxes when searching by just entering the name or part of the name and you would get results. We published a post on how to search using the Exchange Admin Center so please check that out.

  2. Triple verify that your third party applications work with Exchange 2013.
    This includes Anti-virus exclusions, monitoring and auditing software. This is very important to know as you deploy Exchange 2013. If the vendor does not have a version that supports Exchange 2013 you run the risk of having the product impact your Exchange deployment and cause issues or if you opt not to use it until they do, then you lose the benefits that you purchased the product for in the first place. Either outcome is not what you want. We dealt with McAfee Anti-virus exclusion paths for Exchange directories impacting our Exchange 2013 deployment and until it was addressed we actually suspended migrations while we worked with McAfee, Microsoft and our security team. For more information on Anti-Virus Software in the Operating System on Exchange Servers

  3. Learn how the Exchange Administration Center works in Exchange Server 2103
    In an environment like ours which is a large enterprise, there are thousands of admins that manage user issues like creating mailboxes, distribution groups, Public Folders and adding user photos to name a few. We have created documentation to assist them using the Exchange Administration Center since the new interface is different to how users were managed in Exchange 2007 which is what we migrated from to Exchange 2013.

  4. Learn how Database Availability Groups(DAGs)work
    Database Availability Groups (DAGs) were first introduced in Exchange 2010 and are here to stay. DAGs are a base component of the high availability and site resilience framework built into Exchange 2013. A DAG is a group of up to 16 Mailbox servers that host a set of databases and provides automatic, database-level recovery from failures that affect individual databases, networks, or servers. Any server in a DAG can host a copy of a mailbox database from any other server in the DAG. When a server is added to a DAG, it works with the other servers in the DAG to provide automatic recovery from failures that affect mailbox databases, such as a disk failure or server failure. for more information, reference Database availability groups (DAGs)

  5. Use the tools provided by Microsoft: Microsoft Remote Connectivity Analyzer and the Exchange Server Deployment Assistant
  6. When you are preparing to deploy Exchange, Microsoft has provided resources to help you. The Microsoft Remote Connectivity Analyzer validates External connectivity to your servers and lets Exchange Admins run connectivity diagnostics to test issues with Exchange, Skype for Business/Lync and Office 365. There is also now a Client Testing option and Message Analyzer in the latest version of the tool. Here is a screenshot from

    The Exchange Server Deployment Assistant is a web-based tool that asks you a few questions about your current environment and then generates a custom step-by-step checklist that will help you deploy different versions of Exchange Server for different types of scenarios. Learn more at

BONUS TIP : Do not ignore the cloud.
The cloud has come a long way and should not be ignored in your Exchange 2013 deployment. A hybrid configuration where some user mailboxes are hosted in the cloud and are connected to the others deployed in your data centers is becoming a common scenario. A hybrid configuration provides a seamless look and feel for Exchange in your organization and Exchange Online in Microsoft Office 365. In addition, a hybrid deployment can serve as an intermediate step to moving completely to an Exchange Online organization. Reduced costs, benefits of not maintaining hardware and accessibility from anywhere are some of the factors that make Office 365 appealing to some companies and you may want to take a look at that.

We hope these tips have been helpful in your Exchange 2013 deployments. If you have any thoughts, opinions or comments feel free to share them below.

Tuesday, July 19, 2016

How to run multiple PowerShell commands in c# (including pre-environment commands like set-adserversettings -viewentireforest:$true)

This allows me to create a script in a string with multiple commands, it processes 1 command at a time and then creates a runspace in c# and runs all of the powershell commands. The amount of commands that you could put inline in the string is endless.

<pre lang="C#">string scriptText = @"$pw = convertto-securestring -AsPlainText -Force -String '<password>'; $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist '<domain>\<username>', $pw;  $session = new-pssession -ConfigurationName Microsoft.Exchange -ConnectionUri '<server url>/powershell' -credential $cred; import-pssession $session; Set-ExecutionPolicy bypass -confirm:$false -force; $pic = ([System.IO.File]::ReadAllBytes('" + <picture file name> + "')); set-userphoto -identity <username> -picturedata $pic -domaincontroller '<dc fqdn>' -confirm:$false;";


<pre lang="C#">private string runExchangeShellScript(string scriptText)
            Runspace runspace = RunspaceFactory.CreateRunspace();

            // open it

            // create a pipeline and feed it the script text
            Pipeline pipeline = runspace.CreatePipeline();
            RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
            runSpaceInvoker.Invoke(&quot;Set-ExecutionPolicy Unrestricted&quot;);

            // add an extra command to transform the script output objects into nicely formatted strings
            // remove this line to get the actual objects that the script returns. For example, the script
            // &quot;Get-Process&quot; returns a collection of System.Diagnostics.Process instances.

            // execute the script
            Collection&lt;PSObject&gt; results = null;
                results = pipeline.Invoke();
            catch (Exception ex)
                MessageBox.Show(ex.InnerException + &quot; - &quot; + ex.Message + &quot; - &quot; + ex.Source + &quot; - &quot; + ex.StackTrace + &quot; - &quot; + ex.TargetSite + &quot; - &quot; + ex.Data);
                return &quot;&quot;;

            // close the runspace

            // convert the script result into a single string
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in results)

            // return the results of the script that has
            // now been converted to text
            return stringBuilder.ToString();

Tuesday, February 10, 2015

How to count the number of DC's in your forest and individual domains with PowerShell

For some reason, with all the power of the internets, this answer was nowhere to be easily found.

I needed to be able to count the number of (Domain Controllers) DC's in our forest, and also for a specific domain. It's a simple PowerShell script ... here is what I used


$domains = (Get-ADForest).Domains;

foreach ($domain in $domains)


    Write-Host $domain
    (Get-ADDomain -Identity $domain | select -ExpandProperty ReplicaDirectoryServers).Count;
    Write-Host "";
    $totalCount = $totalCount + (Get-ADDomain -Identity $domain | select -ExpandProperty ReplicaDirectoryServers).Count;

Write-Host "Total domain controller count is: "$totalCount

Friday, January 16, 2015

5 Tips for Exchange Server 2013 Administrators

Are you thinking about deploying Exchange Server 2103 or have you already done it? Microsoft released the Exchange Server 2103 Preview  in July 2012 and the Release to Manufacturing (RTM) build for Exchange Server 2013 in October 2012. Exchange Server 2013 is now up to cumulative Update(CU) 7 released in December 2014.  In this new blog series, we will be sharing some helpful tips that will help you as an Exchange 2013 Administrator.

5 Tips for Exchange Server 2013 Administrators
  1. Learn PowerShell and the Exchange Management Shell.
  2. PowerShell (formerly Monad), a management framework that combines a command line shell with a scripting language. PowerShell has been around since 2006 and is currently up to version 5. Exchange Management Shell (EMS) is an extensible command line interface for Exchange Server Management that sits on top of PowerShell. Learning how to use PowerShell and EMS are important to our jobs as Exchange Server 2013 Administrators. Unlike in Microsoft Exchange Server 2007, where local Windows PowerShell is used, a Windows PowerShell snap-in for Exchange isn't loaded for Exchange 2013. PowerShell connects to the closest Exchange 2013 server using a required component called Windows Remote Management 3.0, performs authentication checks, and then creates a remote session for you to use. There are plenty of resources available online for you to learn more about PowerShell.

  3. Know the hardware Exchange Server 2013 is deployed on.
  4. If you are deploying Exchange Server 2013 at your location on purchased servers, you need to evaluate the following: Memory, CPU and disk space. You will need to purchase Client Access Servers and Mailbox servers. Investing in an Uninterruptible Power Supply (UPS) is highly recommended to allow you to properly shutdown the Exchange servers in case of a power outage.  If you are going with  Exchange Online and Office 365, the data center provides the hardware and will have the ability to scale out and scale up as needed. They will also have UPS for the servers in the data center.

  5. Review and Use the new Exchange Server Role Requirements Calculator(formerly Exchange Storage Calculator)
  6. This tool from Microsoft is essential in giving us recommendations for:
    • Deploying dedicated server roles, the minimum number of Client Access Processor Cores, minimum number of Client Access Servers and memory in each server.
    • Deploying Multi-role servers(Client Access and Mailbox) The Client Access Role will be accounted for in the memory and CPU recommendations.
    New to the tool is transport sizing and database sizing and better utilization of disks for Just a Bunch of Disks (JBOD) scenarios for Exchange 2013 installations. The calculator will recommend multiple databases in each volume and supports single datacenter deployments and multi-datacenter deployments like ours.
    Download the latest version of the Exchange 2103 Server Role Requirements Calculator here.

  7. Have a test lab for your Exchange Server 2013 Environment
  8. This is a critical step in preparation for deploying any version of Exchange Server. Before you begin you should review the Exchange 2013 Prerequisites.  For an Exchange Server 2013 test lab environment, we would suggest domain controller(s), a root Certification Authority (CA) Server, DNS and DHCP Servers, Exchange Server 2013 Mailbox and Client Access Servers and workstations for client testing running Office 2010, 2013 or 2016 depending on what is being used in your environment.

  9. Learn how Role Based Access Control (RBAC) works
  10. RBAC is the permission model used in Exchange Server to control what Administrators and users can do based on their roles within your company. Microsoft references the Triangle of Power that addresses The Where, The What and The Who. The Where is where will the permissions be needed. This is also known as the scope. The What is what the person needs to be able to do within The Where. These can be customized to meet your company needs. This is also known as the Role. Finally The Who is the person(s) (administrator or user) that needs to be able to do The What in The Where they have been allowed to do it. This is known as a role group. Finally the Glue or Role Assignment is how all the parts work together. For more information reference "Understanding Role Based Access Control".

We have just published 5 more tips for Exchange Server 2013 Administrators called "5 More Tips for Exchange Server 2013 Administrators" If you have any thoughts, opinions or comments feel free to share them below.

Friday, October 31, 2014

Why are some attachments different places in Outlook messages?

Have you ever wondered why some messages with attachments in Outlook have the attachment in the body of the message and why some messages have the attachment at the top of the message below the Subject? This post will tell  you why that happens and how to fix it. I had a user ask me today why this was like this. He wanted the attachment at the top only not in the body of the message.

The reason this happens is due to the format of the message. In Rich Text format,(Supported since Outlook 97) it does in-line attachments in the body of the e-mail message as shown below.

In HTML Format and Plain Text Format the attachment is at the top of the message. HTML Format is shown below (from Office 2013)

Did you notice the attachment to the message sent in HTML format also has the size of the file (26 KB) while the message in Rich Text Format has the same attachment but no indication of file size?

So how do you change the format of the message from Rich Text to HTML? You can do it two ways. You can change it per message by opening a new message then going to FORMAT TEXT in Outlook and choosing HTML as shown below (applies to Office 2010 and Office 2013)

If you want to only send HTML Messages and have attachments be at the top of the message and not embedded in the body you can change it in the Outlook Client settings By going to FILE then OPTIONS then Mail and select HTML as shown below from Office 2103.

This will cause all messages from that point on to be sent in HTML Format. Please note that replies to messages will be sent in the original format of the message because Outlook preserves the format. Also in my testing the Rich Text Formatted message with the attachment in the body was slightly larger than the HTML Formatted and Plain Text messages. I am sure that will make your Exchange Administrators happy when you can send smaller messages with the same content. Microsoft recommends sending messages in HTML Format.  Rich Text format supports in-line attachments and the attachments are in the body of the message. HTML and Plain Text formats do not support in-line attachments.
BONUS TIP:You can also change the message format for all messages sent to an Outlook Contact
  1. Open the contact card for the recipient.
  2. In the E-mail box, double-click the recipient's e-mail address.
  3. In the Internet Format list, select the format that you want to use for messages to this recipient.
I hope this post has helped with understanding why attachments are different in your Outlook client. Feel free to leave comments.

Tuesday, September 30, 2014

Why you should upgrade Distribution groups moving to Exchange Server 2013

If you previously migrated from Exchange Server 2003 to Exchange Server 2007 and now moving to Exchange Server 2013, Group owners will not be able manage distribution groups created in Exchange Server 2003 or Exchange Server 2007 anymore. They can get the following error message when trying to make changes to a group from Outlook: 

In helping a user who could not manage a mail-enabled security group that she was the owner of and had all the correct rights and RBAC roles assigned, we saw that the Exchange Version for the problem group was 6.5 which was an old 2003 group that was not upgraded when our organization migrated to Exchange 2007 a few years ago.

When checking the group we were able to see the Exchange Version Number as shown below:
To upgrade the group using the Exchange Management Shell:
Set-DistributionGroup -id "Name of the group" -Forceupgrade -bypassSecuritygroupManagerCheck
After the group was upgraded we checked the Exchange Version number. It was now Version 14 as shown below. The user was able to manage the group after Active Directory (AD) Replication had occurred.
If you want to upgrade all your groups at the same time you can use the following from the Exchange Management Shell :
Get-DistributionGroup -ResultSize unlimited | Set-DistributionGroup -forceupgrade -bypassSecuritygroupManagerCheck
If you want to get list of the groups with their Exchange Versions in a report that can be shared with management before you begin to upgrade them, you can run the following from the Exchange Management Shell:

$groupdata = Get-DistributionGroup -ResultSize unlimited | select displayname, exchangeversion
$groupdata | export-csv c:\groups_exchversion.csv 

If you want to see the Exchange versions of your groups and get a count by Exchange versions, run the following in the Exchange Management Shell:
$groupdata | group ExchangeVersion
 Get-DistributionGroup -ResultSize Unlimited | Group ExchangeVersion if you had not done the previous CSV export like the example above.
The output should be similar to the following that I got running this in our environment today 

As you can see we have some work to do with upgrading our groups so let me get back to that. If you upgrade the distribution groups to Exchange 2013 but the owners/managers are still on Exchange 2007 they will no longer be able to manage the groups. This happens because the Exchange trusted subsystem cannot modify the legacy (2003 and 2007) objects. If you migrate the users to Exchange 2013 but the groups are not upgraded they will also not be able to manage the group. You should be following the guidance of using Exchange 2007 administrative tools to manage Exchange 2007 objects and using Exchange 2013 administrative tools to manage Exchange 2013 objects.  
Our current approach is to migrate the user mailboxes to Exchange Server 2013 and upgrade the groups for that specific OU to the Exchange 2103 version after the user migration. This way we can ensure that the groups are upgraded in the same timeframe as the user migration to avoid the support ticket that generated this blog post. 
Good luck to those of you moving to Exchange 2013. Please share your feedback and thoughts in the comments.

Friday, August 29, 2014

Why Can't I find a mailbox using Exchange Admin Center (EAC) in Exchange 2013?

Why Can't I find a mailbox using Exchange Admin Center (EAC) in Exchange 2013?

The answer: You may be looking in the wrong place in the Exchange Admin Center(EAC). In older versions of Exchange using the Exchange Management Console (EMC) or the Exchange Control Panel (ECP), you were able to find mailboxes when searching by just entering the name or part of the name and you would get results. Using the Exchange Admin Center (EAC) which is the new web based management console in Exchange 2013, is bit different and I will go through the options to help you get what you want when searching for a mailbox. Please note that with each of the options outlined in this post you need to wait for the data to finish loading before you start searching using the search box.

If you are searching for a User Mailbox be sure you have the mailboxes option selected.

If you are searching for a distribution group you have to have the groups option selected.
If you are searching for a resource mailbox you need to have the resources option selected
If you are searching for a shared mailbox you need to have Shared option selected
I hope this post has helped and made it easier for you when searching for a mailbox using the Exchange Admin Center in Exchange 2013. Please share your comments and feedback on this post.

Friday, August 1, 2014

A possible fix for Calendar Meeting Requests showing up as email messages on a BlackBerry Device

A few weeks ago we started getting reports of users on Exchange Server 2007 with BlackBerry devices getting calendar meeting requests on their BlackBerry device as an email with no option to accept or decline the meeting. We discovered that the problem was due to the
-AutomateProcessing attribute of the impacted mailbox being set to None. The default should be AutoUpdate.
 To see the setting for a single user open the Exchange Management Shell on Exchange 2007and type Get-MailboxCalendarSettings user alias | FL
press enter and look at what the attribute -AutomateProcessing is set to:
 replace user alias with the appropriate alias for the mailbox you are checking.
To fix the issue, type Set-MailboxCalendarSettings user alias -AutomateProcessing AutoUpdate and press Enter. After it is complete you can check again using Get-MailboxCalendarSettings user alias | FL 
and you should see the following: 
replace user alias with the appropriate alias for the mailbox you are checking.

The users were then able to see Calendar Meeting Requests correctly on the BlackBerry device.

If you want to see of all the user Mailboxes that are set to None, you can type the following in the Exchange Management Shell:

Get-Mailbox -Resultsize Unlimited -RecipientTypeDetails UserMailbox | Get-mailboxCalendarSettings | Where {$_.automateprocessing -eq "None"} | FL Identity, automateprocessing > c:\usermbcalsettings.txt

If you want to change the ones that are found you can type the following in the Exchange Management Shell: Get-Mailbox -Resultsize Unlimited -RecipientTypeDetails UserMailbox | Get-mailboxCalendarSettings | Where {$_.automateprocessing -eq "None"} | Get-MailboxCalendarSettings -AutomateProcessing AutoUpdate

  1. For Exchange Server 2010/2013 you will use Get-CalendarProcessing instead of Get-MailboxCalendarSettings and Set-CalendarProcessing instead of Set-MailboxCalendarSettings.

  2. You can only apply Set-CalendarProcessing to Resource Mailboxes. It cannot be used on User Mailboxes like was done for Exchange 2007 users as mentioned in this post. Additionally in Exchange 2103, Exchange ignores the -AutomateProcessing attribute on the user mailbox. So if it is set to None or AutoUpdate, Exchange treats the message the same way, which is to auto update the meeting.

Refer to RIM KB31558 for more information from RIM about this issue.

If this has helped you fix Calendar Meeting requests showing up as email messages on BlackBerry devices please share in the comments or if you have any additional insights in to this issue, it would be appreciated.

Thursday, March 6, 2014

Fun With PowerShell (Make it Speak)

In my downtime, I wanted to have some fun with PowerShell and make it speak using Add-Type -AssemblyName System.Speech. I have always written an age calculation script in every scripting language I have learned and I realized I had never done one in PowerShell. So I wrote one and decided to have it speak to you. Here it is:

# Funscript.ps1                        # 
# #
# Written by DJ 3/2014                 #

Add-Type -AssemblyName System.Speech
$synthesizer = New-Object -TypeName System.Speech.Synthesis.SpeechSynthesizer

Write-Host This script will tell you how old you will be in $year and will speak to you. Make sure your speakers are on.;
$synthesizer.Speak("This script will tell how old you will be in ($year) and will speak to you. Make sure your speakers are on. ") | Out-Null
$name = Read-Host 'What is your name?';
$synthesizer.Speak("Hello, ($name) ,!") | Out-Null
$yb = Read-Host 'What year were you born?';
$synthesizer.Speak("Thank you, ($name) ,") | Out-Null
$date = Get-Date;
$year = + $date.Year;
$today = Get-Date -Format D;
$span = $year - $yb;
Write-Host Hello, $name. Today is $today. You will be $span years old this year. When is the party?;
$synthesizer.Speak("Hello, ($name). Today is ($today). You will be ($span) years old this year. When is the partee? ") | Out-Null


I would like to see what you can come up with. Be sure to leave your comments and suggestions below.

Friday, January 17, 2014

Have you ever needed to keep the mouse moving? MouseMover can help.

After looking around the Internet a little and not finding a decent mouse moving program, I decided to write my own. I wanted something that had an adjustability to how fast or slow the mouse would oscillate back and forth as well as over all oscillation time, instead of one that just oscillates every second making it ridiculous.

If you have improvements or suggestions, just comment and mention them.

Download link for MouseMover

Friday, May 10, 2013

How to have a single instance app that minimizes to the system tray, as well as restores from the tray and any duplicate instance bring the original to the foreground

For a recent project, I wanted to minimize my application to the system tray, as to not inhibit the precious toolbar space for an application that is accessed at the beginning of the workday and the end of it. I also wanted to be able to restore the application from the system tray, as well as not allow more than 1 instance of the application to be opened and if the user attempted to do that, to bring the original application into the foreground before closing the duplicate app.

This proved to be much more convoluted and difficult then I had originally expected. I found a ton of different suggestions on the internet as to how to do this, but nothing straight forward and plug and play, so this blog post will be all about adding code into an existing project that is plug and play as well as giving a simplistic example application to cherry pick from or build off of. I tried to be as detailed as possible, if I missed a step please comment so I can explain a step or add a step into this.

Create a form in Visual studio, go to the toolbox and add a notify icon to the form1, then choose your icon and the icon name. You'll need to modify the third entry below named this.nofityIcon1.Icon to whatever you name your icon by going into the solution explorer, right clicking on the project name, clicking on the resources menu tab and then add a resource/add existing file. At this point that file will now reside in your resources and be accessible via Properties.Resources .

You can add the following to the Form1_Load method if you would like, it is optional

this.notifyIcon1.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; //Shows the info icon so the user doesn't thing there is an error.
                this.notifyIcon1.BalloonTipText = "[Balloon Text when Minimized]";
                this.notifyIcon1.BalloonTipTitle = "[Balloon Title when Minimized]";
                this.notifyIcon1.Icon = ((System.Drawing.Icon)(Properties.Resources.alarm_clock_face_s)); //The tray icon to use
                this.notifyIcon1.Text = "[ApplicationName] application, double click to restore program";

Inside of Form1() you'll need to capture 2 events via the event handlers and have two corresponding functions to handle those events as well as add a new warning message form. Under solution explorer, right click on the solution, then add, then windows form. Name the form (I called it the default name of form2.cs) and then add a label and a checkbox to it for this code, or anything else you would like to customize it with.

this.Resize += new EventHandler(form1_Resize);
            notifyIcon1.DoubleClick += new EventHandler(notifyIcon1_DoubleClick);

       private void form1_Resize(object sender, EventArgs e)
            if (FormWindowState.Minimized == WindowState)
                Form2 warningForm = new Form2();
                    RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true);
                    if (key.OpenSubKey("TimeKeeper") == null)

                    RegistryKey subKey = key.OpenSubKey([KeyName], true);
                    string regValue = subKey.GetValue("minimizeWarningHide").ToString();

                    if (regValue == "true")
                        // continue on

                catch (Exception ex)
                    MessageBox.Show(ex.Message + System.Environment.NewLine + ex.Source + System.Environment.NewLine + ex.TargetSite + System.Environment.NewLine + ex.StackTrace + System.Environment.NewLine + System.Environment.NewLine);



      private void notifyIcon1_DoubleClick(object sender,System.EventArgs e)
            WindowState = FormWindowState.Normal;

In the new form2 you'll want to paste the following code after adding checkBox1 (which I renamed to ckbxMinimizeWarning), again be sure to change the [KeyName] value to your registry key name that you've chosen. You also want to add the include using Microsoft.Win32; to the top. You'll also want to disable the minimizebox and maximizebox buttons for this warning message, they aren't necessary and could confuse your user.

private void checkBox1_CheckedChanged(object sender, EventArgs e)
                RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true);
                if (key.OpenSubKey([KeyName]) == null)

                RegistryKey subKey = key.OpenSubKey([KeyName], true);

                if (ckbxMinimizeWarning.Checked == true)
                    subKey.SetValue("minimizeWarningHide", "true", RegistryValueKind.String);

                if (ckbxMinimizeWarning.Checked == false)
                    subKey.SetValue("minimizeWarningHide", "false", RegistryValueKind.String);
            catch (Exception)

At this point you'll want to put this code into your Form1_Load() method, ensure to change [KeyName] to the name of the key you want to house your registry settings in, inside of hkcu\software. Also don't forget to add the registry include, using Microsoft.Win32; at the top of your project.

RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true);
                if (key.OpenSubKey([KeyName]) == null)

                RegistryKey subKey = key.OpenSubKey([KeyName], true);

                string[] subKeys = subKey.GetValueNames();

                if (!(subKeys.Contains("minimizeWarningHide")))
                    subKey.SetValue("minimizeWarningHide", "false", RegistryValueKind.String);

Lastly go into the program.cs code and we will use pin invoke.

The first thing to do is add the pininvoke include as well as threading include at the top of program.cs
using System.Runtime.InteropServices; and using System.Threading; This part of the code allows you to identify existing windows and to bring a window to the foreground as needed. Be sure to change the Mutex value of ExampleMinimizeToTrayProject per your own needs. This is a unique value and needs to be unique for each application you write, or else the applications will all think they are the same application (no matter the code) when the open. Mutex stands for Mutually Exclusive.

Here is the program.cs code

static class Program
        /// The main entry point for the application.
        /// </summary>
        static void Main()
            if (IsSingleInstance())
                Application.Run(new Form1());
                bringToFront("Time Keeper");

        static private Mutex _instanceMutex = null;

        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);

        public static extern uint GetWindowThreadProcessId(IntPtr hWnd,
            IntPtr ProcessId);

        public static extern IntPtr GetForegroundWindow();

        public static extern uint GetCurrentThreadId();

        public static extern bool AttachThreadInput(uint idAttach,
            uint idAttachTo, bool fAttach);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool BringWindowToTop(IntPtr hWnd);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool BringWindowToTop(HandleRef hWnd);

        public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);

        public static void bringToFront(string title)
            IntPtr hWnd = FindWindow(null, title);
            uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
            uint appThread = GetCurrentThreadId();
            const uint SW_SHOW = 5;

            if (foreThread != appThread)
                AttachThreadInput(foreThread, appThread, true);
                ShowWindow(hWnd, SW_SHOW);
                AttachThreadInput(foreThread, appThread, false);

        static Mutex _m;
        static bool IsSingleInstance()
                // Try to open existing mutex.
                // If exception occurred, there is no such mutex.
                Program._m = new Mutex(true, "ExampleMinimizeToTrayProject");

                // Only one instance.
                return true;
            // More than one instance.
            return false;
Then add an image to form2 by going to the tool box and adding a picturebox and browsing to an image under the solution explorer for the picturebox, showing the system try and what the icon looks like placed in it by importing it. Then add the label (if you would like) as well as text to the label on form2 explaining to them the minimizing process. I use the following text

This program will be minimized to the system tray by the clock as pictured above. To restore it, look for the alarm clock icon inside of the system tray icon list and double click it.</blockquote>
Also add the following text to the form2 checkbox explaining its usage

Select this not to see this warning again.</blockquote>
Lastly, make sure the bringToFront("[texthere]"); in program.cs is looking for the name of your form, whatever text name you've given it in your project. In this project you'll see it is named ExampleMinimizeToTrayProject.

Project for download: (the second link should be a direct link)

References I used:


single instance app application
system tray minimize restore from tray

Monday, May 6, 2013

How to fix Lync Server Error "An unhandled exception was encountered in Service service"

We recently encountered an error with a Microsoft Lync server "An unhandled exception was encountered in Service service" that impacted users who were trying to expand a Distribution Group in Microsoft Office Communicator 2007 that had a simple fix. Read more about this error message and how we fixed it.

From the log files:

Log Name:      Lync Server
Source:        LS Web Components Server
Date:          4/30/2013 11:39:41 AM
Event ID:      4096
Task Category: (1074)
Level:         Error
Keywords:      Classic
User:          N/A
An unhandled exception was encountered in Service service.
Exception Details. System.Runtime.InteropServices.COMException (0x8007203A): The server is not operational.
   at Microsoft.LiveServer.DLExpansion.Service.ThrowSoapFault(Exception e)
   at Microsoft.LiveServer.DLExpansion.Service.QueryADGetDistributionListInfo(String mail, DirectorySearcher dSearcher)
   at Microsoft.LiveServer.DLExpansion.Service.ProcessADRequest(OCSPrincipal user, String key, DlxGroup& result)
   at Microsoft.LiveServer.DLExpansion.Service.ExpandDistributionList(String groupMailAddress)
   at SyncInvokeExpandDistributionList(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Cause: Application error. Please look through the exception details for more information.
Restart the server. If the problem persists contact product support.

Event Xml:
<Event xmlns="">
    <Provider Name="LS Web Components Server" />
    <EventID Qualifiers="50226">4096</EventID>
    <TimeCreated SystemTime="2013-04-30T15:39:41.000000000Z" />
    <Channel>Lync Server</Channel>
    <Security />
    <Data>System.Runtime.InteropServices.COMException (0x8007203A): The server is not operational.
   at Microsoft.LiveServer.DLExpansion.Service.ThrowSoapFault(Exception e)
   at Microsoft.LiveServer.DLExpansion.Service.QueryADGetDistributionListInfo(String mail, DirectorySearcher dSearcher)
   at Microsoft.LiveServer.DLExpansion.Service.ProcessADRequest(OCSPrincipal user, String key, DlxGroup&amp; result)
   at Microsoft.LiveServer.DLExpansion.Service.ExpandDistributionList(String groupMailAddress)
   at SyncInvokeExpandDistributionList(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</Data>

• Affected Users: users trying to expand Distribution Groups in Office Communicator 2007 were affected.

• Fix: Restarted IIS on Lync servers. Please leave your thoughts in the comment section below this post.

Friday, February 8, 2013

Browse the registry just like a UNC path

Periodically I am searching for a registry path and I stumble upon something on the internet telling me to go 10+ subkeys into a hive to find a value. Although not terrible, it's kind of annoying to switch back and forth between regedit and the browser to follow the path down to the key that I need.

After some googling, I found that Mark Russinovich made a command line version of a tool for this, but I wanted a GUI so I decided to write my own registry jump browser tool. It's pretty simple to use, you plug the key into the input box and hit enter or click the browse registry button.

Format for the key path should look like

hklm\SOFTWARE\Microsoft\Test Key\Test Sub Key

and if the key is present, it will open the registry and navigate down to the key you've input. If the key does not exist, it will tell you that as well.

You may also use a command line version of this using the format below in the command prompt (remember to navigate to it)
regbrowser "hklm\software\microsoft"

You can only have 1 instance of the registry open when doing this, and it is designed for local registry browsing only, FYI.

Enjoy and leave a comment if it is useful for you, or if you have a suggested improvement.

^ new version with help file built in and minor added functionality

^ Sorry blogspot doesn't host .zip files

Tuesday, January 15, 2013

So you're getting Event Manager / Application Log code 9669

This event manager code is generated when your Exchange Server 2007 environment has run out of rows to write to in a database column, that hold unique mail header information, per each mail server. There are many posts on the internet as to how to raise the threshold for this table up to the max (database crashing) limit of 32768.

If you've temporarily raised the ceiling, just as congress keeps raising the debt ceiling, you probably realize just as congress does that eventually a limit is going to be reached and everything is going to then crash and burn.

Fortunately for you, Microsoft decided to build a way to monitor this ceiling/threshold.

Open up regedit and navigate to HKLM\System\CurrentControlSet\Services\MSEXchangeIS\Performance

• Modify the string value "Library" from (notice the dll name) [drive you have exchange program files on]\Program Files\Microsoft\Exchange Server\Bin\Perf\%Processor_Architecture%\mdbperf.dll


[drive you have exchange program files on]\Program Files\Microsoft\Exchange Server\Bin\Perf\%Processor_Architecture%\mdbperfx.dll

• Go to each server and apply the attached registry file change (rename the file extension appropriately)

• Open perfmon after registry change

• Right click and add counters and then select “MsExchangeIS Mailbox” under the counters and expand it

• Scroll down to “Rows in ReplidMap Table” and click once on it

• In the “Instances of selected object” window below, highlight each database individually and click add and then ok

• Next scale your counters and determine if any of them are approaching the 16383 out of the box limit

• Save the counter report as an html file so you can go back later, run the report again and calculate the rate of change each day, you can also export them as a .tsv (Tab Separated Value) file for sharing.

At this point you can spot check all other databases to see which are also approaching the replica id limit you've coded into the registry. You can also check these values with a powershell command after you've altered the registry key mentioned above.

The code for that is:

Get-mailboxserver | foreach {get-counter –counter “\MSExchangeIS Mailbox(*)\Rows in ReplidMap Table” –sampleinterval 2 –maxsamples 1}