Thursday, 28 March 2013

Set ADFS timeout for Ms Dynamics CRM 2011

I always seem to forget how to this, so I thought I would write myself a reminder here, in script form:

param ($RelyingParty)
{
 Add-PSSnapin Microsoft.Adfs.PowerShell

 Set-ADFSRelyingPartyTrust -TargetName $RelyingParty -TokenLifetime 480
}

If you are not sure what your relying party is called, you can list them with this command:

Get-ADFSRelyingPartyTrust | format-list -Property Name 

or from the ADFS MMC ;)

Saturday, 23 March 2013

Create AD Users from PowerShell

We had to rebuild our test environment and the chap that had created all the test accounts in AD no longer works for the company, so after a bit of digging I came with this script:

Import-Module ActiveDirectory

for($i = 1; $i -le 100; $i++){

$accountname=[string]::format("crmtest{0}",$i)
$principal=[string]::format("{0}@dev.com",$accountname)
$password="P@ssw0rd"


New-ADUser -SamAccountName $accountname -Name $accountname -UserPrincipalName $principal -AccountPassword (ConvertTo-SecureString -AsPlainText $password -Force) -Enabled $true -PasswordNeverExpires $true -Path 'CN=Users,DC=dev,DC=com'

}

Monday, 18 March 2013

How to convert webpage to .mobi or .epub file

The standard advice when anybody answers this question seems to be: Use Calibre, the e-book management software. If you have a Kindle you can also use Amazon's conversion service, which is accessed by sending the webpage as an attachment to your kindle's email address (you do need to white list the email address from which you're sending the email from).

The problem is that neither of them works 100% of the time. There are online alternatives, such as instapaper, which is really handy as it allows you to combine multiple webpages into a single mobi file among other things, but I've never seen an image on any of the instapaper mobi files that I have downloaded, never.

I wrote a little console app that gets rid of the nasty stuff that makes Calibre go pop, it might work with Amazon too, but I've only tried it with Calibre as it's quicker to test.

Please bear in mind that I've only done limited testing, by the time I've done the app, done the tests and so on, I probably could have read all the "problematic" articles online, but there you go.

Also note that you will need the HtmlAgilityPack.

using HtmlAgilityPack;              
using System;              
using System.Collections.Generic;              
using System.IO;              
using System.Linq;              
using System.Text;              
using System.Threading.Tasks;              
              
namespace HTMLCleaner              
{              
 class Program              
 {              
     static void Main(string[] args)              
     {              
       if (args.Length >= 1 && args.Length <= 2)              
       {              
        try              
        {              
            string sourceFile = args[0];              
            string destFile = args.Length > 1 ? args[1] : args[0];              
                            
            HtmlDocument doc = new HtmlDocument();              
                            
            doc.Load(sourceFile);              
                            
            doc.DocumentNode.Descendants()              
                .Where(x => x.Name == "script" || x.Name == "iframe" || x.Name == "noscript").ToList()              
                .ForEach(x => x.Remove());              
                            
            using (StreamWriter sw = new StreamWriter(destFile))              
            {              
                doc.Save(sw);              
            }              
                            
            Console.WriteLine("Successfully cleaned HTML");              
        }              
        catch (Exception ex)              
        {              
            Console.WriteLine("Error: {0} - Type {1}.", ex.Message, ex.GetType());              
        }              
       }      
       else      
       {      
        Console.WriteLine("Please Invoke like this:");              
        Console.WriteLine("HTMLCleaner.exe sourcefile destinationfile");              
        Console.WriteLine("Destination file can be omitted, in which case the source file will also be the destination file");              
       }              
 
     }              
 }              
}              

Wednesday, 13 March 2013

Retrieve OptionSet Label value in MS Dynamics CRM 2011

A method I used to retrieve the label, i.e. text of an option set (I would say more but I honestly can't remember what on Earth we use it for, if we still do use it).

string GetOptionSetLabel(IOrganizationService service, string entityName, string attributeName, int attributeValue)
{
  string result = string.Empty;

  try
  {
      RetrieveAttributeRequest request = new RetrieveAttributeRequest()
      {
        EntityLogicalName = entityName,
        LogicalName = attributeName,
        RetrieveAsIfPublished = true
      };

      RetrieveAttributeResponse resp = (RetrieveAttributeResponse)service.Execute(request);

      if (resp.AttributeMetadata.AttributeType != null && resp.AttributeMetadata.AttributeType == AttributeTypeCode.Picklist)
      {

        result = (from x in ((OptionSetMetadata)((PicklistAttributeMetadata)resp.AttributeMetadata).OptionSet).Options
                  where x.Value == attributeValue
                  select x.Label.UserLocalizedLabel.Label).FirstOrDefault();
      }
      else
      {
          result = "Attribute is not picklist";
      }
  }
  catch (Exception ex)
  {
      result = string.Format("Exception of type {0} occurred: {1}", ex.GetType(), ex.Message);
  }

  return result;
}

Friday, 8 March 2013

Introducing the best remote connection manager: mRemoteNG

I had to reimage my laptop again this week and I thought I had backed everything I needed up before I reimaged it, alas I hadn't. I forgot to backup the connections file for mRemoteNG.

I really like mRemoteNG, it is my one stop shop for remote connections, as it does pretty much every time of connection I might wish to use: RDP, SSH, VNC and more.

The key feature(s), for me, of mRemoteNG is in how it allows to classify connections in many ways to avoid working in the wrong server:

  1. Servers can be grouped in directories, which allows the separation of applications in directories, so that for instance you could put all the connections to your servers for a CRM application in one directory called CRM inside the production directory.
  2. Servers can appear in different tabs (Panels in mRemoteNG parlance). This feature is really useful as it allows to separate environments into different tabs, so that I'm not accidentally working in Prod when I think I'm working in dev or test.
  3. Connections are named. Prepending all your connection names with a suitable prefix will help to ensure that you are working where you think you are.
An example of how things might look like in mRemoteNG, I just created a few at random server connections for the purposes of this post. 



The production servers are on their own tab, Prod, which is separated from the Dev tab, which contains the Dev servers.

The Connections and Config windows can be unpinned so that the full screen is devoted to the remote connection, which is really useful for graphical connections and it also allows Full screen if needed.

Another good feature is that the connections can be exported with or without password, which means that it is really easy to give a new employee an export of all the servers they need to use by simply exporting the connections file without passwords.

If you need to connect to many different servers and you want to be able to quickly change between them, mRemoteNG is a really good solution. The only downside I see is that it has been coded in VB.NET and I don't like VB.NET :).

Tuesday, 5 March 2013

Windows has detected that your computer's performance is slow

It's always reassuring to know that Windows is on the ball. Unfortunately, by the time I took this screenshot and saved it to file, the problem had seemingly gone away, laptop was still as slow as cold treacle, so I could not see what suggestions Microsoft would have for me.

Add more RAM you blithering idiot, perhaps?

Sunday, 3 March 2013

Amazon EC2 Micro instance Linpack (HPL) performance

Amazon allows users to test their cloud for free for the first year, there are of course quite a few limitations, perhaps the most important of which is that you can only use the micro instance, which has 613 MB of RAM, I guess the hypervisor memory footprint must account for the ~150 MB that would make it up to 768 MB of memory usage.

At any rate, I wanted to find out how well these machines would perform on Linpack, so I created a very small, 4 node, cluster using my own instructions and set it to work.

All I can say is that the performance is appalling, the best test was 0.72 Gflops, see below.

It took over an hour to run a problem size of 15000, but unfortunately it crashed before it finished, even so I can't image the performance improving by much. These instances are unlikely to have even a single core all to themselves and network traffic was within Amazon's network rather than dedicated networks.

This is hardly surprising as Amazon has cluster specific instances available, still I'm pretty disappointed at the results.

I might try again with MKL to see if the performance improves somewhat.


================================================================================
T/V                N    NB     P     Q               Time                 Gflops
--------------------------------------------------------------------------------
WR11C2R4        1000   128     2     2               0.93              7.223e-01
--------------------------------------------------------------------------------
||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)=        0.0064465 ...... PASSED
================================================================================
T/V                N    NB     P     Q               Time                 Gflops
--------------------------------------------------------------------------------
WR11C2R4        5000   128     2     2             254.06              3.282e-01
--------------------------------------------------------------------------------
||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)=        0.0061108 ...... PASSED
================================================================================
T/V                N    NB     P     Q               Time                 Gflops
--------------------------------------------------------------------------------
WR11C2R4       10000   128     2     2             965.92              6.903e-01
--------------------------------------------------------------------------------
||Ax-b||_oo/(eps*(||A||_oo*||x||_oo+||b||_oo)*N)=        0.0060791 ...... PASSED
================================================================================

Finished      3 tests with the following results:
              3 tests completed and passed residual checks,
              0 tests completed and failed residual checks,
              0 tests skipped because of illegal input values.
--------------------------------------------------------------------------------

Thursday, 28 February 2013

Removing stack trace from Microsoft Dynamics CRM 2011 log files.

If you've ever had to do any serious troubleshooting with MS Dynamics CRM, you know how annoying the log files can get with all the stack trace information that 99% of the times tells you nothing of use.

You can use the following PowerShell commands to remove them. Note that Exception Stack traces will still be there, use \s instead of \t if your really want to get rid of them.
Get-Content CrmTraceFile.log | Select-String "^[\t]" -NotMatch  | Out-File -Width 256 newlogfile.log
You could do it for all files in the trace directory like this, which should be used as a script:
$files = ls
foreach ($file in $files){  
$name = [string]::Format("p_{0}",$file.Name)
 $filepath = [string]::Format("{0}\{1}", $file.DirectoryName,$file.Name)
 get-content -Path $filepath | select-string "^[\t]" -notmatch | out-file $name -width 256 
} 

Monday, 25 February 2013

How to hire experts in a field of which you know nothing about

I went to another interview a few days back, the position that I was interview for was of MS Dynamics CRM developer. The company had decided, god knows why, that their perfectly good .NET system wasn't up to scratch anymore and so they were going to move it to MS Dynamics CRM 2011. It looks as if the head developer might have done some of the Dynamics CRM 2011 certifications, but it doesn't look as if anything else related to Dynamics CRM 2011 might have been done by anybody, other than install it on the dev server.

I was asked three technical questions:
  1. Write a complex SQL query (I was given some tables and asked to write a query to extract the average of some column with some filtering and joining)
  2. Explain how locking works for SQL Server Databases. In particular what was the behaviour of  selects and update statements, see this for details.
  3. How would I debug a WCF service? I don't know, run it from Visual Studio or use a remote debugger.
It is possible that they decided that they did not want me and were looking for a way of closing the interview quickly, but I think that they just didn't know what would prove my knowledge of, or lack thereof,  Dynamics CRM 2011 so they asked me about stuff that they knew about as some sort of knowledge proxy.

I must admit that I've never been in a position to make a decision about hiring anybody, I have looked over many CVs, but never actually interviewed anybody, but I simply cannot see how this is a good way of establishing potential performance on a person on any given subject. It is a good way of establishing whether they know about something that you know, but that's not really relevant when you are hiring for something that you don't know, is it?

Granted that these were not random questions but it's hard to see how they enable to make a reasonable guess at anybody's competency on another somewhat related field. How related these are is a matter of opinion.

The salient point is that use knowledge proxies is a bad idea.

At the same time, I must admit that I don't know of a good way of establishing degrees of competency on a particular subject, if you know very little about the subject.

If somebody were to bullshit me about the intricacies of STP or VPNs, I simply wouldn't know because I know very little about those areas, certainly not enough to establish somebody else's competence on the field.

Recruitment agencies could do some of this job, but all they seem to do is look at CVs and ask really bland questions, e.g. so you are comfortable writing plug-ins and custom workflows?. I guess somebody may answer: actually, I haven't got a clue what you are talking about, but it's unlikely. 

At the end of the day they are recruitment people not techies, so they would have to charge more for their services if they had techies to evaluate other techies on competency, but how would these judges of competency by judged themselves and I guess therein lies the problem.


Wednesday, 20 February 2013

Triggering Workflows in Ms Dynamics CRM 2011

Yesterday I was looking at an issue where we were getting two accounts created for each of our callbacks (a custom entity) under certain circumstances.

It turns out that if you have a dialog, workflow or plugin that updates a field, even if the update is to set the field to the same value that it had before, this will trigger any workflows that are watching that field.

The solution is simple, only make the update if it's needed, i.e. check the value before you do the update, but it's perhaps a little bit counter-intuitive as the field has not actually changed.

If you have auditing enabled, you'll be able to see how a change is registered from value to value [sic].