Creating lookup and dependency columns in CSOM


What is a dependency column?

When you create a list in SharePoint this list can be used as a lookup. So for example (a very bad example, but gives you the idea), you have a customer list and an order list. On the order list you want to lookup to your Customer List. You would pick the column you want to point to for the lookup, in this case it would probably be the Customer column. However there might be other columns from the Customer list that you want to pull through to your orders list. (Customer ID, Date Joined etc). These extra columns are the dependency columns.

The customer you pick to associate with the order, these extra columns are pulled through. On the lookup list, if any of the data changes for the customer, this data will automatically be updated on the order list.

Not all columns can be used as a lookup/dependency column, only columns that can are:

  • Single Line of text
  • Number
  • Date
  • Calculated

The Demo

I have put together a demo, using a SharePoint hosted Add-In (SharePoint App). This SharePoint Add-in acts as a provisioning page to create my columns and lists, (similar to how OfficeDevPnp samples work) I will not be explaining in this post how to create a SharePoint Add-In.

The main point of the code that adds the dependant lookups uses the method AddDependentLookup which is part of the Microsoft.SharePoint.Client namespace.

public Field AddDependentLookup(string displayName, Field primaryLookupField, string lookupField ) 

I will be explaining the relevant sections of the code. All the methods have been written so that if anything already exists, it will not recreate it. My code also using OfficeDevpnp dlls, which I have obtained through NuGet. It is not until near the end after creating the Order List will I be adding the dependency columns.


Creating the Customer List

This is standard SharePoint CSOM code, I’m checking if the list already exists, if it doesn’t then I create it.

 
List customerList = null; 
if(!ctx.Web.ListExists("Customers")) 
{ 
  customerList = ctx.Web.CreateList(ListTemplateType.GenericList, "Customers", false, false); 
}
else { 
  customerList = ctx.Web.Lists.GetByTitle("Customers"); 
} 
customerList.Update(); 
ctx.Load(customerList); 
ctx.ExecuteQueryRetry(); 

I then change the Title display value from Title to Customer Name.

var title = customerList.Fields.GetByInternalNameOrTitle("Title"); 
title.Title = "Customer Name"; 
title.Update(); 

Lastly I create 3 fields if they don’t exist, Account ID, Address, Date Joined. Once the Date Joined column is created, I’m then ensuring that the Date column is just using Date Only, instead of Date Time values.

 if(!customerList.FieldExistsById("E99BF256-BC01-4A37-B35A-B39BCC5FB82E")) 
 { 
   var accountId = new FieldCreationInformation(FieldType.Text){ 
                           AddToDefaultView = true, 
                           DisplayName = "Account ID", 
                           Id = new Guid("E99BF256-BC01-4A37-B35A-B39BCC5FB82E"), 
                           Group="Lookups", 
                           Required=true, 
                           InternalName = "AccountID" 
                      }; 
    customerList.CreateField(accountId, true); 
 }

 if(!customerList.FieldExistsById("2A8ABC2E-B7F0-4187-ADCA-7831648AFAD3")) 
 {
   var address = new FieldCreationInformation(FieldType.Note){
                           AddToDefaultView = true, 
                           DisplayName = "Address", 
                           Id = new Guid("2A8ABC2E-B7F0-4187-ADCA-7831648AFAD3"), 
                           Group = "Lookups", 
                           Required =true, 
                           InternalName = "CustomerAddress" 
                       }; 
   customerList.CreateField(address, true); 
 } 

 if(!customerList.FieldExistsById("C73123E9-85C8-4156-B280-E7783EEB119C")) 
 { 
   var dateJoined = new FieldCreationInformation(FieldType.DateTime){
                             AddToDefaultView = true, 
                             DisplayName = "Date Joined", 
                             Id= new Guid("C73123E9-85C8-4156-B280-E7783EEB119C"), 
                             Group = "Lookups", 
                             Required = true, 
                             InternalName = "DateJoined" 
                         }; 
   customerList.CreateField(dateJoined, true); 

   var dateJoinedField = ctx.CastTo<FieldDateTime>(customerList.Fields.GetById(new Guid("C73123E9-85C8-4156-B280-E7783EEB119C"))); 
   ctx.Load(dateJoinedField); 
   ctx.ExecuteQueryRetry(); 

 if(dateJoinedField.DisplayFormat == DateTimeFieldFormatType.DateTime) 
 { 
  dateJoinedField.DisplayFormat = DateTimeFieldFormatType.DateOnly; 
  dateJoinedField.UpdateAndPushChanges(true); 
  ctx.ExecuteQueryRetry(); 
 } 
}

 

As this is just a demo, I want to ensure that my Customer list already has some data in it ready to use. Therefore I’ve added a method that just adds some data to the Customer list.

private void CreateCustomerData(ClientContext ctx) 
{ 
  List customerList = ctx.Web.Lists.GetByTitle("Customers"); 
  ctx.Load(customerList); 
  ctx.ExecuteQueryRetry(); 
  if(customerList.ItemCount == 0) { 
      //Add Data. 
      Microsoft.SharePoint.Client.ListItem cust1 = customerList.AddItem(new ListItemCreationInformation()); 
      cust1["Title"] = "Customer A"; 
      cust1["AccountID"] = "A12345"; 
      cust1["CustomerAddress"] = "85 Abbott Close, \r\nLondon"; 
      cust1["DateJoined"] = new DateTime(2015, 6, 4).ToString("o"); 
      cust1.Update(); 

      Microsoft.SharePoint.Client.ListItem cust2 = customerList.AddItem(new ListItemCreationInformation()); 
      cust2["Title"] = "Customer B"; 
      cust2["AccountID"] = "B26554"; 
      cust2["CustomerAddress"] = "745 Rose Drive, \r\nLondon"; 
      cust2["DateJoined"] = new DateTime(2014, 8, 14).ToString("o"); 
      cust2.Update(); 
      
      Microsoft.SharePoint.Client.ListItem cust3 = customerList.AddItem(new ListItemCreationInformation()); 
      cust3["Title"] = "Customer C"; 
      cust3["AccountID"] = "C44575"; 
      cust3["CustomerAddress"] = "547 Cooper Way, \r\nLondon"; 
      cust3["DateJoined"] = new DateTime(2011, 1, 24).ToString("o"); 
      cust3.Update(); 

      ctx.ExecuteQueryRetry(); 
 } 
} 

 

Now we can move onto creating the Orders list. I have written this code very similar to how I started to write the Customer list, where I’m first checking if it exists first before creating it. I’m then changing the Title display value from Title to Orders. So that I have access to the Customers list columns I’m loading the list and columns.

 List orderList = null; 
 if (!ctx.Web.ListExists("Orders")) 
 { 
   orderList = ctx.Web.CreateList(ListTemplateType.GenericList, "Orders", false, false); 
 } 
 else 
 { 
   orderList = ctx.Web.Lists.GetByTitle("Orders"); 
 } 

 //Change Title 
 var title = orderList.Fields.GetByInternalNameOrTitle("Title"); 
 title.Title = "Order Item"; 
 title.Update(); 

 //Get the customer list 
 List customerList = ctx.Web.Lists.GetByTitle("Customers");
 //Load Lists, fields and views ready to add more fields and lookup fields. 
 ctx.Load(orderList); 
 ctx.Load(customerList); 
 ctx.Load(customerList.Fields); 
 ctx.ExecuteQueryRetry();

I now need to add the columns to the Order list. I’m going to start with the Cost column, as this is a standard currency column. I’m checking if the column exists first before adding it to the list.

 Field cost = null; 
 if (!orderList.FieldExistsById(new Guid("70420D11-3D40-4B53-AAF4-21B57D51C033"))) 
 { 
  FieldCreationInformation orderCost = new FieldCreationInformation(FieldType.Currency) 
  { 
    DisplayName = "Cost", 
    Id = new Guid("70420D11-3D40-4B53-AAF4-21B57D51C033"), 
    AddToDefaultView = true, 
    Group = "Lookups", 
    Required = true, 
    InternalName = "Cost" 
  }; 

 cost = orderList.CreateField(orderCost, true); 
 ctx.Load(cost); 
 } 

This is the section where the AddDependentLookup method is being used. First I need to create the lookup column from the Customers list to the Orders list. If it already exists I need to load this column as I require the Field when I call the AddDependentLookup method. Once this is created, I will check to see if the dependency column has already been added. Unfortunately when it gets added, you don’t have control over what the GUID of the column will be. Therefore you will need to check by internal name. This name will be the title of the column that you give it encoded the way SharePoint encodes spaces, punctuation etc. If the column doesn’t exist it is then added to the Order list using the AddDependentLookup method passing in the column display name, the lookupfield, and the internal name of the dependant column within the customer list.

FieldLookup customerLookupField = null; 
if (!orderList.FieldExistsById("FE9ED460-02E7-4124-A4F0-BFE5A3DDA4D0")) 
{ 
  FieldCreationInformation customerLookup = new FieldCreationInformation(FieldType.Lookup) { 
       DisplayName = "Customer", 
       Id = new Guid("FE9ED460-02E7-4124-A4F0-BFE5A3DDA4D0"), 
       Group = "Lookups",
       Required = true, 
       AddToDefaultView = true, 
       InternalName = "CustomerLookup" 
 }; 
  customerLookupField = ctx.CastTo<FieldLookup>(orderList.CreateField(customerLookup, false)); 
  customerLookupField.LookupList = customerList.Id.ToString(); 
  customerLookupField.LookupField = "Title"; 
  customerLookupField.Update(); 
  ctx.ExecuteQueryRetry(); 
} 
else 
{ 
  customerLookupField = ctx.CastTo<FieldLookup>(orderList.Fields.GetById(new Guid("FE9ED460-02E7-4124-A4F0-BFE5A3DDA4D0"))); 
  ctx.Load(customerLookupField); 
  ctx.ExecuteQueryRetry(); 
 } 
 
 //Add Dependency fields. AccountID, DateJoined 
 Field accountDependency = null; 
 if (!orderList.FieldExistsByName("Cust_x002e__x0020_Account")) 
 {
   accountDependency = orderList.Fields.AddDependentLookup("Cust. Account", customerLookupField, "AccountID"); 
   ctx.Load(accountDependency); 
 } 
  Field dateJoinedDependency = null; 
  if (!orderList.FieldExistsByName("Cust_x002e__x0020_Joined")) 
  { 
    dateJoinedDependency = orderList.Fields.AddDependentLookup("Cust. Joined", customerLookupField, "DateJoined"); 
  ctx.Load(dateJoinedDependency); 
  } 
  ctx.ExecuteQueryRetry();

After deploying my app, and loading it up, I am able to create the lookup lists.

Customer List


Creating a new Order


Orders List


Reference

https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.fieldcollection.adddependentlookup.aspx

Link to Visual Studio Project

http://1drv.ms/1WWzyoi

Using a Document Library to store global Document Templates


With the use of Content Types, you can assigned a Document Template to the content type. That way when the user goes to create a new document of that content type, they will be given a Word/PowerPoint/Excel document that you want them to use. For example a company expense form, or a company report document.

Typically you would create a content type, and upload the document template you wish to use. Then you add the content type to your library and then every time you wish to create a new document the document template opens. However if you look under the covers although you have just uploaded one document template, the document template is being copied into each Document library the content type is being added to.

With the use of SharePoint Designer I can prove this point.

I have created a Content Type called CandC Document, and added a few extra site columns to it.

Then in the advance settings I have uploaded a Document Template that I wish my Content Type to use.

By opening my site in SharePoint Designer, click on All files, and in the _cts folder, there is now a folder named after my Content Type. (This is the first copy of my Document Template within SharePoint)

After creating a document library called Team Documents and adding my Content Type I can then use my document template.

However if I look at this document library in SharePoint Designer, I see that SharePoint has actually copied my Document Template to be local to the list. (This is the second copy of my Document Template within SharePoint)

Every document library I create and add the document template to will also create a copy. (This is the X copy of my Document Template within SharePoint).

Now you are right if you are thinking, when I have a new Document Template I just need to go to the Content Type, upload the new template and ensure that when I click OK, ensuring I’ve selected Yes for ‘Update all content types inheriting from this type’. This works fine in one site collection, therefore having multiple copies isn’t really an issue.

What if the Content Type being used in multiple site collections?

If the Content Type is being used in multiple site collections and you wish to update the Document template then the choices are to:

  1. Use the Content Hub.
  2. Define a document library in a different site collection as the global location.

Manually going to each site collection and update the Content Type.

This is a valid option, you might only have 4 site collections. Hopefully you have used code to create your content types in each site collection (otherwise the GUID’s) won’t match. If you have 100s of site collections this isn’t suitable. You will still have multiple copies of your Document Template.

Use the Content Type Hub.

The full explanation and setup of the Content Type hub is out of scope for this document, but basically it is a built in publishing of content type mechanism. You would create the Content Type in the Content Hub with the Document Template and then publish the content type. This will be pushed out to every site collection. Any updates/changes to the Content Type (including changing the Document Template) can be republished and pushed out to all site collections. Again this a valid option, however there can be caveats using the Content Type Hub, and I fully recommend you do your research online before making this decision. Not all site columns play nicely with the Content Hub. Also using this approach you are creating copies of your Document Template everywhere.

http://blogs.msdn.com/b/chaks/archive/2011/02/09/content-type-hub-limitations.aspx

Define a document library in a Site Collection as the Global Location.

This is the solution I’ve used recently and it ensures there is just one copy of the Document Template. The update is instantly, unlike using the Content Hub which relies on a timer job to push the changes everywhere, and there isn’t multiple copies of the template. Also you have the added bonus that because you are storing the Document Template is a Document Library, you can apply versioning, workflow approval on it too if you wish.

You will need to ensure your Content Types are created in code, as you need the GUID’s to match.

First create a document library in the Site Collection you are going to store your document templates in. Then upload all your document templates into this library. Please note, that if you wish to use your document template with multiple content types then you will need to have a copy for each content type still. (I know I said one copy, but there are limitations if using the same document template for multiple content types and you will understand why later, also having one document template for each content type even if they are the same is not a bad idea, as in the future the documents templates could different from each other.)

So I have create my Site Collection on my root site (can be any other site collection), and created my Document Library called Document Template. Inside my document library I have create 2 folders, one called CandC and once called Cann0nF0dder. Inside each folder is the same two templates I want to assign to my Content Types. Ensure you have also given everyone access to this library.

In your other site collections, using code, however you wish to do it, PowerShell, C# CSOM or JavaScript, create your Content Types in your Sites and ensure that the Document template URL is a relative path to your Document template stored in the global location. Below is sample PowerShell code I used for this demo.

$UserName = Read-Host -Prompt "UserName"
$Password = Read-Host -Prompt "Password" -AsSecureString
$Url = https://tenant.sharepoint.com/sites/Teams

#location is https://tenant.sharepoint.com/DocumentTemplates
$location = "/DocumentTemplates"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)
$ctx.ExecuteQuery();

#Create Content Type
$lci = New-Object Microsoft.SharePoint.Client.ContentTypeCreationInformation
$lci.Description = "CandC Document"
$lci.Name = "CandC Documents"
$lci.ID = "0x0101005F05888B19FD40C798741D9F1B5401E4"
$lci.Group = "CandC"

#Add Content Type
$contentType = $ctx.Web.ContentTypes.Add($lci)
$ctx.Load($contentType)
$ctx.ExecuteQuery()

#Update Document Template
$contentType.DocumentTemplate = $location + "/CandC/CCDocument Template.docx"
$contentType.Update($true)
$ctx.ExecuteQuery()

#Create Content Type
$lci = New-Object Microsoft.SharePoint.Client.ContentTypeCreationInformation
$lci.Description = "CandC Presentation"
$lci.Name = "CandC Presentation"
$lci.ID = "0x0101005F05888B19FD40C798741D9F1B5401E5"
$lci.Group = "CandC"

#Add Content Type
$contentType = $ctx.Web.ContentTypes.Add($lci)
$ctx.Load($contentType)
$ctx.ExecuteQuery();

#Update Document Template
$contentType.DocumentTemplate = $location + "/CandC/CCPresentation Template.pptx"
$contentType.Update($true)
$ctx.ExecuteQuery()

The above code only creates 2 content types (CandC Document and CandC Presentation), and it also doesn’t add the additional columns I wanted, you’ll have to work that out on your own for now. However I did create 4 content types, one for each document template.

By going into the Content Type, and viewing the Advanced Settings, you will see that it is pointing to the correct location in my Global Document Template library.

I’ve added these content types to my library (this can also be done in code) and now select whatever content type/template I wish to use.

However we are not finished yet. I discovered that when I select a Content Type, it opens up the relevant template, but when I save it back to the list, the Content Type for the document is the default content type for the library (in my case Document) not the Content Type I have picked. Also, any extra columns in my Content type were not showing up in the Document Information Panel at the top of the Microsoft Office application.

To ensure that it saves with the correct content type, you need to use your code to deploy the content types to the site collection that is holding the Global Templates. Then you need to add these Content Types to the document library that is holding the Document Templates.

Edit the property of each document and assign them to the correct content type.

Now when you create a new document from one of the content types, first of all you will notice that the Document Information panel displays with your columns.

After you have saved your document back to your library, you will also notice that it has been saved with the correct content type.

By using SharePoint designer I can also check that there is no template stored within the Site Collections, the only location you will find your template is in the Site Collection holding your Global Document Templates.

Office applications crashing with SharePoint Content Types and Document Templates


The scenario I had set up was, a few content types with different site columns assigned to the content type. (Single Line of Text, Ratings and Managed Metadata). Each content type also had a document template assigned to them.

The content types were then added to a document library list. When I click the New button on the list menu bar, I’m presented with a choice of documents I can create.

On my environment I was using Office 2013, and opening each one didn’t cause me a problem. The Document Information Panel (DIP) was there, my Presentation document template loaded correctly.

However when my clients tried to open any of the document templates it crashed. It appeared to crash just as the Document Information Panel attempted to load. They were using MS Office 2010, perhaps that was the problem?

It wasn’t. As I tried to open the same document on numerous of other PC’s that had either MS Office 2010 or MS Office 2013, none of them had a problem. The client had a few different people attempt to open the document templates and they all had MS Office crashing on them.

Going back to basics, I decided to create a basic content type with just single line of text columns and use the same document template. This loaded no problem in the clients MS Office 2010, the document information panel was there and the document saved back to the SharePoint Library. Therefore only difference then between the two content types were the columns.

Working with the client, I removed a column from the content type one at time and got them to open the Document Template. It turns out that after all Managed Metadata columns were removed the document open OK. This was great that I worked out the problem, but this wasn’t a solution, I needed the Managed Metadata columns to be there. I did a bit of searching on the internet, and many forums were pointing people in the direction that there are two version of Microsoft Office installed on the PC’s that are crashing.

The guys I were dealing with were working with SharePoint 2013 a lot, and turned out that they had SharePoint Designer 2013 installed. When SharePoint Designer 2013 is installed so is a bunch of Microsoft Office 2013 dlls. These Shared Dlls get registered and override some of the Office 2010 dlls.

Solution

The solution is a simple fix, (maybe not if you have to do it to everyone in your company), basically you need to either upgrade everyone to 2013 or get the PC’s with Office 2010 to repair the install. This will re-register the dlls for 2010 correctly and the Document Templates will open correctly. (SharePoint designer 2013 will continue to work)

To repair your Office 2010, on the PC go to Control Panel > Program and Features. Click on MS Office 2010, and then on the menu bar Click Change. Then select Repair. Once the repair is complete you will need to restart your PC, and afterwards you will be able to open Document Templates with Managed Metadata columns.

Final thought

Even though MS Office 2010 is very old now, and less people will probably encounter this issue, there is a chance that this issue could resurface for people when MS Office 2016 is released.

Upgrading Windows 10 – Resolution stuck at 1024×768


I’ve upgraded a laptop tonight to Windows 10. The laptop is quite old, it’s a Compaq and it was brought with Vista originally installed on it.

Once it had finished upgrading, I found that the screen resolution was stuck in 1024×768. Thought this shouldn’t be a problem, just Right Click the desktop, select Display Settings. This is where Windows 10 looks a little different, compared to previous versions of Windows. To be able to change the resolution you need to select Advance Display Settings.


Once you have clicked Advanced display settings it is on this screen you can change the resolution. However when I got to this on the laptop the maximum resolution was only 1024×768.

I needed to get the drivers, I had a Nvidia nforce 730m in-built graphics card, and the Nvidia website doesn’t allow you to download the driver for it, and recommend you to download from the manufactures website. So I head over to the manufacturers website and typed in my model number. The only 64 bit driver available for the graphics card was for the operating system Vista, which make sense as that should be the operating system on this laptop. So I downloaded the driver and when to install it. As it was a Zip file I had to extract the file.

From inside the extracted folder, I found the setup file and tried to install the graphics driver. As I went to install it, I received an error message saying:

Setup detected that the operating system in use is not Windows Vista [32-bit]/[64-bit]. This setup program and its associated drivers are designed to run only on Windows Vista [32-bit]/Vista[64-bit]. The installation will be terminated.

The solution is to not use the setup file. In the search bar start typing Computer Management and open the Computer Management app.


Once you have opened Computer Management, select Device Manager in the left panel and then find the Display adapters in the right panel and expand the Display adapters.

Note: Picture below shows the graphics card is already installed, this is because I’m grabbing screen shots after I found the solution.

Right click the generic graphics card and select Properties. On the properties dialog, select Update Drivers


You will be asked how you want to search for drivers. Select Browse my computer for driver software.


I then Browsed to the folder where 64 bit driver is located. This location is the unzip file location. Ensure you have Include subfolders ticked.

After I clicked OK, Windows was able to find and install the graphics driver, instantly my resolution changed to the maximum size my laptop would go, that was 1280x 800.

Upgrading to Windows 10 now I have a blank screen and cursor


I updated my first PC to Windows 10 today, never actually touched Windows 10 before today, and to ensure I didn’t damage my PC with a first run, I used my Mum’s. You can see the blog here with all the steps and screenshots. However, at the last part of the upgrade when I was logged into Windows 10 for the first time the screen was just a blank screen and a cursor. I waited quite some time, about 30 mins (The PC was very low spec) but still nothing was showing. I didn’t want to just reboot the PC, so I first checked to see if Microsoft had any messages about this in any of their forums. It turns out that on some Dell pc’s when Windows 10 first boots up, it thinks you have 2 screen connected, and you are seeing the second screen.

How to Fix?

First of all, press enter and put in your password if you have one (I know you can’t see the screen, but imagine that you can). Give it a moment and then press Windows Key + P. If you do this on a screen you could see you would see this appear. You want to select Second screen only. Of course you can’t see this, your setting will be at the top one PC screen only, so after pressing Windows Key + P, press the down arrow 3 times and then press enter. I did it first time, but some people did report they had to try a few times with a different amount of down key presses. Note: If you press the down key too many times it will go back to the top option and cycle round. You should now see your Windows 10 desktop. However, you haven’t finished yet.

  • Right Click the desktop and select Display Settings
  • Change Multiple Displays to Show only on 1
  • Click Apply.

Hope this solves your problem as it did mine.

Upgrading to Windows 10, step by step


It’s has been a very long while since I have written a blog, and this one is an easy one, hopefully there will be enough screenshots and walkthrough steps that it will help even the most basic user who never heard of Azure/SharePoint (which is what I’m normally talking about). Today I upgraded my Mums PC from Windows 7 to Windows 10. At the same time I also upgraded a Windows 8 PC to Windows 10 and the steps were exactly the same. Here I am going to walk through the simple steps, with lots of screen shots that I took on my phone. I do state many times in this blog that you are waiting, or things go slowly, this can be true if you have an old spec pc that you are upgrading. Like I said, I was using my Mum’s PC, which used to be an XP machine that I brought a copy of Windows 7 for, and now upgrading it to Windows 10.

Windows 10 is FREE to anyone who owns a legitimate copy of Windows 7, Windows 8 or Windows 8.1 for the first year of Windows 10 release. Once you have upgraded, that machine will be able to re-install Windows 10 at any point in the future. This isn’t a trial period of a year, this is a completely, free legitimate upgrade to Windows 10 that is yours to keep for now until… well… Windows 11 I suppose (Or you buy a new PC).

If you do have a legitimate copy of Windows 7, 8 or 8.1, you should see a Windows symbol in your notification area on your task bar, which if you double click on it, you can reserve your free copy of Windows 10.

Now before you can install Windows 10, it needs to be downloaded on your pc. This is supposed to happen through Windows update, as Microsoft is releasing Windows 10 to people globally in waves and you will be notified when it’s ready on your PC. (See Image below), however you can download it today without waiting for a notification.

There are places on the internet that shows you how to force the download of Windows 10. The steps are below (but they didn’t work for me!)

  1. Navigation to c:\Windows\SoftwareDistribution\Download
  2. Delete everything in this folder. This will give Windows Update a clean slate.
  3. Open up the command prompt by hitting the Windows key and typing in Cmd, right click and choose “Run as administrator”
  4. In the command prompt type ‘wuauclt.exe /updatenow
  5. This will kick off Windows Update, and have a Windows Update saying that it is downloading Windows 10.

As I said this didn’t work for me. I tried on 2 PC’s. One of them did state in the Windows Update history that Windows 10 was attempted and failed to download.

What worked for me.

Microsoft has a Windows 10 download page. https://www.microsoft.com/en-us/software-download/windows10  Head to this page and at the bottom of the page, you can click either download button. Either the 32 or 64 bit version. You have to use the version that matches your current Windows version. You can find this out by opening File Explorer. Right clicking on This PC, and selecting Properties.


On the System window that opens, it will state your current Windows version (Windows 10 will be the equivent version of your current Windows version), and under System it will state if your system is running 32 bit windows or 64 bit windows.

Back to the Windows 10 Download page, click the correct version of the Download tool.

Once downloaded, run the tool. A Windows 10 Setup dialog will pop up asking if you want to ‘Upgrade this PC now‘ or ‘Create installation media for another PC‘. I am not going to talk about Create installation media for another PC, this just allows you to copy the Windows 10 files onto a DVD or USB stick so that you can install on other machine (that are also entitled to the free upgrade). Leave Upgrade this PC now selected and click Next

Windows 10 will start downloading.

Once it has downloaded the files it requires, it will then start preparing your PC for Windows 10. (Following pictures are now all taken by my phone)

Then it checks for updates.

Gets a few things ready, not sure what!

Then you need to read and agree to the Licence terms, well at least click Accept.


The screen will then indicate to you what you needs to be done if you contine. On my surface, I had to reboot at this point to upgrade the firmware before I could continue. With the message below, I just need to click the OK button to accept that I understand that my English language could turn back to American English, and that I will need to re-install language packs.

Finally! I’m ready to install. Click Install.

After I clicked Install, the screen went completely blue, no longer in the dialog, and Windows 10 started installing. The PC does reboot several times, and it does take a while.

Then the screen went black and I got an Upgrading Windows message, with a large circle that pulses and a percentage slowly, very slowly creeps up.

Eventually it got there to 100% and I was welcomed. (Well my Mum was, being her PC).

Next you get to Customise settings or Use Express settings. I always like to customise, but you could just hit Use Express settings and skip the next 3 screenshots.

I went through the setting and turn on or off what I felt suited.


Then you are told about the new apps that comes with, (sorry, built for) Windows 10.

At this point, if you have a password, you will be asked to sign in, or you will logged in automatically.

Then I’m told, ‘This won’t take long‘, which means it probably will. At this point it is just setting up your apps, settings, configuration etc.

Windows 10 has it all handled, don’t you worry.

Apparently tweaking is involved.

Told you it was going to take a bit of time.

Then I got a blank screen!!!! Just a cursor moving about. Argh!

Don’t panic, I searched the internet and found out why. It appears to be happening on some Dell machines and read my next blog quickly to solve your issue.

If you don’t see a blank screen, you will see your new shiny, Windows 10 desktop. And in my Mum’s case a picture of a very young me, with my late Grandad and sister.

I hope these screenshots were simple enough for you to follow, or read through first and realise it’s not going to be that bad. Enjoy your Windows 10.

Deploying an Azure Website using PowerShell


Every developer learns that F5 is their deployment friend, but when it comes to deploying to live/production environments it is not an option. So how can you website code be deployed into Azure?

Let’s start of by creating a website in Visual Studio.

  • Open Visual Studio and Click New Project… from the welcome window.
  • From the new project dialog, select ASP.NET web Application and Click OK.

  • On the New ASP.NET Project dialog, select the template you wish to use. I’m using an MVC template, with No Authentication.

  • At this point it will ask you to configure your Microsoft Azure Website. Fill in the details and click OK. (I know this creates the site for you in Azure, we will delete this later.)

Once created you will have a Website, just underneath the solution we have PowerShell files that Visual Studio uses to deploy the website to Azure. It is these PowerShell files and configuration that we will use ourselves.

First we need to package up the website. You can do this by right clicking on the project in Visual Studio and click Publish.

The Publish web dialog that appears will be set up for direct publishing to Azure, we need to change the Publish method to Web Deploy Package, and then give a Package Location.

Click Next > and on the next page of the wizard, ensure you Configuration is set to Release. Note: if there is a web job related to this, then do not click Exclude files from the App_Data folder as this is where the webjobs get compiled to.

Click Next > then Publish.

If you open the folder where you published your website files to you will find a collection of files. The only file you need from here is the zip file, so delete the rest, they are for IIS deployment.

From your Visual Studio project copy over your configuration, Publish-WebApplicationWebsite.ps1 and AzureWebSitePublishModule.psm1 file. These are all the files required to give to your administrator to deploy to Azure, with the next set of instructions with the heading “Deploying to Azure”.

Just before we continue to the next step, go to you azure tenant and delete the website that Visual Studio created, that way you will be doing everything via PowerShell.

Deploying to Azure.

To deploy to Azure you need to ensure you have Azure PowerShell installed on your machine – see my blog Installing Azure PowerShell if you need instructions how to. You will also need to know how to connect to you Azure Subscription via PowerShell. The steps below will show the basic commands but if you have multiple subscriptions you should read my blog Handling Azure PowerShell with multiple Azure Subscription first to ensure you don’t deploy to the wrong subscription.

  • Open the Configurations folder and edit the .json file.
  • Change the website Name and Location to match where you want this deployed and the name you wish to give it.

{

    "environmentSettings": {

        "webSite": {

            "name": "CFWebSiteDemo-Dev",

            "location": "West Europe"

        },

        "databases": [

            {

                "connectionStringName": "",

                "databaseName": "",

                "serverName": "",

                "user": "",

                "password": "",

                "edition": "",

                "size": "",

                "collation": ""

            }

        ]

    }

}

  • As you can see from the script above, I’ve named my CFWebSiteDemo-Dev. Personally I find it useful to copy this file once for each environment (Dev, test, uat, prod), then when I’m deploying I just need to call the right configuration file.

  • Open up an Azure PowerShell Window.
  • Connect using your account. Add-AzureAccount press enter. You will be asked to sign into your Azure account.
  • Type Get-AzureSubscription to see all the subscriptions linked to your account(s). You need to ensure that your subscription you want to use is your current subscription.
  • Type Select-AzureSubscription –SubscriptionId [SubscriptionID]. This should now make your subscription the current subscription. Call Get-AzureSubscription to make sure. Read Handling Azure PowerShell with multiple Azure Subscription if you are still having issues up to this point.
  • Now navigate to your directory in the Powershell window. Mine is at c:\deploy. Cd deploy
  • Now type ./publish-webApplicationWebSite.ps1 –Configuration [Location of correct environment.json file] –WebDeployPackage [Location of zip file]
  • This will create the website in Azure, and then install the files. You will get a screen very similar to below.


NOTE: If you encounter an error when the website is trying to be created, then it will not upload the files. I have had this a few times before. Just check that the Azure website exists in your Azure Tenant and seems to be looking OK, then call the .\Publish-WebApplicationWebSite.ps1 command again. (You might need to try a new Azure PowerShell window.) Other reason why it fails could be due to how your company locks down your network. If you are having no success, try on a network (Starbuck wireless) that doesn’t have a network policy. If it then seems to work on that network, then you have something preventing the upload in your network, and will need to work through the problem with your network administrators.

  • As you can see in my tenant I now have a web app called CFWebSiteDemo-Dev.

  • My Website is up and running.

 

Upgrading Azure Website.

Upgrading the Azure website is very easy, make your changes and then create a new publish zip file.

Use the original PowerShell files and configuration files for Deploying Azure follow these steps.

  • Open up the Azure Windows PowerShell as Administrator.
  • Ensure you have added the account and subscription to your PowerShell profile if you haven’t done the previous steps.
    • Get-AzureAccount –Checks if account is there.
    • Get-AzureSubscription – Checks if Subscription is there.
    • Select-AzureSubscription –SubscriptionName [subscriptionName] –Selects the Subscription to deploy to.
  • Deploying files to Azure
  • Type ‘./Publish-WebApplicationWebsite.ps1 –Configuration [Location of correct environment .json file] –WebDeployPackage [Location of new zip file]
  • Your updated website should now be up and running.