Monday, December 26, 2011

Disable Office 365 Retention Policy

Recently I made the move from Google Apps to Office 365. I love cloud services for mail, especially ones that allow 25G+ of mail storage. However, I was a bit shocked to find out that the default retention policy is set to 30 days. I basically never want my email deleted as I never know when I’m going to need a message later. Fortunately, with just a little PowerShell, this is easily fixable.

The first step is to get connected Office 365 via PowerShell. As Mike Pfeiffer shows us, this is easily accomplished with the following three PowerShell Commands:

$cred = Get-Credential

$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $cred -Authentication Basic -AllowRedirection

$importResults = Import-PSSession $s

(The second command is all one line – formatting issues) :-)

Upon executing the first PowerShell command (Get-Credential) you’ll be prompted for a username and password. Use your Office 365 administrator’s credentials.

Then the command to disable the retention policy for the mailbox is as follows:

Set-Mailbox <name> -RetentionPolicy $null

Make sure the <name> is the email address for the mailbox you wish to disable the retention policy for. And fixed!

Thursday, December 15, 2011

Remove System Account from Workflow History

SystemAccountYesterday I blogged about keeping System Account out of the Modified By column. Today I want to tackle the other annoying place System Account rears its ugly head – workflow history.

The LogToHistoryListActivity determines who it will log as by reading the ID in the UserId property. By default this property is set to –1, meaning the System Account. What we need to do is set this to the ID for the user. How we go about finding the user ID and assigning it will vary a bit.

If we’re looking for the person who kicked off the workflow, this is pretty easy. After dragging out your LogToHistoryActivity, bind the UserId property to workflowProperties.OriginatorUser.ID.

If you’re looking for the user who modified a task, you’ll need to perform a couple of steps.

  1. Add a field or property to the workflow to store the ID for the user of type Int32. I like to simply call mine logUserId.
  2. Create a new binding on the OnTaskChanged activity for the Executor property. This will contain the string for the login name. I call mind taskExecutor.
  3. Create a little helper method in the code to update the logUserId. I like mine UpdateLogUserId():
    private void UpdateLogUserId()
    {
       logUserId =
          workflowProperties.Web.EnsureUser(taskExecutor).ID;
    }
  4. Ensure the UpdateLogUserId() method is called before the LogToHistoryListActivity executes – this is most easily accomplished by making the call in the Invoked event handler for the OnTaskChanged event handler.

For each OnTaskChanged event handler and LogToHistoryActivity you simply need to ensure steps 1, 2 and 4 (since the method will have already been created) and you’re all set!

Now we can hide System Account from our users once and for all.

Wednesday, December 14, 2011

Avoiding System Account in “Modified By”

When creating event receivers or workflows you frequently need to update the list item in question in that code. The problem with doing this is it typically requires changing the user context to someone who has permissions to perform the operation (frequently the System Account or another privileged user). You usually want these changes to occur behind the scenes and not be displayed to the user.

Consider the following little example for an event receiver:

public override void ItemAdded

                          (SPItemEventProperties properties)

{

   SPUser adminUser =

       properties.Web.EnsureUser("GEEKTRAINER\\charrison");

   using (SPSite site =

       new SPSite(properties.WebUrl, adminUser.UserToken))

   using (SPWeb web = site.OpenWeb()) {

     SPList list = web.Lists[properties.ListId];

     SPListItem item = list.GetItemById(properties.ListItemId);

 

     item.BreakRoleInheritance(true);

     item.Update();

   }

}

Pretty simple demo code for an event receiver. First I’m changing context[1] to a privileged account. Then I’m loading up new instances of the SPSite, SPWeb, SPList and SPListItem objects in order to make changes. I then perform the change and call Update() on the list item. The result? Well, the result looks like this for a user named Susan who creates a new announcement in this list:

BeforeCallingSystemUpdate

You’ll notice that it says the item was updated by Christopher, which is true – it was modified by Christopher, but that’s not the display I’m looking for. The item was created by Susan, and Susan should be the only person shown on the Modified By column.

Thus enter SystemUpdate[2]. SystemUpdate allows you to change a list item without changing either the Modified or Modified By fields. Behind the scenes, SystemUpdate will still update the audit log, however it will not send alerts for the changes.

SystemUpdate has two two overloads, SystemUpdate() and SystemUpdate(boolean). The second overload allows you to control if a new version is created by passing in true. The default (no parameters overload) is false – don’t create a new version.

If we update the line:

item.Update();

to be:

item.SystemUpdate();

and then create a brand new item again as Susan, you’ll notice the difference (the one titled “Modified by Current User”:

AfterCallingSystemUpdate

SystemUpdate allows you to make changes to list items in code and essentially “hide” those changes from the user. The audit logs will still record the change, but the user will not see the dreaded “System Account” (or other account) in the Modified By column.

[1] See blackninja for a demo on changing context.
[2] See MSDN for the full documentation.

Wednesday, November 30, 2011

Taking Your Developer Skills to the Next Level

IMG_0017There are many courses and books on the market that will teach you C#. When you finish one, the world of .NET is now open to you. However, merely knowing the syntax of the programming language isn’t the entire story. In order to be a good developer we need to learn conventions, best practices, and when to apply the techniques we’ve learned – and when not to! Fortunately, if you’re willing to invest the time, getting over that wall and taking your skills to the next level is within reach. While everyone is different, here’s a list of resources (books) that have helped me improve my skills as a developer.

Applying UML and Patterns (Craig Larman) – While not a .NET book, this book picks up where most C# courses and books leave off. You know the syntax but not the techniques of proper object design. The code samples are in Java, but if you know C# it’s a pretty straight forward translation. Besides, it’s the skills we’re interested in rather than the syntax itself. What I love about this book is how down to earth it is, and that Craig walks you through every step of his small case study, explaining every decision that he makes.

Refactoring: Improving the Design of Existing Code (Martin Fowler, Kent Beck et al.) – The first couple of chapters are a must read for every developer. In those chapters, the book introduces one of my favorite terms in determining the quality of code – smells. There are certain, well, smells that bad code gives off – little things that indicate there’s probably a better way to do things. The rest of the book is a great reference on how to convert that bad smelling code into code that’s more readable and elegant.

Code Complete (Steve McConnell) – While this book may seem very basic at times, it covers basically every item that needs to be covered in every team’s coding standards documents. In fact, it wouldn’t be a bad idea at all to make this book the team’s coding standards.

CLR via C# (Jeffrey Richter) – Want to know what goes on behind the scenes in the CLR? Trying to figure out what’s emitted when you create an anonymous type? Looking for the best way to take advantage of certain .NET features? This is the book for you. This book belongs on the shelf of every .NET developer.

Framework Design Guidelines (Krzysztof Cwalina, Brad Abrams) – The tile of this book is a bit deceptive in my opinion. While this book certainly does spend talking about how best to build libraries, it gives great coverage to best practices in .NET. It’s a very approachable book, categorizing best practices as Do, Consider, Avoid and Don’t.

The Art of Unit Testing (Roy Osherove) – I’m a huge proponent of test driven development (TDD). When done correctly, TDD saves time in the long run, makes for more elegant code, and allows for quick assessment of the state of an application and bugs. However, putting together good tests is a skill just like any other that needs to be learned. This will help get you moving in the right direction.

Keep in mind that all of the above have simply worked for me, and that your mileage may vary. With that in mind, these books come with an absolutely no money back guarantee. However, I do think you’ll find that these will help get you started on your journey and take you to the next level. And even if you’re at that next level, it never hurts to go back to the fundamentals.

Like the list? Don’t like the list? Books you think shouldn’t be on there? Books you think should be added? Let me know!

Friday, November 18, 2011

Taking Advantage of User Profiles

The key to most (all?) successful SharePoint deployments is achieving a high level of user adoption. One of the mail goals of a SharePoint deployment is collaboration, and if a large portion of the user base isn’t using SharePoint, there isn’t necessarily a reason for anyone else to either.

Towards that end, one of the things I look for when it comes to deploying SharePoint for the first time in an organization are little things that I can do for “big wins” – things that are simple for me to set up and configure that my users will hopefully love and help drive them into SharePoint. Implementing user profiles is one of those things.

If you’re not familiar with a user profile, the simplest way to think of it is to picture a Facebook profile. Just like Facebook, users can post status updates, share information about themselves, and find and connect with other people. While at first glance that can seem like a small thing, it actually has many applications throughout your users’ day to day lives.

The most obvious use case for a user profile is simply trying to figure out who someone is. When you’re a larger organization, it’s simply not possible to know everyone. It can be embarrassing to attend a meeting with a senior manager and not realize who that person is. Taking advantage of user profiles to find out who’s participating in a meeting or who’s included in an email can be very helpful.

You may also have times when you need to figure out who works with a particular coworker. I wish I could tell you the number of times I’ll receive an out of office reply without alternate contact information, or the alternate contact is also out of the office. If I am in need of finding someone to get in touch with, I can fire up the person’s profile and see who else works in their department or who their manager might be.

While those are typical day-to-day uses for user profiles, there are other, more subtle, uses as well.

Let’s say our organization is considering implementing a new internal rewards program for sales, or ------. Inviting managers to those planning meetings is pretty obvious, but it could also be good to get input from other employees as well – maybe ones that have been with the organization for a long period of time, or ones that have recently worked for a competitor; they can offer valuable insight. Finding those types of employees in the past would typically require contacting HR and digging up their records. With user profiles, it’s a quick search and I can identify the perfect people to help contribute.

And it even goes beyond direct business needs as well. I’m a big believer that happy employees are productive employees. User profiles can help drive different morale building activities. Users can add personal interests as well, so I can find people that share common passions. Forming a basketball or kickball team can be as easy as looking to see who enjoys those sports. Or, as a runner, if there’s a race coming up I can do a search to find fellow runners to train with, and maybe raise money for a charity as well.

User profiles will quickly become a heavily used resource for your users. It’s a great way for users to connect, find one another for both business and nonbusiness needs, and share information about themselves. Plus, it’s one of those little things that will be a big win (and a big hit) for your SharePoint implementation.

Thursday, November 10, 2011

Disabling the Submit Button with Ajax

LoadingNow that SharePoint 2010 has Ajax support built in I find I’m using it more frequently. Ajax, of course, allows us to update a portion of the page without having to do a complete post back to the server. However, the browser does not see this as a full page refresh and doesn’t alert the user that it’s loading data meaning they may keep hitting that “submit” button over and over again. The best way to handle that issue is to just disable the button. Fortunately, we can do that with just a few lines of JavaScript code.

The first thing we need to do is set up a couple basic variables – one for the button, and another for the text being displayed in the button.

var originalText;

var button;

Next up – register the event handlers. ASP.NET’s Ajax has a request manager that has the events (beginRequest and endRequest) that we need. The beginRequest will of course execute when the round trip starts, and the endRequest will execute when we receive our data from the server. We place the code to wire up the event handlers inside pageLoad, which is automatically called when, you guessed it, the page loads. The one little thing you’ll need to change for your environment is the name of the button. In my case it’s btnSearch.

function pageLoad() {

       var manager =

              Sys.WebForms.PageRequestManager.getInstance();

       manager.add_beginRequest(beginRequest);

       manager.add_endRequest(endRequest);

       button = $get('<%= btnSearch.ClientID %>');

}

Our logic for beginRequest and endRequest is very straight forward. beginRequest will disable the button and set the text to be “Loading…”, while endRequest will set it back to the original value.

function beginRequest() {

       originalText = button.value;

       button.value = "Loading...";

       button.disabled = true;

}

 

function endRequest() {

       button.value = originalText;

       button.disabled = false;

}

No more need for text that says, “Please only click the button once!” If they can’t click the button, we don’t need the text.

Tuesday, November 1, 2011

Taking Advantage of HTTP Modules

No way in the world I could do that jobOne of the things I love most about training is the constant real world questions and scenarios that students bring to the table. Yesterday I received an email from a former student asking about how they could log a little bit of information passed in the query string of a URL (for example, a CustomerID). As it turns out, that’s a relatively easy feature to implement – simply use an HTTP module.

An HTTP module gives you the ability to slide custom code into the handling of pages, allowing you to customize behavior or add additional functionality. Our HTTP module will fire for any file being requested if IIS 7 or later is in use, or just ASP.NET files (ASPX, ASMX, etc.) if IIS 6 is in use. In this case, the HTTP module is the perfect choice, because it will execute for every page, so anywhere we have the CustomerID in the query string we can grab it.

You might be thinking at this point – wait a minute… I can do that in my global.asax file.

And you’re right, many times you can. However, an HTTP module does have a few advantages. First, an HTTP module is more, well, modular. It’s much easier for me to add and remove it from different web applications; I can register the DLL that contains the HTTP module in the GAC and access it from multiple web applications. And that registration can be done with a simple update of the web.config file, rather than having to (potentially) recompile the application to add the functionality. Second, if you’re dealing with a lot of custom event handlers, the global.asax file can become rather convoluted dealing with all the logic necessary to figure out how to deal with each possible scenario. And finally, as an added bonus, I can add modules in places (like SharePoint) where updating the global.asax file may not be an option.

Fortunately, setting up an HTTP module is relatively straight forward. The first thing to do is to create a class that implements IHttpModule. IHttpModule has two very simple methods, Dispose (which you’re probably familiar with), and Init which is where you register your event handlers.

public class CustomerLoggingModule : IHttpModule

{

   public void Dispose()

   {

      // cleanup code if needed

   }

 

   public void Init(HttpApplication context)

   {

      context.BeginRequest +=

         new EventHandler(context_BeginRequest);

   }

 

   void context_BeginRequest(object sender, EventArgs e)

   {

      // cleanup code if needed

   }

}

If you’re curious, there are many, many events you can handle in your HTTP module.

Event Name Description
BeginRequest Request has started
AuthenticateRequest Used for creating a custom authentication scheme
AuthorizeRequest Used for any custom authorization scheme – scenarios where you need a bit more logic than simply a list of files that users can access
ResolveRequestCache Determines if a page is in the Output Cache
AcquireRequestState Raised when session state information is retrieved
PreRequestHandleExecute Raised just before the HTTP handler (whatever will actually parse the page) is executed
PostRequestHandleExecute Raised just after the HTTP handler (whatever will actually parse the page) is executed
ReleaseRequestState Raised when the session state information is saved back to the backing store
UpdateRequestCache Raised when the page to the Output Cache
EndRequest One last chance to access any information in the request or page before the result is sent to the user

The rest is simply adding the appropriate logic to the event handlers. In the example my student asked about, he was looking to log the CustomerID from the query string. While I don’t have the database code to do the logging below, it’s pretty simple to extrapolate how you’d write that out to the database.

public class CustomerLoggingModule : IHttpModule

{

   // previous code sampled above

 

   void context_BeginRequest(object sender, EventArgs e)

   {

      HttpApplication application = (HttpApplication) sender;

      HttpContext context = application.Context;

 

      String customerID =

         context.Request.QueryString["CustomerID"];

 

      if(!String.IsNullOrEmpty(customerID)) {

         context.Response.Write("Customer ID : " + customerID);

      } else {

         context.Response.Write("Customer ID not found");

      }

   }

}

Finally, we need to update the web.config to register our cool new handler. Fortunately, the DLL for the handler itself can be in the bin directory if we like, although the GAC does work as well.

If IIS 6 is in use (or IIS 7 is running in Classic Mode), the following would need to be added to our web.config:

<system.web>

   <httpModules>

      <add name="CustomerLoggingModule"

         type="HttpModulesPost.CustomerLoggingModule"/>

   </httpModules>

</system.web>

 

For IIS 7 in Integrated Mode (the default for IIS 7), here’s the web.config changes:

<system.webServer>

   <modules>

      <add name="CustomerLoggingModule"

         type="HttpModulesPost.CustomerLoggingModule"/>

   </modules>

</system.webServer>

 

As a side note, I set both in the web.config file for IIS 7. I’ve had a couple issues in the past with SharePoint where it didn’t fire the handler properly if I didn’t have both sections registered, and it also will ensure the code will still execute if someone changes the IIS 7 mode.

And just like that, we’ve now got our own little event handler running behind the scenes, quietly logging our customer information or performing whatever little operations we need.