Musings of a PC

Thoughts about Windows, TV and technology in general

Category Archives: Computers and Internet

An open letter to Leo Laporte, Paul Thurrott and Mary Jo Foley

I know that I haven’t written anything here for a long time now … I’ve been sorta busy :). I needed to get something off my chest, though, and this seemed as good a platform as any on which to do it.

So this is addressed to Leo Laorte, Paul Thurrott and Mary Jo Foley, the hosts of TWiT TV’s Windows Weekly. TWiT has the tagline of “netcasts you love from people you trust” and Windows Weekly has the tagline of “talk about Windows and all things Microsoft”. Sadly, for me at least, lately neither of these statements have been true for a while now.

I want to make it clear that this is an opinion piece. As such, you may disagree with what I write, and that’s fine – you are entitled to your own opinion – but I am allowed to have my own opinion even if you do disagree with it.

With that said …

Windows Weekly really doesn’t seem to be sticking to talk about Windows and all things Microsoft. Episode 461, for example, spent the opening 30 minutes talking about Facebook and their bot announcement; I’ve even re-listened to that part of the show and there was barely any comparison with the bot announcements made at Microsoft’s recent BUILD developer conference. Leo even went so far as to say that Facebook had the inside track! There was then an unannounced advertisement for Amazon Echo before going on to talk about Android handsets again (see below) and how Mary Jo is now using a Nexus instead of a Lumia Icon.

Remind me what this show is called?

Leo, you come across as a very affable person; easy to listen to and generally a good host. However, there are three things that really grate with me about you on Windows Weekly:

  1. Sometimes you just don’t listen to whoever else is talking with the outcome being that you ask a question that has literally been something that was said seconds earlier.
  2. There doesn’t seem to be a show that goes by without you promoting an Android handset. This is Windows Weekly. If I was interested in Android stuff, I’d be listening to This Week in Google. Anyone would think it was an unannounced advertisement the way you go on about it.
  3. Associated with #2, you really do have a tendency to derail the topic of conversation. You even admitted as much in episode 461 as you went to the first ad after talking about nothing really related to Microsoft.

Paul, you are a very depressing person to listen to. I don’t know if your articles have always been so tabloid or if this is since you left Penton to form thurrott.com, but I do get very disappointed/frustrated when headlines are just clickbait. Take the headline “Windows Phone is Irrelevant Today, But It Still Has a Future“. This is a very provoking headline … particularly since the use of the word irrelevant actually pertains to the statistical relevance of the number of Windows Phone/Mobile handsets in use. Like Leo, you have started pushing Android really hard lately instead of trying to find even the smallest positive about Windows Mobile.

You made a fair point about how Microsoft could have used Windows Mobile handsets on stage during the BUILD keynotes but, apart from that, your criticism of the lack of anything phone-related at BUILD was very unfair. Windows 10 Mobile is Windows 10. Any developer-related news or information would have been across the whole of Windows 10 unless it was Hololens because nobody knows how to develop for that, hence the sessions.

By and large, Mary Jo (with her Enterprise hat on) doesn’t get sucked into the anti-Microsoft rhetoric coming from Leo and Paul but recently she hasn’t been immune. There was one episode where she asked why data protection hadn’t been mentioned in BUILD. Errr … wasn’t that a developer event? Wouldn’t you expect data protection to be covered at Ignite (what used to be Tech-Ed)?

It has got to the point where I just don’t enjoy listening to the podcast any longer. I said at the start of this post that I needed to get something off my chest but I think that a comment on a recent Mary Jo article puts it more eloquently than me:

Since Mary Jo and Paul Thourrott don’t believe in Microsoft products, I unsubscribed to the ZDnet email, and to both their podcasts. They forgot that the ones that listen are Microsoft fans, and we don’t appreciate being laughed at. Maybe they should join an android show. I no longer listen to Windows Weekly or What the Tech.

I don’t consider myself to be a fanboy, but I do prefer the Microsoft ecosystem over Android or Apple. As such, I want to listen to people who are like me and I’ve come to the conclusion that Leo, Paul and Mary Jo simply don’t believe in Microsoft products and so I am no longer listening to Windows Weekly or following TWiT, Paul or Mary Jo on Twitter.

To use that word from Paul’s article, I may be (statistically) insignificant, but I still count.

Advertisements

Security and Email groups in LDAP

After working with Active Directory since 2000, I’ve clearly become a bit spoiled with the ability to create a group in AD that serves the purpose of both a security group and a distribution group with just one checkbox. Why do I say that? Because in LDAP, there isn’t a commonly used way of achieving that same goal.

LDAP, or Lightweight Directory Access Protocol, is an Internet protocol that services can use to look up information from a server. Active Directory makes use of LDAP which is why you’ll come across terms common to both such as schema.

For the UNIX world, the commonly used schemas are defined in RFCs. For example, the most common objectClass used to define a person – inetOrgPerson – is defined in RFC 2798. This is a really great class to use for storing personal information in an LDAP directory because it has attributes for all of the important stuff you might want to know about someone.

When it comes to groups, though, things get a bit tougher. There is posixGroup which is a good class to use for security needs because it stores a group ID, a description and the members of the group. Rather surprisingly, there isn’t an accepted standard for defining a distribution or email group. There are classes for defining groups of users, such as groupOfNames, groupOfUniqueNames and groupOfMembers. They each have their slight differences and which one(s) you use typically comes down to either personal preference or the tools you are going to be using to manage those groups.

Another curious aspect about groups in LDAP is that there are differences in how the members are represented. For example, posixGroup uses an attribute called memberUid and the value is just that – the uid of the member of the group. groupOfUniqueNames, by comparison, uses an attribute called uniqueMember and the value is the distinguishedName of the member. One of the benefits of using the distinguishedName is that it allows groupOfUniqueNames to contain other groups as members, which posixGroup does not.

So when it comes to trying to maximise the value of a group’s membership by using the group for dual-purposes, i.e. security and email, what can you do? One option is to define your own objectClass and add it to the schema on the LDAP server. That is essentially what Microsoft did but the problem then is that your tools probably won’t know how to work with that class unless you can modify the tools.

Given that the objectClasses do represent members in different ways makes any attempt to “merge” or “overlay” multiple objectClasses to get the desired result is also likely to fail.

For myself, in the end, I decided that I would use posixGroup as the definitive representation of a group and then have a script that reads the various posixGroup groups and creates groupOfUniqueNames groups to match those groups. I wrote the script in Perl and it is at the end of this blog.

Here is a bit more detail about how the script works and how I’ve got my LDAP server set up …

I have an organizationalUnit (OU) called groups, below which I have an OU called mailing and an OU called security. The idea should be clear but all of my posixGroup groups go into ou=security and the script creates the mailing groups in ou=mailing. The script can be used in two ways:

  1. Full scan of the security OU. It looks at each of the groups in turn and processes it.
  2. Processing of one security group by specifying the cn value on the command line. This functionality is primarily there for use with LDAP Account Manager Pro. This great web-based product allows the administrator to define custom scripts that get run at specified trigger points. In my case, I get it to run the script, passing the cn value, when a group is created or modified, thus ensuring the email group is kept up-to-date.

The logic behind processing a security group is as follows:

  • Get the attributes we need from the security group: modifyTimestamp, description, displayName, mail, owner and memberUid.
  • If there aren’t any members, we delete the corresponding email group. This is because groupOfUniqueNames has to have at least one member. If you want to use groupOfMembers instead, that restriction goes away and the script could be modified accordingly.
  • If the email group already exists and its modifyTimestamp is newer than that of the security group, we don’t do anything else because the implication is that it was created by the script after the security group was created/modified.
  • The next step is to delete the email group. This is done rather than trying to figure out the differences in group membership. If you want to get fancy with the code, go ahead but this works for me Smile.
  • The final step is to create a new email group, specifying the attributes and members retrieved from the security group.

A few notes about the attributes: the posixGroup class doesn’t allow you to specify a display name (displayName), email address (mail) or group owner (owner). To permit that, I use the objectClass extensibleObject which allows you to add any attribute defined in the schema. LDAP purists tend to frown on this because it could lead to errant attributes being added. If you are concerned, you could define your own objectClass as an auxiliary class in order to allow just those three attributes to be used. Alternatively, the script will work without them since displayName and owner aren’t strictly necessary and the script can auto-create an email address by adding the email domain to the end of the existing cn value.

For the email groups, I again use extensibleObject because groupOfUniqueNames doesn’t allow a display name or email address. The email address is clearly required if you want this to work as an email group and the display name may be required if you are, for example, syncing with Google (which was my requirement) and you want the group to have a “nicer” name than just the cn value. Again, if you don’t like the idea of allowing all attributes to be added, you could define your own objectClass and amend the script accordingly.

Final comments:

  • this is my first Perl script and I have been quite lazy in that I have hard-coded the various domain bits into the script. Feel free to improve and, if you want, share back!
  • I’ve not used SSL in the connection because the script runs directly on the LDAP server. It is quite straightforward to amend the script to use LDAPS and there are examples on the web on how to do that.
  • The script assumes, when converting from memberUid to uniqueMember that all of the UIDs exist in the same OU, namely ou=staff,ou=accounts,dc=example,dc=com. It should be fairly straightforward to extend the script so that it searches for the UID and finds the DN that way.

use strict;

use Net::LDAP;

# See if a group name has been passed on the command line, e.g. from

# LDAP Account Manager

my $groupMatch = "";

# $#ARGV is -1 if no parameters, 0 if 1 parameter, etc. We only

# look for one group name.

if ($#ARGV == 0)

{

$groupMatch = $ARGV[0];

}

# Create a connection to the LDAP server

my $ldap = Net::LDAP->new ( "<LDAP server>" ) or die $@;

my $mesg = $ldap->bind ( "account with appropriate write privs",

password => "account's password",

version => 3 );

my $result = $ldap->search ( base => "ou=security,ou=groups,dc=example,dc=com",

filter => "cn=*",

attrs => ['cn', 'description', 'displayName', 'mail', 'memberUid', 'owner', 'modifyTimestamp'] );

print "Got ", $result->count, " entries from the search.\n";

# Walk through the entries

my @entries = $result -> entries;

my $entr;

foreach $entr ( @entries ) {

my $thisCN = $entr->get_value("cn");

# Only process the group if either we are processing them

# all, or the group name matches.

if (($groupMatch eq "") || ($groupMatch eq $thisCN))

{

print "DN: ", $entr->dn, "\n";

my $deleteEmailGroup = 1;

my $buildEmailGroup = 1;

my $thisModify = $entr->get_value("modifyTimestamp");

my $thisDescription = $entr->get_value("description");

my $thisDisplayName = $entr->get_value("displayName");

my $thisMail = $entr->get_value("mail");

my $thisOwner = $entr->get_value("owner");

my $memberRef = $entr->get_value ( "memberUid", asref => 1 );

if ($memberRef == undef)

{

# No members means we don't build a new email group, regardless

# of timestamps, etc. We do still try to delete an existing email

# group though.

$buildEmailGroup = 0;

}

else

{

# We have members in the security group so now we check timestamps

# so that we only create a new email group if the security group has

# been modified more recently.

# See if the email group exists already and, if it does, when was it

# modified? There is no point in creating the new email group if it

# was modified after the security group.

my $emailGroup = $ldap->search ( base => "ou=mailing,ou=groups,dc=example,dc=com",

filter => "cn=$thisCN",

attrs => ['modifyTimestamp']);

if ($emailGroup->count == 1)

{

my @emailEntries = $emailGroup -> entries;

my $emailEntry = @emailEntries[0];

my $emailModify = $emailEntry->get_value("modifyTimeStamp");

if ($thisModify > $emailModify)

{

print "... security group is newer\n";

}

else

{

print "... email group is newer\n";

$deleteEmailGroup = 0;

$buildEmailGroup = 0;

}

}

else

{

print "... email group doesn't exist.\n";

}

}

if ($deleteEmailGroup)

{

print "  ... deleting old email group\n";

$mesg = $ldap->delete("cn=$thisCN,ou=mailing,ou=groups,dc=example,dc=com");

# If we got an error from that, print the error and don't try to

# create the replacement group

if ($mesg->code() != 0 && $mesg->code() != Net::LDAP::Constant->LDAP_NO_SUCH_OBJECT)

{

print "  ... error while deleting group: ", $mesg->error(), " (code ", $mesg->code(), ")\n";

$buildEmailGroup = 0;

}

}

if ($buildEmailGroup)

{

# If we have members in the group, create a new email group

my $entry = Net::LDAP::Entry->new();

$entry->dn("cn=$thisCN,ou=mailing,ou=groups,dc=example,dc=com");

$entry->add('cn' => $thisCN,

'objectClass' => [ 'groupOfUniqueNames', 'extensibleObject' ]

);

# If we have an email address set that, otherwise make one up

if ($thisMail)

{

$entry->add('mail' => $thisMail);

}

else

{

$entry->add('mail' => "$thisCN\@example.com");

}

# If we have a description, display name or owner, set them

if ($thisDescription)

{

$entry->add('description' => $thisDescription);

}

if ($thisDisplayName)

{

$entry->add('displayName' => $thisDisplayName);

}

if ($thisOwner)

{

$entry->add('owner' => $thisOwner);

}

# For each of the memberUid entries, add a uniqueMember attribute

# $memberRef is a reference to the array, so dereference it

my @members = @{ $memberRef };

foreach ( @members ) {

print "  ... adding $_\n";

$entry->add('uniqueMember' => "uid=$_,ou=staff,ou=accounts,dc=example,dc=com");

}

#         $entry->dump();

print "  ... creating group\n";

$mesg = $entry->update( $ldap );

if ($mesg->code() != 0)

{

print "  ... error while creating group: ", $mesg->error(), "\n";

}

}

print "\n";

}

}

$ldap->unbind;

Two IPv6 addresses defined? Try this

If you have an IPv6 network set up, the likelihood is that you are making use of Router Advertisements to allow your systems to automatically grab an IP address.

However, if you then statically assign an IPv6 address to a server, for example, you end up with two IPv6 addresses … which seems to me to be very messy. Deleting the dynamically assigned address seems to be pretty difficult … you can delete the DNS entry to try to stop other systems using it, but the DNS entry will come back.

The answer lies with netsh. All you need to do is run this command:

netsh interface ipv6 set interface <x> routerdiscovery=disabled

where <x> is the index for the interface. This can easily be found with the command:

netsh interface ipv6 show interface

This will stop the server from listening for those Router Advertisements and automatically remove the dynamic address.

Pinning a WordPress blog with IE9

If you’ve got IE9 installed, you’ll know that one of the features it introduces is the ability to pin a website to the Windows 7 taskbar and, depending on how the site has been defined, gain useful shortcuts from the jump list.

The Windows Team recently shared that if you use this feature with a WordPress blog, you really get some great benefit and the thing about WordPress is that there are over 20 million sites that immediately gain this benefit.

So what does it give you? Well, here is the jump list for my blog, pinned to the task bar:

image

So, at the top, you get the 5 most recent posts followed by a set of tasks that are most useful to the blog owner.

If you enjoy reading this blog, please consider pinning it to your taskbar. Alternatively, you can now subscribe to the blog by email – there is a Sign me up! button on the right hand side of the page, at the top. You’ll then get notifications of new posts by email. Alternatively, there is the good old RSS Feed, which is on the page just a bit higher than the Email Subscription feature.

Thanks for reading.

Lessons Learnt Deploying DirectAccess

I’ve recently been working on a basic DirectAccess (DA) configuration, using a Windows Server 2008 R2 virtual server with 2 network interfaces to provide the DA service. The ultimate aim is to use UAG (Unified Access Gateway) to provide a more complete DA experience but a recommendation I picked up from TechEd 2011 was to build a working DA implementation with just the DA role in Windows Server so that, once that is working, you can replace the DA server with UAG and if it stops working, you know it is the UAG server you need to fix.

The company I work for has perhaps a slightly unusual network configuration in that both the DMZ and Internal networks use public IP addresses. This was done before I joined them :-). I’ve recently introduced private IP addresses to augment the number of addresses available to us but my initial implementation had both NICs on the DA server using public IP addresses.

That seems to be a configuration that Direct Access can’t handle although you won’t see any errors. The upshot of this configuration is that the 6to4 adapter on the DA server, which is used to tunnel traffic from clients with public IPv4 addresses, had three IPv6 addresses instead of two. The two you would expect to see map onto the two public IPv4 addresses used on the external NIC.

This was diagnosed by performing network captures on the client whilst trying to ping some IPv6 addresses on the internal network. If you are trying to do DirectAccess network troubleshooting, I would strongly recommend the use of Microsoft’s Network Monitor tool, even instead of other popular tools such as WireShark. One of the reasons I make this recommendation is because Network Monitor will capture traffic going through tunnel adapters such as the 6to4 adapter, whereas WireShark seems to be only able to capture traffic going through physical adapters.

When you do a packet capture on a DA client, you’ll see both the IPv4 and IPv6 traffic. What happens is that the client will wrap the IPv6 PING into an IPv4 packet, pass it across to the DA server where it then gets unpacked and the IPv6 packet sent out.

What I was seeing was that instead of the wrapped up packets going to the external IPv6 address of the DA server, they were going to the internal IPv6 address … which clearly wasn’t going to work because the internal interface isn’t reachable from outside. To solve that particular issue, I had to reconfigure the DA server’s internal NIC to use a private IP address. That stopped an address being created on the 6to4 adapter for it and that allowed the tunnelled traffic to be sent consistently to the correct destination.

The next problem I faced was that the IKE tunnel wasn’t being set up. IKE failure is typically due to certificate problems. There is a good document called DirectAccess Client Cannot Establish Tunnels to the DirectAccess Server that says:

If the DirectAccess client computer cannot establish the main and quick mode SAs for the infrastructure tunnel using the default connection security rules created by the DirectAccess Setup Wizard, the most likely problem is a certificate authentication failure. For more information, see the “IKE certificate selection process” and “IKE certificate acceptance process” sections of Public Key Certificate.

Under “IKE certificate selection process”, the document says:

IKE searches the computer store for an IPSec certificate that chains to any of the trusted CA roots identified in step 1. An IPSec certificate contains an Enhanced Key Usage (EKU) attribute with a value equal to the IP security IKE intermediate object identifier (OID) 1.3.6.1.5.5.8.2.2.

Ah, I thought! I’ve only installed a certificate with the Server Authentication OID, not the IPSec IKE intermediate OID. So, I removed that cert, installed a cert with both OIDs and tried again. Things got further … when I tried to ping an internal IPv6 address, there were AuthIP packets being exchanged but the tunnel wasn’t being established and I couldn’t see why. This proved to be a harder issue to troubleshoot so I want to share the two tools I used that ultimately got me to the right answer.

The first tool is netsh, which provides network tracing functionality at a level better than Network Monitor. As an administrator, you run:

netsh trace start scenario=directaccess capture=yes report=yes

then you reproduce the problem and then you run:

netsh trace stop

This captures all of the network traffic into an ETL file which can be opened in Network Monitor. This revealed that the AuthIP traffic was failing because of the error “authentication credentials are unacceptable”. So this was still suggesting a problem with the certificates, but what?

Enter the second troubleshooting tool – event logging for CAPI2. CAPI2 is the part of the OS that deals with certificates. It is very straightforward to turn on event logging for CAPI2. Once you’ve done that, you again reproduce the problem and then look at the event log to see what is being shown.

In my case, the CAPI2 logging showed that the client goes through a process of checking that the server’s certificate has an Enhanced Key Usage of … Client Authentication. NOT, as the TechNet article said, IPSec IKE intermediate.

Again replacing the certificate on the server, this time with a cert for client and server authentication, and the tunnel is now getting established!

 

Quick tip for deployment task sequences

It is great when an application comes packaged with an MSI because it is so easy to deploy those, whether you are using MDT or Configuration Manager. However, sometimes you need to do a little bit more than just install the MSI – you might want to run a script to give you a bit more flexibility.

The problem is, though, that when you run msiexec to install the MSI, it returns straight away which isn’t very helpful if your script can’t do what it needs to do until the application has been properly installed.

Thankfully, the solution is quite simple. Instead of just executing the normal msiexec /i command, prefix it with start /wait (followed immediately with the rest of the normal command) and the MSI will get installed but the script won’t continue until it has completed. Any error code from the MSI installation is returned to your script.

The importance of keeping drivers current

I’ve just been writing a review of Synology’s DS1511+ NAS unit for Digital Media Thoughts and I wanted to really throw some data at it to see how it performed. I’ve got my media PC connected to the NAS over a 1Gb switch, with multiple SATA drives connected to the PC.

Using TeraCopy, I set up four copies – one for each of the SATA drives – to a single volume on the NAS. However, copying was not entirely successful – it would work for a while and then seem to just give up. Disabling and enabling the Ethernet interface on the PC seemed to get things going again for a while but it wouldn’t last.

Looking at the drive for the RealTek Ethernet interface, I noticed that it was quite an old driver, dated 2007. Looking in their web site, I could see that they had much newer versions, which I then downloaded and installed onto the PC.

The difference was fantastic. All four copies went smoothly, taking the average network utilization up to around 80% or 800Mb/s. A big improvement for such a small amount of effort.

It just goes to show … it doesn’t hurt to periodically check the drivers on your system to see if any of them have newer versions. You might be surprised at the results.

How to hide shared folders under DFS Namespaces

There is a very well known “trick” to hide shares with Windows and that is to put a $ sign at the end of the share name. The problem is that this doesn’t work if you are using DFS Namespaces (DFSN).

The reason why it doesn’t work is because DFSN doesn’t advertise shares – it advertises folders and there is an underlying mechanism to transparently redirect computers trying to connect to those folders to the underpinning shares.

So if you have folders in your DFS Namespace that you want to hide just as if they were a share, how do you do it?

The answer lies in the fact that they are, indeed, folders. Go to the DFSN root server and open up the folder for your namespace. Right-click on the folder you want to hide and choose Properties. Then select the Hidden attribute and click OK. You will be asked if you want to apply the change to this folder only or to this folder, subfolders and files. You only need to apply the change to this folder only.

Be mindful of the fact, though, that this trick of hiding the folders only works so long as users aren’t showing hidden files and folders on their computers. If they are, these folders will still show up.

To make it even harder for users to find these “hidden” folders, it is necessary to set the System attribute on the folder. This then prevents the folders from being seen unless the user has unticked “Hide protected operating system files”.

Setting the system attribute on a folder requires the use of the attrib command with a very specific sequence of flags:

attrib –r +h +s <folder path>

The –r flag removes the read-only setting which is normally used by Windows on folders as an indicator that the folder might have customisation on it. Since we are talking about folders in the DFS Namespace, that isn’t going to apply here.

The +h flag applies the hidden setting. You need to do this as part of the same command as +s in order to make sure that the folder does actually get hidden and not just set as a system folder. You cannot apply the hidden flag after the folder has got the system flag set.

The +s flag applies the system setting.

A new home for my blog

I was slightly concerned when I first heard that Microsoft were closing Live Spaces … where would I go to put my blog and what would I need to do in order to retain my postings so far?

Thankfully I needn’t have been concerned. Microsoft had it all covered. They have paired up with WordPress and provided an automated process to migrate sites.

So now my blog is at https://pcmusings.wordpress.com/. Please update your RSS subscription if you have one. WordPress has a lot of new functionality to explore so bear with me while I look around and see what is possible.

The dangers of using Public Wi-Fi?

I thought that I would fire up Windows Media Player so that I could listen to some music while finishing off the editing of my holiday diary. I’m currently connected to the Orlando International Airport free Wi-Fi service and this is what WMP is displaying:

image

Now I know that I selected Public as the network type when I connected. Did these other people? If they did, how do you stop WMP from making your content freely available?

Most of the computers report “Before you can play items in this library, you must first be allowed the access the library”. Others, however, when selected, start to connect to the PC … but then report “No files have been found on this remote library”.

So it would appear that no harm is done. However, information is being made available, e.g. the computer name, and that would give a starting point should someone want to start an attack.