Charteris Community Server

Welcome to the Charteris plc Community
Welcome to Charteris Community Server Sign in | Join | Help
in Search

Ivor Bright's blog

  • Installing .Net 1.1 applications on Windows Server 2008 R2

    I recently needed to get an ASP.Net 1.1 application working on Windows Server 2008 R2. I naively assumed that this was just going to work but then the whole 32/64 bit problem emerged.

    .Net 1.1 is 32 bit only and Server 2008 R2 is 64 bit only! Well – WOW64 has been around quite a while so surely this would be a piece of cake. I proceeded to download the .Net Framework Version 1.1 Redistributable Package and when you attempt to install – you get your first hint about the potential problems ahead.

    At this stage – you have 2 choices:

    • Attempt to upgrade your application to a 64 bit version of the framework
    • Attempt to get .Net 1.1 working on Server 2008 R2

    My preference was to get .Net 1.1 working as I didn’t want to go through a test cycle for an application I didn’t really understand on a new version of the framework. However – rather than just choosing “Run Program” from the Program Compatibility Assistant dialog – I did some research and used the following process to get my application to work.

    1 - Install IIS Metabase Compatibility

    To install on Windows 2008 Server – click Start and then “Server Manager”.

    Under Web Server (IIS), click Add Role Services.

    Ensure that IIS Metabase Compatibility is installed.

    2 - Install .Net 1.1

    I installed .Net 1.1 in the following order:

    I still got a compatibility warning, but chose “Run Program” to continue.

    Installing Service Pack 1 is likely to require a reboot.

    3 – Enable ASP.Net 1.1 ISAPI Extension

    Following the steps in option 2 made ASP.NET v1.1.4322 available on my ISAPI and CGI Restrictions dialog, but was disabled by default. Open Internet Explorer, click on your server name and choose ISAPI and CGI Restrictions from the IIS section. Enable ASP.Net v1.1.4322 as a valid ISAPI extension.

    4 – Adjust machine.config

    We need ASP.NET 1.1 to ignore IIS configuration sections, so open machine.config for Framework 1.1 (%windir%\Microsoft.NET\Framework\v1.1.4322\config\machine.config) and add the following towards the end of configSections.

       1: <section name="system.webServer" type="System.Configuration.IgnoreSectionHandler, 
       2:     System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 

    5 – Adjust the Application pool

    I now needed to tell my application to use the application pool ASP.NET 1.1. Use IIS Manager, choose the site that you are working with and choose “Advanced Settings”. Adjust the application pool to use ASP.NET 1.1 which will use .Net Framework 1.1.

    6 – Fix applicationHost.config bug

    IIS runtime detected that I was running on a 64 bit operating system, so it attempted to load .net framework configuration from Microsoft.Net\Framework64, but this doesn’t exist for .Net Framework 1.1. The solution is to copy the 32 bit version into the appropriate 64 bit folder.

    • Create \Windows\Microsoft.net\Framework64\v1.1.4322\config
    • Copy machine.config from \Windows\Microsoft.net\Framework\v1.1.4322\Config\

    7 - Check any application registry settings

    My application relied upon a number of custom application registry settings. In the 32 era – this wasn’t a problem as registry settings were in the “same” expected place. e.g. people often put registry settings under HKEY_LOCAL_MACHINE \ SOFTWARE \ [CompanyName]. However – on a 64 bit machine – the 64 bit software settings are stored in this expected place, while 32 bit settings are stored under HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ [CompanyName]. I initially exported the keys from an existing Server 2003 machine and imported them onto Server 2008 which put them into HKEY_LOCAL_MACHINE \ SOFTWARE \ [CompanyName], but because my application is 32 bit running on a 64 bit platform – it was trying to read them from HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ [CompanyName]

    The result was a lot of pain and confusion trying to understand why my application couldn’t read registry settings which were obviously there.

    The solution is to put your 32 bit registry settings where they need to be – under Wow6432Node.

    Finally, after following all of the above – my 32 bit .net 1.1 application  was working correctly on Server 2008 R2.

    Useful links

    Technorati Tags: ,
  • Sync Framework 2.0 Series – Part 2 – Using Local Database Caching for an occasionally connected application.

    This is part 2 in the Sync Framework 2.0 series and deals with building an occasionally connected application using Local Database Caching. Part 1 in the series dealt with installing the Sync Framework and using the File Sync Provider.

    My original goal with this post was to see if I could use the Sync Framework to build a C# version of SQL Replication to keep two SQL Server databases in sync. However – I found a limited amount of information available in the public domain, so I have decided to take an initial step into SQL Synchronisation by building an “occasionally connected application” using Local Database Caching. The basic idea is to build something like the following:

    Users of the application can work in local mode where all their changes are persisted to a local database, and at intervals they can sync their changes back to the main corporate database. The best initial source of information I found for this type of application was on MDSN called “Occasionally Connected Applications” – an excellent series of articles that discuss various aspects of this topic. The manner you approach this type of application depends upon what technologies you are going to use to build it – for my example – I’m going to use SQL Server 2008 R2, Visual Studio 2010 and of course – Sync Framework 2.0.

    When it comes to tracking database changes, there are 2 general approaches that can be taken.

    • Add columns and triggers to the tables being monitored.
    • Use SQL Server Change Tracking

    In general – I find Database Administrators quite reluctant to add columns to tables for this kind of work. Generally – the application is in production when someone decides that they would like to be able to add a disconnected approach, and it is often considered to risky to add these additional tracking columns and triggers. Other people don’t like mixing the data we need to store for an entity with metadata we use to embellish an entity. For this reason – I’m going to focus on using SQL Server Change Tracking and further details on change tracking can be found on MSDN.

    First step is to choose the data that your application needs to work with. I wanted an example that was as simple as possible so I chose the pubs database. pubs isn’t installed by default on SQL Server 2008, so I had to download the database from Microsoft. After attaching to SQL Server 2008 – I came across my first stumbling block – using the Local Database Caching wizard (more on this later) didn’t detect it as a database which I could use SQL Server Change Tracking on as “Use SQL Server change tracking” was disabled.

    I struggled to find useful information on the internet about this using my favourite search engine (perhaps I was using poor search criteria?), but in the end I made a lucky guess – perhaps it didn’t like my database as it wasn’t really a SQL Server 2008 database? It was really a SQL Server 2000 database attached to SQL Server 2008. I quickly created a new database and used the Data Import Wizard to copy the “authors” table from pubs to my new database and while this was a step forwards as “Use SQL Server change tracking was now enabled”, my next stumbling block was that it wouldn’t let me add a new Cached Table - the Add button was disabled!

    More lost time using my favourite search engine and another lucky guess solved my problem – perhaps it was to do with the way my authors table was created. The Data Import Wizard created my table as well as copying the contents, and it decided not to create a primary key. Sync Framework likes primary keys so a quick “Add Primary Key” operation later – and the Local Database Caching wizard was a lot happier.

    To recap – when you are choosing your data source which you wish to use for an occasionally connection application and you want to use SQL Server Change Tracking – make sure its SQL Server 2008 and you have a primary key on any table that you want to synchronise.

    Now we have our data that we want to synchronise – let’s start building our application. I’m going to use a simple WinForms Desktop application. Tweak the default form so we have a tab control with 2 tabs – one to display the contents on the server and one to display the contents on our client and some buttons to perform useful operations. I’ve built the following:

    Right click the project and choose “Add New Item” and on the Data section – choose “Local Database Caching”. This will bring up the “Configure Data Synchronisation” wizard where you specify the data that you wish to use. Specify the Server connection for the source of the data and the Client connection should default to a new Compact database. Choose the table which you wish to cache by clicking the Add button. The dialog should look something like the following:

    Next step in the wizard is to choose the database model, and I went with the Dataset approach. This is good for getting a prototype up and running, but if you are building something for a production environment – you might want to consider using an Entity Data Model.

    You end up with a typed dataset for the local version of the authors table. Visual Studio will have added references to Microsoft.Synchronisation, Microsoft.Synchronisation.Data, Microsoft.Synchronisation.Server and Microsoft.Synchronisation.ServerCe but it managed to completely screw up the references on my machine. I’m working on a 64 bit machine and it created a strange hybrid of 32 and 64 bit references. I manually removed and re-added all 64 bit references on my machine and then changed the target platform to be “Any CPU” (It had defaulted to x86).

    Next step is populate the client DataGridView and this requires minimal coding. I have 2 form level variables as follows:

       1: #region Variables
       2:  
       3: private AuthorsDataSet authorsClientDataSet = new AuthorsDataSet();
       4: private AuthorsDataSetTableAdapters.AuthorsTableAdapter authorsClientAdapter = 
       5:     new AuthorsDataSetTableAdapters.AuthorsTableAdapter();
       6:  
       7: #endregion

    In the event handler for the click event for the populate button on the client tab – I have the following code:

       1: /// <summary>
       2: /// Populate the client data grid view control
       3: /// </summary>
       4: /// <param name="sender"></param>
       5: /// <param name="e"></param>
       6: private void buttonClientAuthorsPopulate_Click(object sender, EventArgs e)
       7: {
       8:     try
       9:     {
      10:         authorsClientAdapter.Fill(authorsClientDataSet.Authors);
      11:  
      12:         this.dataGridViewClientAuthors.DataSource = authorsClientDataSet.Authors;
      13:     }
      14:     catch (Exception Ex)
      15:     {
      16:         MessageBox.Show("Failed to populate the client - perhaps the client compact " +
      17:             "database hasn't been created yet!" + Environment.NewLine + Ex.Message);
      18:     }
      19: }

    To make our prototype easy to test – it’s useful to be able to change and save the data using the application (rather than testing by changing the data directly in the database), so I implemented the save functionality for the client as follows:

       1: /// <summary>
       2: /// Save any changes on the client
       3: /// </summary>
       4: /// <param name="sender"></param>
       5: /// <param name="e"></param>
       6: private void buttonClientSave_Click(object sender, EventArgs e)
       7: {
       8:     try
       9:     {
      10:         this.Validate();
      11:         this.dataGridViewClientAuthors.EndEdit();
      12:         this.authorsClientAdapter.Update(this.authorsClientDataSet);
      13:  
      14:         PopulateClient();
      15:         MessageBox.Show("Saved");
      16:     }
      17:     catch(Exception ex)
      18:     {
      19:         MessageBox.Show("Error " + ex.Message);
      20:     }
      21: }

    In order to make the server tab work, I decided to manually add a typed dataset for the server version of the authors table. There were a number of ways I could have made the server tab work, but using a typed dataset meant that the code looked very similar to the client version.

    You should now have working versions of the server and client tabs which allow you to view, change and save values. Next step is to implement the Synchronisation functionality – we want the user to be able to perform synchronisations between their local database and the central server database. Initial implementation for performing the synchronisation is very straightforward:

       1: /// <summary>
       2: /// Perform a database change sync between our client and the server.
       3: /// </summary>
       4: /// <param name="sender"></param>
       5: /// <param name="e"></param>
       6: private void buttonSync_Click(object sender, EventArgs e)
       7: {
       8:     AuthorCacheSyncAgent syncAgent = new AuthorCacheSyncAgent();
       9:     Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
      10:  
      11:     PopulateServer();
      12:     PopulateClient();
      13:     
      14:     StringBuilder message = new StringBuilder();
      15:     message.Append("Changes downloaded: ");
      16:     message.Append(syncStats.TotalChangesDownloaded.ToString());
      17:     message.AppendLine();
      18:     message.Append("Changes uploaded: ");
      19:     message.Append(syncStats.TotalChangesUploaded.ToString());
      20:  
      21:     MessageBox.Show(message.ToString());
      22: }

    When I tried to run my application for the first time – it failed with the following error: “The specified change tracking operation is not supported. To carry out this operation on the table, disable the change tracking on the table, and enable the change tracking.” More frantic searching but at least I found other people having the same problem. The easiest way to get rid of this exception is to set the “Copy to Output Directory” for your local compact database to “Do not copy”.

    You should now have a working “occasionally connected application” which can synchronise changes from the server to your client. However – what if you want to be able to synchronise both ways? This is actually easy to achieve – you just need to implement the OnInitialized() method in the cache file that the wizard generated.

       1: /// <summary>
       2: /// Code generated Sync Agent which we can extend
       3: /// </summary>
       4: public partial class AuthorCacheSyncAgent 
       5: {
       6:     /// <summary>
       7:     /// Initialise the sync agent to perform a bidirectional sync.
       8:     /// </summary>
       9:     partial void OnInitialized()
      10:     {
      11:         Authors.SyncDirection = SyncDirection.Bidirectional;
      12:     }
      13: }

    This allows you to perform a 2 way sync. However – what happens if you change a record on both the server and the client and perform a sync. The behaviour you should find is that the server always wins and the client change is thrown away. What happens if this isn’t the behaviour you require? You can add custom conflict handling by extending the client and server sync provider that the wizard generated. Delve into the generated code to find the names of the client and server providers, and create a partial class for the client provider as follows:

       1: /// <summary>
       2: /// Extends the code generated client sync provider for authors.
       3: /// </summary>
       4: public partial class AuthorCacheClientSyncProvider
       5: {
       6:     /// <summary>
       7:     /// Allows the main form to configure the event handler for the 
       8:     /// ApplyChangeFailed event
       9:     /// </summary>
      10:     public void AddHandlers()
      11:     {
      12:         this.ApplyChangeFailed +=
      13:             new System.EventHandler<ApplyChangeFailedEventArgs>
      14:             (AuthorCacheClientSyncProvider_ApplyChangeFailed);
      15:     }
      16:  
      17:     /// <summary>
      18:     /// Allow the client to win a conflict by choosing to continue.
      19:     /// </summary>
      20:     /// <param name="sender"></param>
      21:     /// <param name="e"></param>
      22:     private void AuthorCacheClientSyncProvider_ApplyChangeFailed(object sender,
      23:         Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
      24:     {
      25:  
      26:         if (e.Conflict.ConflictType ==
      27:             Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate)
      28:         {
      29:             e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue;
      30:         }
      31:     }
      32: }

    Similarly – create a partial class for the server provider as follows:

       1: /// <summary>
       2: /// Extend the server sync provider for authors to allow a client to win a conflict.
       3: /// </summary>
       4: public partial class AuthorCacheServerSyncProvider
       5: {
       6:     /// <summary>
       7:     /// Hooks up the ApplyChangeFailed event handler.
       8:     /// </summary>
       9:     partial void OnInitialized()
      10:     {
      11:         this.ApplyChangeFailed +=
      12:             new System.EventHandler<ApplyChangeFailedEventArgs>
      13:             (AuthorCacheServerSyncProvider_ApplyChangeFailed);
      14:     }
      15:  
      16:     /// <summary>
      17:     /// When a conflict occurs, force write the client change.
      18:     /// </summary>
      19:     /// <param name="sender"></param>
      20:     /// <param name="e"></param>
      21:     private void AuthorCacheServerSyncProvider_ApplyChangeFailed(object sender,
      22:         Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
      23:     {
      24:         if (e.Conflict.ConflictType ==
      25:             Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate)
      26:         {
      27:             string message = "A client/server conflict was detected at the server.";
      28:             MessageBox.Show(message);
      29:             e.Action = Microsoft.Synchronization.Data.ApplyAction.RetryWithForceWrite;
      30:         }
      31:     }
      32: }

    Finally you need to tweak the implementation to perform the synchronisation as follows:

       1: /// <summary>
       2: /// Perform a database change sync between our client and the server.
       3: /// </summary>
       4: /// <param name="sender"></param>
       5: /// <param name="e"></param>
       6: private void buttonSync_Click(object sender, EventArgs e)
       7: {
       8:     AuthorCacheSyncAgent syncAgent = new AuthorCacheSyncAgent();
       9:     AuthorCacheClientSyncProvider clientSyncProvider = 
      10:         (AuthorCacheClientSyncProvider)syncAgent.LocalProvider;
      11:     clientSyncProvider.AddHandlers();
      12:  
      13:     Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
      14:  
      15:     PopulateServer();
      16:     PopulateClient();
      17:  
      18:     StringBuilder message = new StringBuilder();
      19:     message.Append("Changes downloaded: ");
      20:     message.Append(syncStats.TotalChangesDownloaded.ToString());
      21:     message.AppendLine();
      22:     message.Append("Changes uploaded: ");
      23:     message.Append(syncStats.TotalChangesUploaded.ToString());
      24:  
      25:     MessageBox.Show(message.ToString());
      26: }

    The latest implementation now means that the client always wins and the server change is throw away.. In reality you might want to prompt the user or log the details and allow manual intervention, but at least we can control how we manage the conflict.

    This prototype application can be downloaded from here. You will need to create a SQL Server 2008 database with an Authors table containing the standard authors information. I used a SQL ConnectionString for a user called sqlsync but you can edit these in the app.config.

    Hopefully you will agree with me that using the Local Database Cache means that we don’t have to write much code in order to produce a working occasionally connected application.  However – the main problems are limited example in the public domain and some puzzling times when things don’t work quite as expected!

    Technorati Tags:
  • Sync Framework 2.0 Series – Part 1 – Using the File Sync Provider

    This is the beginning of what will hopefully become a series of posts about Microsoft Sync Framework 2.0.

    Microsoft Sync Framework is “A comprehensive synchronization platform that enables collaboration and offline access for applications, services, and devices with support for any data type, any data store, any transfer protocol, and any network topology”. I wanted to use the sync framework recently but struggled to find really good content using my favourite search engine. I decided to work through some of the samples in the SDK and try and explore around some of the issues, and hopefully my experiences will help jump-start others who wish to use the platform.

    The best place to start reading is on msdn at the Microsoft Sync Framework Developer Center

    One of the first things you will want to do is download the Sync Framework 2.0 SDK and this can be found at: Sync Framework 2.0 SDK.

    I’m using Visual Studio 2010 to develop a Windows Forms application so the first thing I needed to do was add a reference to Microsoft.Synchronisation and Microsoft.Synchronisation.Files. However – a gotcha (at least on my machine) are that the available references on the .Net tab are for Sync Framework 1.0. Its worth checking the Path column on the Add References dialog to make sure you are adding a reference to Sync Framework 2.0. In the end – I did a Browse to the SDK folder and added my reference that way. Some constructors etc have changed subtly from version 1.0, so you need to use the right sample with the right version of the SDK to make things a bit easier.

    Another gotcha that I came across is that my Visual Studio 2010 defaulted my Windows Forms Application to a platform target of x86 despite the fact that I was using a 64 bit machine. This became an issue as I had installed the 64 bit version of the Sync Framework SDK, so I started getting run time exceptions like the following: "Retrieving the COM class factory for component with CLSID {C201C012-C929-4D72-B9C5-341D48630630} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).". After a lot of frustration – I found by changing the platform target to “Any CPU”, my run time COM error went away.

    I think the issue is created by the managed implementation actually being a wrapper around the real non managed implementation, so when I installed the 64 bit version of the SDK – I got the 64 bit registry entries. When Visual Studio built the 32 bit version of the application – it couldn’t find the 32 bit registry entries and gave me a run time error.

    I wanted to build an example that looked and worked a bit like SyncToy. If you are unfamiliar with SyncToy – its “a free application that synchronizes files and folders between locations. Typical uses include sharing files, such as photos, with other computers and creating backup copies of files and folders.” and is actually built with Sync Framework 2.0.

    So some might ask the question – why build something when a solution already exists and my answer is that its allows me to extend the solution beyond SyncToy. e.g. It would be relatively easy to extend my solution to use a Windows service and FileSystemWatchers to detect changes to the file system and automatically initiate a synchronisation. SyncToy simply initiates a synchronisation on demand.

    My example prompts the user for a source and target folder, and the user can press a button to synchronise the files between the 2 folders. To get a simple example working, you need to create a FileSyncProvider for the source folder, a FileSyncProvider for your target folder and a SyncOrchestrator to perform the synchronisation operation. I’ve put my code into a class, and my button click event handler calls it.

       1: /// <summary>
       2: /// Perform a simple synchronisation
       3: /// </summary>
       4: public class SimpleSyncHelper
       5: {
       6:     /// <summary>
       7:     /// Perform the synchronisation
       8:     /// </summary>
       9:     /// <param name="sourceFolder"></param>
      10:     /// <param name="targetFolder"></param>
      11:     public void PerformSynchronisation(string sourceFolder, 
      12:         string targetFolder)
      13:     {
      14:         FileSyncProvider sourceProvider = new FileSyncProvider(sourceFolder);
      15:         FileSyncProvider targetProvider = new FileSyncProvider(targetFolder);
      16:  
      17:         SyncOrchestrator agent = new SyncOrchestrator();
      18:         agent.LocalProvider = sourceProvider;
      19:         agent.RemoteProvider = targetProvider;
      20:         
      21:         // Perform 2 way sync
      22:         agent.Direction = SyncDirectionOrder.UploadAndDownload; 
      23:         agent.Synchronize();
      24:     }
      25: }

    This works really well but when I looked at the file synchronisation example from the SDK, it was coded differently and the piece that attracted my attention was: “Explicitly detect changes on both replicas upfront, to avoid two change detection passes for the two-way sync”. It turns out that the implementation of SyncOrchestrator-Synchronize() actually splits the operation into 2 – 1 to perform the upload and 1 to perform the download. When it performs the upload part – it detects changes on both the source and the target, and when it performs the download part – it detects changes on both the source and target. This effectively means that 4 “detect change” operations are performed and explains why the SDK sample was keen to avoid the two change detection phases.

    To prove to yourself that the code performs as above, hook up a DetectingChanges event handler for both the sourceProvider and the targetProvider and add a MessageBox.Show() to the handler and you should observer 4 message boxes.

    To get around the two change detection passes, you should perform an explicit detection on both the source and the target.

       1: /// <summary>
       2: /// Perform a DetectChange operation on a FileSyncProvider.
       3: /// </summary>
       4: /// <param name="replicaRootPath"></param>
       5: /// <param name="filter"></param>
       6: /// <param name="options"></param>
       7: private void DetectChangesOnFileSystemReplica(string replicaRootPath, 
       8:     FileSyncScopeFilter filter, FileSyncOptions options)
       9: {
      10:     using (FileSyncProvider provider = new FileSyncProvider(replicaRootPath,
      11:         filter, options))
      12:     {
      13:         provider.DetectChanges();
      14:     }
      15: }

    The Framework captures the change information which can then be used later in the synchronisation process. You can then change your code that instead of performing a SyncDirectionOrder of UploadAndDownload – you perform 2 SyncDirectionOrder with a value of Upload – once between the source and the target and once between the target and the source. Make sure you use the FileSyncOptions.ExplicitDetectChanges to prevent unnecessary change detection passes.

    As well as the DetectingChanges event, there are a number of other EventHandlers that you can hook up on a FileSyncProvider to get useful information:

    • ApplyingChange – occurs when a change is about to be applied.
    • AppliedChange – occurs when a change has been applied
    • SkippedChange – occurs when a change is skipped.

    The return value from a SyncOrchestration – Synchronise() operation is of type SyncOperationStatistics and it contains useful information about the changes applied as part of the synchronisation. This could be used to display a report for the user after the synchronisation operation. It contains properties like:

    • UploadChangesApplied – total number of changes that were successfully applied during the upload session.
    • DownloadChangesApplied – total number of changes that were successfully applied during the download session.
    • SyncStartTime – when the synchronisation started.
    • SyncEndTime – when the synchronisation ended.

    So far – we have seen how we can listen for events occurring as part of the synchronisation, and get details for a report at the end of the synchronisation, but what if we want to display a progress bar to indicate to the user how long is left in the synchronisation process? The Sync Framework doesn’t provide this kind of functionality by default as it would incur a reasonable overhead which would be wasted for those who do not require it. However – the FileSyncProvider does provide a preview mode! When this is set to true – it performs all the work of calculating what changes need to be made without actually performing the changes. This allows us to perform the operation initially in preview mode to calculate what changes need to be applied (which we can access by looking at the SyncOperationStatistics), we can capture the events from the operation and display accurate progress information to the user.

    I’ve put all of the above information into a sample application that looks like the following:

    The source code for this sample application can be downloaded from here.

    Hopefully future posts in this series will demonstrate the use of other providers in Microsoft Sync Framework 2.0.

    Technorati Tags:
  • Windows PowerShell Series - Part 8 – Working with Variables

    This is part 8 in a series of posts related to Windows PowerShell, and deals with working with Variables.

    Those from a programming background will be very used to dealing with variables – it is something we take for granted when doing development. Without variables – it would be very difficult to write any useful scripts as we wouldn’t have anyplace to remember working values.

    Variables in Windows PowerShell are prefixed with the dollar sign ($).Variable names are not case sensitive but you should be consistent to make your life easier. By default – any variables you create will exist only in the current session and will be lost when you end your session. There are 4 types of variable:

    • Automatic – these are created and maintained by Windows PowerShell and users cannot change their values. e.g. $PSHome stores the path to the Windows PowerShell installation directory.
    • Preference – these are created by Windows PowerShell with default values which the user can change. e.g. $MaximumVariableCount determines how many variables are permitted in a given session.
    • Environment – these store information about the operating system environment. To list all environment variables – use Get-ChildItem Env:
      or to get details about a particular environment variable – use Get-ChildItem Env:ComputerName
    • User created – these are variable which are created and maintained by the user. When someone refers to a variable – they usually mean this type of variable. e.g. $Today = (Get-Date).date

    Windows PowerShell variables are loosely typed which mean they are not limited to a particular variable type of object. The type of a variable is determined by the value it contains. e.g.

    Variables1

    In general – most programming languages (like C#) are strongly typed. There can be a number of advantages that using strong types can bring:

    • Limit the range of values that a variable can contain. e.g. limiting a variable like $Age to integer values. Compilers and other tools can check that we are putting sensible values into appropriate variables.
    • Improved clarify. e.g. if a “+” operation is performed on 2 integer variables -  then we always need to perform an addition. If a “+” operation is performed on 2 string variables – then we always need to perform a string concatenation. With loose/weak typing – the operation depends on the contents of the variables so isn’t always clear.
    • Improved Performance – optimisations can often be made when the type is known in advance rather than being determined “on the fly”

    Windows PowerShell allows us to use the type attribute and cast syntax to constrain a variable to a particular type. Some examples include:

    Variables2

    There are a number of Cmdlets which are designed for manipulating variables. These include:

    • Clear-Variable – Deletes the value for a variable
    • Get-Variable – Gets the variables in the current console
    • New-Variable – Creates a new variable
    • Remove-Variable – Deletes a variable and its value
    • Set-Variable – Changes the value of a variable.

    Variables3

    Windows PowerShell allows us to create constant and read-only variables. While constants and read-only variables are functionality very similar – one difference is that you can delete a read-only variable while you cannot delete a constant. To create constants and read-only variables, use:

    Variables4

    See the following for useful information about PowerShell variables:

    Next step – Working with Logic

    Previous step – What the heck is a Cmdlet?

    Technorati Tags:
    Posted Jun 29 2010, 02:49 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 7 – What the heck is a Cmdlet?

    This is part 7 in a series of posts related to Windows PowerShell, and deals with cmdlets.

    Cmdlets (pronounced command-lets) are the smallest units of functionality in Windows PowerShell. They are named in a very specific verb-noun format that should make it obvious what operation the cmdlet performs.

    e.g. Get-Date returns the current date and time while Set-Date allows you to set the current date and time.

    A useful cmdlet when starting out with Windows PowerShell is Get-Command which returns a complete list of available cmdlets.

    Get-Command

    The example above also demonstrates pipelining where the output from the Get-Command cmdlet is piped (or redirected) to Format-Wide

    Get-Help is also useful in discovering information about available cmdlets, and its output includes some summary information about each cmdlet.

    Get-Help

    To get detailed information about a particular cmdlet, use Get-Help “cmdlet name”.

    Get-Help

    There are 2 other variations of Get-Help which provide different levels of information for a cmdlet:

    • Get-Help “cmdlet” –detailed
    • Get-Help “cmdlet” –full

    You can pass parameters to a cmdlet by using the a dash (-) notation. e.g. if you want to get the current date, but not include the time aspect, you can use the following:

    cmdlet parameters

    Some standard cmdlets which I recommend looking at include:

    • Get-Command – Get information about cmdlets
    • Get-EventLog – Gets events fro man event log
    • Write-EventLog – Writes an event to the event log
    • Get-Host – Gets information about the host application
    • Get-Location – Gets information about your current working location.
    • Get-Variable – Gets a particular variable
    • Ping-Computer – Sends a ping
    • Read-Host – Reads information from the host window
    • Write-Host – Writes information to the host window.
    • Start-Service – starts a particular service

    Use Get-Help *-* to discover other useful cmdlets.

    Next step – Working with Variables

    Previous step – Getting to grips with Scripts

    Technorati Tags:
    Posted Jun 25 2010, 04:14 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 6 – Getting to grips with Scripts

    This is part 6 in a series of posts related to Windows PowerShell, and deals with getting to grips with scripts..

    So far – we have been typing commands into the PowerShell console (or the ISE) but what happens if you want to create some functionality which you can reload at a future session. The answer is to create your PowerShell commands as a PowerShell script.

    You can either go hard-core and use something like Notepad (or your text editor of choice) to create the script, or you can use the ISE to create and save your script. When saving the script – give it a “.ps1” file extension so PowerShell knows that it’s a script file and not a text file. The extension comes from PowerShell 1.0 and they didn’t feel the need to change the extension for PowerShell 2.0. As you would expect – PowerShell 2.0 can run PowerShell 1.0 scripts, but the reverse is not guaranteed.

    Let’s start with our first script – the typical Hello World script!

    HelloWorld

    Save this as HelloWorld.ps1 (or similar). To make your life easier for the moment – make sure there is no space in the file name or anywhere in the path that contains the file name. We’ll worry about handling spaces in a later post.

    The logic for this script is extremely simple:

    • Clear the output
    • Prompt the user their name and store in a variable
    • Say hello and repeat the users name by accessing the variable.

    You have a number of choices to run this script:

    • Run it from inside the ISE by pressing F5
    • Run it from inside the ISE or PowerShell Console by typing the script name (including path) into the command prompt
    • Run it from a standard console prompt by using the following: powershell [FilePath]\HelloWorld.ps1 where [FilePath] is your relevant directory structure. In my case – my script is stored on my desktop so I’m executing powershell c:\Users\IvorB\Desktop\HelloWorld.ps1"

    There you go – you should now have a working Hello World script!

    As mentioned in Part 4 of this blog series – security measures are in place to prevent scripts executing without your permission. You have 2 choices at this stage – to digital sign your script, or to adjust your execution policy to allow execution of unsigned scripts. The easiest (and laziest) way to get this to work is to change the execution policy which you can do with the following command:

    Set-ExecutionPolicy RemoteSigned.

    Next step – What the heck is a Cmdlet?

    Previous step – The Integrated Shell Environment (ISE)

    Technorati Tags:
    Posted May 11 2010, 03:13 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 5 – The Integrated Shell Environment (ISE)

    This is part 5 in a series of posts related to Windows PowerShell, and deals with using the Integrated Shell Environment.

    So far we have been using the PowerShell Command Shell to execute PowerShell statements but you also have the option of using the Integrated Shell Environment.This is a more graphical rich interface for using PowerShell.

     PowerShellISE

    You can launch it in similar ways to the PowerShell Command Shell:

    • All Programs > Accessories > Windows PowerShell > Windows PowerShell ISE
    • From a command line prompt (e.g. cmd), type powershell_ise (note the underscore)
    • Start menu > Search > type powershell_ise (note the underscore)
    • [Win] + R (for Run command) > type powershell_ise (note the underscore)

    The ISE interface is made up of the following:

    • Script/Editor pane – this is where you will spend most of your time creating scripts. Tabs across the top of the pane allow you to work on multiple scripts at the same time.
    • Output pane – this is where the output from executing your script is displayed.
    • Command pane – you can enter ad-hoc commands in this pane. It effectively behaves as a standard PowerShell Command Shell

    This type of interface is a bit more familiar to those who are used to Visual Studio, although perhaps a little basic in direct comparison:

    • You have a text area where you can enter your script
    • Your have toolbar buttons to control script execution
    • You have basic debugging facilities.
    • Useful context sensitive help – highlight a command in the script window and press F1
    • Execute part of the scripts without running the whole thing (highlight the text you want to run and choose “Run Selection”
    • You can customise the environment by changing $psISE.Options including adding new menu options.

    The first time I attempt to debug a script in the ISE – I couldn’t figure out how to set a breakpoint. Coming from a Visual Studio background – I am used to creating a breakpoint whenever and where-ever I like. However – the ISE refused to create my breakpoint. I eventually figured out that you simply need to save your script and you then get access to the debugging facilities. You also need to remember that breakpoints are only remembered for your session – once you close the ISE and fire it up again – you’ve lost all your previous breakpoints.

    At this stage, its also worthwhile mentioning that Quest provides a free graphical user interface and script editor for Windows PowerShell called PowerGUI. This is definitely worth a look if you are going to be doing a lot with PowerShell.

    Next step – Getting to grips with scripts

    Previous step – Customise via Commands

    Technorati Tags:
    Posted May 10 2010, 04:52 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 4 – Customise via Commands

    This is part 4 in a series of posts related to Windows PowerShell, and deals with customising the PowerShell console through use of PowerShell commands.

    We’re seen previously how you can Customise the appearance of the PowerShell command by tweaking the properties of the console. However, you can also issue PowerShell commands which affect the appearance of the console.

    The command Get-Host gives you a reference to ConsoleHost object. This has a UI property which manages a lot of the UI details for the console, and this in turn has a RawUI property which gives access to colour, title etc. e.g. (Get-Host).UI.RawUI gives the following:

    Get-Host

    We use brackets around Get-Host to ensure this is evaluated first, before we access the UI property of the return object.

    If you want to save a bit of typing, you can use $Host.UI.RawUI to return the same information. $Host is a special variable that is a reference to the current console object.

    The property values can be changed, so you can do something like the following to get a console that looks like a standard command console:

    CommandPrompt

    If you change some of the properties like background-color, you might want to use the command Clear-Host to “refresh” the entire console window.

    Changing the Window Size or Position is slightly more complicated as these are “complex” objects rather than simple properties. The easiest way to change these types of properties is to store the current value in a variable, and then adjust property values on the variable. e.g:

    WindowSize

    Here we store the current WindowSize in a variable called $WindowSize, adjust its Width property and then set the WindowSize back to the Console.

    It would be quite tedious if you had to issue the same commands to setup your Console environment every time you wanted to use PowerShell, so the solution is to adjust your profile. You can find out where your current/active profile is stored by viewing the special variable $profile. You should find that your default profile is stored in a file called something like Microsoft.PowerShell_profile.ps1. You can now put whatever commands you like in this file (by using Notepad or similar) and these commands will be executed every time you start a PowerShell console. If the folder or file don’t already exist – just create them and everything should just work fine.

    You might find that the first time you try this, that you get an error like “Microsoft.PowerShell_profile.ps1 is not digitally signed”. This is deliberate by Microsoft to prevent scripts executing without your permission. We’ll discuss signing of scripts and execution policies in a later article, but for the moment – the fastest  (and laziest) way to get this to work is to change PowerShell to allow execution of local scripts which are unsigned. You can do this by issuing the following PowerShell command:

    Set-ExecutionPolicy RemoteSigned

    You can find loads of information about customising the PowerShell console at the following location: Customise the PowerShell Console

    Next step – The Integrated Shell Environment (ISE)

    Previous step – Customise the Console

    Technorati Tags:
    Posted May 05 2010, 11:48 AM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 3 – Customise the Console

    This is part 3 in a series of posts related to Windows PowerShell, and deals with customising the PowerShell console.

    If you use the PowerShell console frequently, it is probably worth spending a bit of time to customise it to your exact tastes. You are going to be looking at the console quite a bit, so you may as well have it exactly the way you want it!

    Properties

    To begin customising your console, fire up the PowerShell console and right click the title bar and choose properties. From the properties menu, you then have the choice of 4 tabs:

    • Options
    • Font
    • Layout
    • Colours

    Options

    • Cursor Size: Fairly obvious – I find the default of “small” fine for normal use.
    • Command History: The command history is a buffer of previous commands in the current session. You can access previous commands in the session by using the arrow keys (up and down and press Enter to choose a particular command),  press F7 to display a pop up window that contains the list of buffered commands or type the first few letters of the command to execute and press F8.
    • Edit Options: QuickEdit mode allows you to single mouse click to paste into the command window (rather than right clicking and choosing paste). InsertMode means that you default to inserting a new command and clearing this option means that you overwrite text as the default editing mode.

    Font

    • Allows you to adjust the font used in the console window. I personally increate the font size to “12 x 16” which I find easier on the eye.

    Layout

    • Screen Buffer Size: This controls the virtual window size which is the amount of content the window can actually hold. If the virtual window size is larger than the actual window size, then the console window changes to include scrollbars.
    • Window Size: The size of the physical window. You should probably make the width the same as the screen buffer size width to avoid horizontal scroll bars.
    • Window Position: Uncheck Let system position window if you want to control the initial position of the window.

    Colours

    • Allows you to set the foreground and background colours used by the PowerShell console.

    Click OK to save your settings to your user profile. Note: You may need to run PowerShell as Administrator in order for your settings to be saved. It is also worth noting that your changes are only applicable to the shortcut that you used to start PowerShell.

    Next step – Customise via Commands

    Previous step – Installation

    Technorati Tags:
    Posted May 04 2010, 05:08 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 2 - Installation

    This is part 2 in a series of posts related to Windows PowerShell, and deals with Installation

    The good news if you are running Windows 7 or Windows Server 2008 R2 (or later) is that you have nothing to do – PowerShell V2 was installed as part of the operating system.

    If you have a different operating system and want to install PowerShell – you have to choose between PowerShell V1 and PowerShell V2. The only reason I can think of to choose PowerShell V1 is if you were working as part of a team where everyone is using that version. If possible – just go for PowerShell V2 as it includes a vast number of additional commands.

    PowerShell is installed as part of Windows Management Framework so visit Microsoft Support for install packages for a number of different platforms.

    Once PowerShell is on your system, fire it up by any of the following methods:

    • All Programs > Accessories > Windows PowerShell > Windows PowerShell V2
    • From a command line prompt (e.g. cmd), type powershell
    • Start menu > Search > type powershell
    • [Win] + R (for Run command) > type powershell

    Whatever method you try, the result should be the same – the PowerShell command prompt which should look like:

    PowerShellConsole

    Once you’ve got the PowerShell console open – let’s confirm that you have V2 installed by typing the following command:

    get-host

    You should see something like the following:

    PowerShellVersion

    Assuming you have got the same – then we are good to go.

    Next step – Customise the Console

    Previous step – Introduction

    Technorati Tags:
    Posted Apr 30 2010, 12:07 PM by IvorB with no comments
    Filed under:
  • Windows PowerShell Series - Part 1 - Introduction

    powershellThis is the start of a number of posts related to Windows PowerShell. The goal is that each post will introduce a single concept, and build upon previous posts in the series. We’re going to start off with a very gentle introduction which will hopefully explain “What is Windows PowerShell?”

    Windows PowerShell is the latest command line shell and scripting language from Microsoft. An initial reaction might be “Do we really need another shell?” and my answer is that you should give it a go. If you like it – use it. If you don’t like it – then chances are you will be able to achieve whatever you need to do some other way. What PowerShell does really well is bring together a large number of commands, make their usage consistent and makes it really easy for you to build your own powerful scripts.

    PowerShell implements a scripting language based upon C# and an object model based upon Microsoft .NET framework. As such – it is incredibly easy for someone with a developer background to pick it up. However – System Administrators will also love the fact that they will be able to use PowerShell to manage Active Directory, Exchange, Windows File System, Windows Services and a wide variety of other essential system infrastructure components.

    This series will attempt to cover as many aspects of PowerShell as possible, but feel free to make suggestions for content to cover.

    Next step – Installing PowerShell…

    Technorati Tags:
    Posted Apr 29 2010, 05:38 PM by IvorB with no comments
    Filed under:
  • Conference Identity links

    I thought it was useful to put together a collection of links with ADFS materials for those attending the Microsoft Architect Insight Conference 2007. Initially it will be a short list - but if people ask me "where can I find a link to...?", I'll update this entry and point them at my blog.

     

    Microsoft Identity - general launch page:

    http://www.microsoft.com 

    Overview of ADFS:

    http://www.microsoft.com/downloads/details.aspx?familyid=8a4ccaf1-d55e-4129-8a5f-97093a48fd3d&displaylang=en

    Identity and Access in Windows Server "Longhorn"

    http://www.microsoft.com/windowsserver/longhorn/ida-mw.mspx

    Step-by-Step Guide for Active Directory Federation Services:

    http://go.microsoft.com/fwlink/?linkid=49531

    ADFS Operations Guide:

    http://www.microsoft.com/downloads/details.aspx?familyid=c6154ff7-fb05-4497-951d-5dc22bbf0775&displaylang=en

    ADFS Design Guide:

    http://www.microsoft.com/downloads/details.aspx?familyid=aa0c3af7-17c8-45cc-a6c2-269fbd1fd970&displaylang=en

    The .Net Show about ADFS:

    http://msdn.microsoft.com/theshow/episode.aspx?xml=theshow/en/episode047/manifest.xml

    Kim Cameron's Identity Blog:

    http://www.identityblog.com/

    Role Based Security with AzMan:

    http://msdn.microsoft.com/msdnmag/issues/03/11/authorizationmanager/default.aspx

    Posted Mar 04 2007, 10:36 PM by IvorB with no comments
    Filed under: ,
  • Microsoft Architect Insight Conference 2007 - Blog site

    The Architect Insight Conference for 2007 has its own blog site to provide updates about the conference sessions.

    The blog can be found at:

    http://blogs.msdn.com/ArchitectInsight/

    "The purpose of this blog is to update all conference goers and other interested parties of the latest updates to the agenda during the final run up to the event. We will also use it to provide information , but also to allow us to share any developments during the conference and then afterwards"

    Posted Feb 26 2007, 10:10 AM by IvorB with no comments
    Filed under:
  • Microsoft Architect Insight Conference 2007

    The Microsoft Architect Insight Conference for 2007 is happening at The Celtic Manor Resort, Newport, Gwent from 5th March 2007 to 6th March 2007.

    http://www.microsoft.co.uk/Events/registermulti.aspx?event=ArchitectInsight2007 

    I'll be speaking as part of the Identity track on Active Directory Federation Services. The current description for the session is as follows:

    "In this session we'll start with a whiteboard chalk/talk in which we'll outline the problems and known ways of tackling the problems of federating identities, both across organizational boundaries and across platform and technology boundaries. In MS parlance this means ADFS, but as these technologies overlap so much with other technologies which follow the same WS-Federation standards from other vendors this will be a great starting point for a discussion.

    We'll then break the delegates in to a few small groups and have you discuss the sorts of issues you face in your own organisations. Following that we'll create a prioritised list and debate the issues. There may be many issues that arise, and because of time we may not get to all of them, but by prioritising the list we will have covered the most important ones first.

    It will be a very interactive session where the discussion is facilitated by an expert(s) in enterprise federation issues.
    "

    This blog can be used to ask questions or for help, or to start a debate about any of the issues raised at this session

    Hopefully see you then.

    Posted Feb 26 2007, 09:54 AM by IvorB with no comments
    Filed under: ,
Powered by Community Server (Commercial Edition), by Telligent Systems