Setup Windows 8 as NTP (Time server)

I have a Ubuntu VM running under Hyper-V on Windows 8. Time synchronisation is enabled, however after hybernation, or suspending my laptop, time is not resynched to my VM.

To make ubuntu synchronised more regularly, I have setup my Windows host as a time (NTP) server, enabled firewall rules and created a cron job to check time every minute.

I created the cron job using webmin. See below for the command to use to update time from the time server.

Note, Microsoft explicitly states it does not guarantee the accuracy of the service, as it is used for Kerberos purposes (which only requires synchronisation accuracy of 5 minutes). However I have found it to work reasonable for my dev machine. For more info, see Microsoft KB939322.

First, to setup the time server, make the following registry edits to enable the NTP server.

Enable the W32Time service to announce itself as a NTP server. Open the registry and navigate to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32TimeConfig

Set the “AnnounceFlags” from 10 (or ‘a’ in hex) to 5.

Next, enable the NTPServer. Open the registry and navigate to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer

Set “Enabled” to 1.

Now, restart the Time service. Open command prompt as administrator and run the following:

C:>net stop w32time && net start w32time

To confirm the settings were changed correctly, run the following (in an admin command prompt):

C:>w32tm /query /configuration

Confirm you should see something similar to the following:

[Configuration]

EventLogFlags: 2 (Local)
AnnounceFlags: 5 (Local)
TimeJumpAuditOffset: 28800 (Local)
MinPollInterval: 10 (Local)
MaxPollInterval: 15 (Local)
MaxNegPhaseCorrection: 54000 (Local)
MaxPosPhaseCorrection: 54000 (Local)
MaxAllowedPhaseOffset: 1 (Local)

FrequencyCorrectRate: 4 (Local)
PollAdjustFactor: 5 (Local)
LargePhaseOffset: 50000000 (Local)
SpikeWatchPeriod: 900 (Local)
LocalClockDispersion: 10 (Local)
HoldPeriod: 5 (Local)
PhaseCorrectRate: 1 (Local)
UpdateInterval: 360000 (Local)
[TimeProviders]

NtpClient (Local)
DllName: C:Windowssystem32w32time.dll (Local)
Enabled: 1 (Local)
InputProvider: 1 (Local)
AllowNonstandardModeCombinations: 1 (Local)
ResolvePeerBackoffMinutes: 15 (Local)
ResolvePeerBackoffMaxTimes: 7 (Local)
CompatibilityFlags: 2147483648 (Local)
EventLogFlags: 1 (Local)
LargeSampleSkew: 3 (Local)
SpecialPollInterval: 604800 (Local)
Type: NTP (Local)
NtpServer: time.windows.com,0x9 (Local)

NtpServer (Local)
DllName: C:Windowssystem32w32time.dll (Local)
Enabled: 1 (Local)
InputProvider: 0 (Local)
AllowNonstandardModeCombinations: 1 (Local)

VMICTimeProvider (Local)
DllName: C:WindowsSystem32vmictimeprovider.dll (Local)
Enabled: 1 (Local)
InputProvider: 1 (Local)

The NTP service should now be setup. The final step is to allow the service through the firewall.

Open Windows Firewall Settings. Click Inbound Rules. Right-cick and select “New Rule…”.

Select “Port”. Click Next.

Select “UDP”, and Specific local ports: “123”.
Click Next.

Make sure “Allow the connection” is selected, then click Next.

Enter the profiles to setup the rule (for example, only Private and Domain).

Click Next

Enter the name (or your preferred name): w32time – ntp server. Click Finish.

You should now be able to access the time server.
Here is the command to test it from Ubuntu:

$ sudo ntpdate [ServerName]

You should see something like this:

 7 Jan 14:10:38 ntpdate[3328]: adjust time server 192.168.0.2 offset -0.000822 sec

Configure Host headers in Apache

Host headers allow you to map hostnames to web sites.  You can have multiple host headers pointing to the same IP, using the same port (generally standard port 80).

A common scenario when I use host headers is for SharePoint. In SharePoint, each web application is a web site in IIS.  I might have 3 web applications (central administration, intranet and mysites).  I can have all three web sites using port 80, with different host headers:

central.mydomain.com
intranet.mydomain.com
mysites.mydomain.com

The process is the same for all web servers.  For example in Apache, I have the following host headers setup on my network:

wordpress.devuxmachine.local
phpmy.devuxmachine.local
mail.devuxmachine.local

Today I am going to describe how to do it in Apache.

First, I am going to setup some local host headers on the server, so we can use for testing.  Open the /etc/hosts file for editing.  Add the following lines:

127.0.0.1 wordpress.devuxmachine.local
127.0.0.1 phpmy.devuxmachine.local

Now you should be able to ping the hostnames above:

$ ping wordpress.devuxmachine.local
PING wordpress.devuxmachine.local (127.0.0.1) 56(84) bytes of data.
64 bytes from wordpress.devuxmachine.local (127.0.0.1): icmp_req=1 ttl=64 time=0.017 ms

Now we want to add a virtual host to Apache.  Lets say we have the following setup:

<VirtualHost *:80>
 DocumentRoot /var/www/wordpress
</VirtualHost>

The above should display your wordpress site using http://yourserver:80. To tell Apache to listen for the host header instead, add the following line:

<VirtualHost *:80>
 ServerName wordpress.devuxmachine.local
 DocumentRoot /var/www/wordpress
</VirtualHost>

Now you should be able to access your wordpress site using http://wordpress.devuxmachine.local.

If you have DNS configured, you can add this as an A record, which will allow all users to use this host header.  Otherwise (for example for use in a development environment), you can always edit your /etc/hosts file (in Linux), or your c:/windows/system32/drivers/etc/hosts file in Windows.

 

Create SQL Alias

A SQL Alias is an alternate name used to make a database connection.

Aliases are configured on the client machine, not the database server.  Therefore, the SQL Server Native Client is required on the client servers.

Let’s say we have a SharePoint web server on SERVERW01 and all databases are on SERVERD01.  The scenario is that SERVERD01 needs to be decommissioned and all databases moved to SERVERD02.

We can easily do this using SQL Aliases, without making any modifications to SharePoint configuration.

Context based, you may want to use explicit IP address, or the server name.  There are pros and cons for each.  If you are not sure I would advise using the server name as if the IP changes on the DB server, the alias will still work.

Here is the process to add a SQL Alias:

1. Run “cliconfg.exe” (Note the missing “i” in config)
2. Select the Alias tab
3. Click Add
4. Select TCP/IP
5. Enter the name of the Alias (in our scenario: SERVERD01)
6. Enter the name of the new server (in our scenario: SERVERD02)
7. Click OK

cliconfg-screen

Allow Authentication Forwarding When Using SharePoint WebDAV with FQDN

A common scenario for using WebDAV is for a SQL Server Integration Services (SSIS) package to read an Excel spread sheet stored in a SharePoint document library. The package imports the contents into a SQL database.   Business users are able to upload Spread sheets using SharePoint (no IT involvement required), data can automatically be imported (using scheduled SQL Jobs), and users can view reports (through Reporting Services in SharePoint Integrated Mode) with up-to-date data.  Here’s a diagram:

sharepoint-webdav-logical-diagram

When configuring WebDAV, make sure the WebClient service is installed and started on the server hosting the SSIS package.  This service allows the server connect to SharePoint via WebDAV.  By default, Windows Server does not have the WebClient service installed.  In Windows Server 2008 R2, this is bundled up with the “Desktop Experience” feature

The authentication using FQDN issue is caused by the WebClient service only allowing credentials to be passed to local intranet sites – without checking Internet Explorer settings.  A URL is considered local intranet if it is not fully qualified, such as “SPWFE01”.  If the URL contains a period, it is considered Internet, such as “intranet.mycompany.com”.

The behaviour you are likely to see when trying to access FQDN is:

HTTP 401: Authentication Error.

You can check this by reading the IIS logs on the SharePoint web application.

To allow a specified FQDN URL to have credentials passed, we need to add a registry key to specify the FQDN URL(s).  First, open the following location in Registry Editor:

ComputerHKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesWebClientParameters

Create a new key (Mult-String), called “AuthForwardServerList”.

Edit the key, and add the relevant URLs (one URL per line).  For example:

http://intranet.mycompany.com
 http://*.companyxyz.com

Note that all sites/libraries under the URL will be allowed as well.

Finally, restart the WebClient service.

Now WebDAV should work correctly and credentials forwarded appropriately for the specified FQDN(s).

Write a simple JavaScript Object Model Script for SharePoint 2010

The SharePoint Client Object Model allows applications to make server calls to SharePoint, who originate from a server or system without SharePoint installed.

Server calls can include retrieving list items, updating list data, or even manipulating security. Note that there are some functions only available to the Server Object Model (such as interacting with Web Application and Farm objects).

I am going to demonstrate a simple example of retrieving information from the SPWeb and SPSite objects of the current site collection.  The example is using JavaScript to access the Client Object Model. For this example we create a Document Library called “Scripts,” to store our JavaScript files.  Create a new file called Test_CEWP.js and open it for editing.

The first part of this file is going to be a simple HTML content placeholder, to display the information on the page. Next we create our Script tags, where we will insert our JavaScript code:

<div id="contentDiv">&nbsp;</div>
<script type="text/javascript" language="javascript">
</script>

Before we start making server calls, we want to provide an update to the web part, to show it is loading.  The calls can be made asynchronously, so the rest of the page can load quickly.  Here we will set the HTML div content to “Loading…”:

<div id="contentDiv">&nbsp;</div>
<script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
</script>

SharePoint includes JavaScript files to define and implement the Client Object Model API.  One of these files is called “SP.js.”  We need to make sure this script is loaded before our code.  This is part of the API.  We want the request to load asynchronously, so the rest of the page can load quickly.  Here we will set the HTML div content to “Loading…”:

<div id="contentDiv">&nbsp;</div>
<script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
 ExecuteOrDelayUntilScriptLoaded(GetSite, "sp.js");
</script>

The function GetSite is going to be the name of our function.  We need a Context object to use to load data, and to interact with SharePoint.  The code below creates the GetSite() function, and returns an object which represents the SharePoint context of the current site:

<div id="contentDiv">&nbsp;</div>
<script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
 ExecuteOrDelayUntilScriptLoaded(GetSite, "sp.js");
 function GetSite()
 {
  var ctx = new SP.ClientContext.get_current();
 }
</script>

Now we need to make a call to return the SPWeb object (an object representing the current web site).  Note this won’t actually be executed until we tell it to (see below, executeQueryAsync). We assign it to the current object to reference later.  This allows batch processing which can improve performance.

<div id="contentDiv">&nbsp;</div>
 <script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
 ExecuteOrDelayUntilScriptLoaded(GetSite, "sp.js");
 function GetSite()
 {
 var ctx = new SP.ClientContext.get_current();
 this.web = ctx.get_web();
 ctx.load(this.web,'Title');
 }
 </script>

We can control which properties of an object are returned.  This can improve performance by only transferring relevant data. The above load method tells SharePoint to only return the Title property.  We could add as many parameters as we like.

The final call in this function is to execute the query.  It can be executed asynchronously, meaning other parts of the page can load while waiting for this call to be returned:

<div id="contentDiv">&nbsp;</div>
 <script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
 ExecuteOrDelayUntilScriptLoaded(GetSite, "sp.js");
 function GetSite()
 {
 var ctx = new SP.ClientContext.get_current();
 this.web = ctx.get_web();
 ctx.load(this.web,'Title');
 ctx.executeQueryAsync(Function.createDelegate(this, this.onSiteLoadSuccess), Function.createDelegate(this, this.onSiteLoadFail));
 }
 </script>

The executeQueryAsync function intiates a call to the SharePoint server (asynchronously), and provides function delegates to invoke on success/failure.  See the two functions onSiteLoadSuccess and onSiteLoadFail in this example:

<div id="contentDiv">&nbsp;</div>
 <script type="text/javascript" language="javascript">
 var div = document.getElementById("contentDiv");
 div.innerHTML = "Loading...";
 ExecuteOrDelayUntilScriptLoaded(GetSite, "sp.js");
 function GetSite()
 {
 var ctx = new SP.ClientContext.get_current();
 this.web = ctx.get_web();
 ctx.load(this.web,'Title');
 ctx.executeQueryAsync(Function.createDelegate(this, this.onSiteLoadSuccess), Function.createDelegate(this, this.onSiteLoadFail));
 }
 function onSiteLoadSuccess(sender, args)
 {
 div.innerHTML = "<div>Title: " + this.web.get_title() + "</div>";
 }
 function onSiteLoadFail(sender, args)
 {
 div.innerHTML = "Error: " + args.get_message();
 }
 </script>

If the call is successful, the web site title is rendered inside the div element we setup above.  If an error occurs, the error message is displayed.

To try out the example, save the above JavaScript file (e.g. Test_CEWP.js), and upload it to your document library in SharePoint.

Copy the link to the script in the library to the clipboard.

Open and edit a sharepoint page.  Add a Content Editor Web Part and paste the URL copied previously into the source text property.

Click OK and you should see the JavaScript code run.

Notice this example required no administrative access, only access to a document library and adding a web part. The server call was asynchronous so other parts of the page can load while the call is being made.

Activating Windows 8 RTM Enterprise Edition

After installing Windows 8 RTM Enterprise Edition when you try to activate Windows, you may see the following error message:

Error code: 0x8007232B
Error description:   DNS name does not exist.

As you may expect, this error indicates that the key (a temporary key) cannot be activated. A new key needs to be set.

To change the key, open a command prompt as administrator. Move your mouse to the bottom left of the screen and right-click. Select “Command Prompt (Admin).”

slmgr.vbs /ipk <Key>

Go back and try to activate windows again. Windows 8 should activate successfully.