Sunday, May 15, 2016

The Division and delta 20010186

There is no doubt that if you search on The Division for the Mike or Delta error messages you will uncover a sordid history of unhappy users that began with the beta and continues.

My son recently invested in this game only to pop it into the Xbox to be greeted by the "delta 20010186" error.

  1. enable uPNP
  2. If you have a router behind your modem, put your modem in bridge mode
  3. Rerun the Xbox multiplayer network test (see the link below) - UBISoft requires this to test as 'open'
The long winded explanation:

If you search on this you will find all kinds of guessed at solutions.  From punching port forwarding rules in your firewall to putting your Xbox wide open for attack in a DMZ (seriously, these are the suggestions from UBISoft for Xbox connectivity)

Considering the number of folks that run into this issue, I really don't think UBIsoft understands it.

After thinking about this and spending hours troubleshooting, my conclusion is this: UBISoft blocks the game working if there is any reduction in the multi-player experience at all.

If you read the Xbox network descriptions, there should be grades in the experience where only certain features of the game don't function if the connectivity status is reduced from the full set.  And I can only speculate that UBISoft chose to not follow this guideline (could be by choose or ignorance - the result is the same).

There is a mysterious black box type issue on the Xbox side that puts the pieces together.
It is rooted in the output of the Xbox multiplayer network test and the resulting "NAT type".
This is not a setting that any human can impact, nor any resetting, cryptic combinations of movement through the settings menus or anything else can reliably impact.

From what I can tell, there are a couple issues going on here.

1. There is an expectation that uPNP is enabled on your router.

The multiplayer mode requires communication back to your Xbox. 
This is why there are port forwarding rules being suggested, and DMZ placement.  If uPNP is not available or not working, this this would solve that issue.

Adding to this is claims that I uncovered that stated that Xbox historically had issues with properly making the uPNP router when it is set to 'InstantOn' power mode.
Again, uPNP not working for a different reason.

Wrap all of these together and you have a combination of things that all impact connectivity back and the Xbox test for multiplayer connectivity puts you in the Moderate or Severe NAT bucket.

2. Beware the double NAT

No matter the setting on your router, if you have put yourself into a double NAT configuration, you will never be tested as 'open' by Xbox.

What is this double NAT?  It is when you hop through two IP address changes on your end of the network.
Frequently a double NAT happens in the IT world to isolate front end web servers or to further protect the corporate network by using two firewalls instead of one.

For the home network, the first NAT would be between your ISP (Comcast, ATT, etc.) and you - your cable modem (or FIOS modem, 'the modem').  The ISP network IP address range is converted once.
If you go straight from your modem to a switch, you are probably good.

The second NAT happens when you put a router behind your cable modem.  Thus you end up traversing another IP address change.  Thus a second IP change.  The key here is that the public side of this second NAT is private behind the first firewall of the modem.

This looks like this:  - modem - - router -
The problem is that any modifications you make to your router get trapped in this container .
Not even port forwarding or DMZ will work properly here unless your cable modem supports uPNP or does not offer a firewall at all ( most give a firewall and default you into this first NAT ).

The things here, simply put your model into 'bridge' mode.
What this does is turn off this first NAT, and your router gets the public side IP from your ISP instead of your cable modem getting it.
The impact here is that for most of us, this means only ONE device can plug into the modem.  As you only get one IP of the ISP network.

If you cannot put your modem into bridge mode, put attach your Xbox directly to the modem (using a switch to go around your router).
I am always assuming that there is still some network protection here, at least a basic firewall.  As just about anything can be hacked these days.

I always want folks to understand how things work, how things function and to tie as much as what I uncover together in a cohesive way.  That is what I have attempted to do here.

I hope it helps some folks, or solves the problem for others.
It is very frustrating to bring a new game home ($80 - $100) only to have it not work (fail to load) at all.  From the number of passed customers on the web, I am not alone.

Wednesday, March 16, 2016

PowerShell to the Philips Hue API

If you have been to HPE Discover London 2015, Aruba Atmosphere 2016, CeBIT 2016 or you are going to Citrix Synergy 2016 you will have an opportunity to experience the Collaborate Cube(d).

I have been working with the Cube (making it do its song and dance) and related technologies for nearly two years.

This is an IoT thing.  But what we are driving and the place we are operating is not what most folks thing of as IoT.
This is about taking context (a person, a physical place, the capabilities of a space, and what is relevant at this moment in time) and tying them all together into a set of context specific actions (capabilities, events, controls - call it what you will).

The actions are relevant to this time and place.

One of the actions in the Cube is setting lights around the glass enclosure to red (the room is busy) or green (the room is available).

This sounds pretty simple on the surface.  You hook up a Philips Hue then you link it in, then you send some commands.  Actually, it is rather simple.  Except one part that is not entirely obvious to most folks (that aren't makers nor developers), and that is getting that first connection in the first place.

In helping to set the Cube up at three venues now, the Hue connection still seems to be one of the more complex things.  Especially when you Hue is brand new (which of course it is at each show :-S  ).

So, I have a little PowerShell script that will give you what you need to:
  1. create a valid user in your local Hue bridge
  2. get the information you need to connect to that
Of course I am using Octoblu to control the Hue.  Why wouldn't I?  There are some decent instructions for getting things set up. (see Step 4, then instead of 3 come back here, then 5).
But they send you off to an API document to sort out the one critical getting started piece, getting connected.  And then Philips hides their API guide behind a registration gate.  Double whammy.  Too much effort.  Walk away.

Here is my script, with comments, to get you started.
And after you get hooked up, there is most likely enough guidance in this script for you to simply play with the Philips Hue API.  ;-)

You can copy, save, and run this script and it should do everything you need.

# Associate your Hue Bridge with Octoblu.
# These are the setup things you need to do.

# find the Hue on your local network - this assumes you have only one
$hueIp = Invoke-RestMethod -URI
$ip = $hueIp[0].internalipaddress

$gatebluName = Read-Host -Prompt "Enter the name of your Gateblu"

Do {
    if ( !$hueUser ) {
        Write-Host -ForegroundColor Black -BackgroundColor White "Press the button on the top of the Hue bridge."
    elseif ( $hueUser.error.description ) {
        Write-Host -ForegroundColor Black -BackgroundColor White $hueUser[0].error.description
    Read-Host -Prompt "Enter to continue"

    #Hue create account
    $body = @{ "devicetype" = "gateblu#$gatebluName" }
    $json_body = $body | ConvertTo-Json
    $hueUser = (Invoke-RestMethod -URI http://$ip/api -ContentType "application/json" -body $json_body -Method Post -ErrorAction SilentlyContinue)[0]

} until ( $hueUser.success )

$apiUsername = $hueUser.success.username

Write-Host "Open the Philis Hue Thing in Octoblu interface"
Write-Host "Select the Gateblu instance to connect to"
Write-Host "Enter: $ip as the ipAddress"
Write-Host "Enter: $apiUsername as the apiUsername"

# Return the full state
$hueState = Invoke-RestMethod -URI http://$ip/api/$apiUsername -ContentType "application/json" -Method Get -ErrorAction SilentlyContinue

"Configured Lights:"
$hueState.lights | Format-List

"Configured Groups:"

# Full configuration
# $hueState.config

Wednesday, March 2, 2016

How can my Checkpoints be consuming more storage than the root virtual disk?

I explain this in the forums every so often.

Folks Create a VM, then a few Checkpoints.  And before they know it they are in that horrific Paused-Critical state with their VMs.

All because they are running out of storage.

In the end, it comes down to many folks not really understanding how this happened in the first place.

It really goes back to the fact that Checkpoints use differencing disks.  And each differencing disk has the potential of consuming as much disk space as its parent.

First of all; the warnings:
Be sure to only delete checkpoints through the Hyper-V Manager.
Do not attempt to manually delete AVHD files on the local file system.

Also, dynamic disks do not matter.  Whether your VM began with a dynamic disk or a fixed disk makes no difference. 
A dynamic disk just gives the illusion of consuming less space as the full potential of the disk is not realized.
But all differencing disks are dynamic, regardless if the parent was fixed or dynamic.

The root concept here is:
Each Checkpoint disk has the potential of consuming the maximum amount of disk space that its parent did.

For example:  Say you make a VM with the default of a 127Gb dynamic virtual disk (you have the potential of consuming 127Gb of storage). 

You install an OS and only 14Gb of physical storage is used. 
You then take a Checkpoint.  Now, you have the root 14Gb, and the potential to consume another 127Gb of additional storage.
Time passes and this Checkpoint consumes 50Gb of storage.  14 + 50 = 64Gb consumed.
You now take another Checkpoint.  And all kinds of stuff happens in that VM OS. 
You install Visual Studio create a database application, who knows. 
And with all that the current state is now consuming 80Gb of Storage.

You have only increased the disk use by 30Gb. 
But, with the Checkpoint tree in place you have now consumed 14 + 50 + 80 = 144Gb. 
Beyond the 127Gb limit of the virtual disk. 

Because of the potential of each Checkpoint being able to consume 127Gb (of VM disk change) all by itself.

Side by side with this is folks that use Checkpoints or differencing disks with the false idea that they will save storage.  Over time, they save nothing and add complexity.
Unless you are doing test and are constantly tossing away VM disks and creating new ones, using differencing disks with the argument of reducing storage use is a very false assumption.

Tuesday, December 1, 2015

Error handling can make or break an experience

This post is a bit of an adventure in building a very small piece of a rather cool demo.
It is really an adventure in developing thorough unit tests.

Some of you have probably noticed that my blog has been kind of dead for a pretty long stretch.  Needless to say, I have been busy.

This week is HP Discover in London.  It is a really big show for HP.

There is a demo called Collaboration Cubed.  And I must say, it is pretty cool.

This is all about building an experience more than it is about building software.

There is this big glass cube, with two monitors, a table, three Surface tablets, and more.
You walk in with a phone, you are recognized. 
You are welcomed by a synthetic voice. 
The room is tagged as occupied. 
Your cohorts come into the room.
A Lync meeting begins on the wall monitor.
A tweet is sent out.
You sit down at the table and your tablets are 'called' through Lync. 
You collaborate and save stuff. 
You exit the cube, the Lync meeting is exited and a follow-up email is sent.

Aruba handles the device detection.
Octoblu handles the automation of the actions.
Microsoft provides OneDrive and Lync.

Why describe all of this?  Well, for one thing I am kind of excepted about it.  But at the same time, there are lots of moving parts.  And each moving part must play its role.

I had a simple request around the tweet.  Since not everyone provides their twitter handle, can we substitute their first name instead?

Sure, sounds easy enough.
I observed some of the data I had captured.
I thought I was being rather cleaver with my solution and keyed off whether or not there was an '@' in the twittername field.
I tested it, it was great.
I deployed it.

Poo, a new case arose.  The app sending me data is suddenly sending me a twittername that is no more than '@'.  Now I am sending tweets with @ @ @ in them (and hoping that the Twitter spam bots don't kick in and suspend the account).

Suddenly I find myself focusing on my unit tests and the variations that I have seen as well as dreaming up ones that I have not seen but expect to.

In the end to handle this simple request I had 9 conditions to cover the cases of the expected data from the other application.
The golden case where everything is good, and eight cases of other stuff.

Since I use PowerShell to do everything, my JSON looks like this:

$TwitterHandles += @{ “firstname”=”Brian”; "twittername"="@testhandle" }
$TwitterHandles += @{ “firstname”=”Brian”; "twittername"="@" }
$TwitterHandles += @{ “firstname”=”Moheeb”; "twittername"="" }
$TwitterHandles += @{ “firstname”=””; "twittername"="@" }
$TwitterHandles += @{ “firstname”=”Thomas” }
$TwitterHandles += @{ “firstname”=”Joe”; "twittername"=$null }
$TwitterHandles += @{ “firstname”=$null; "twittername"=$null }
$TwitterHandles += @{ “firstname”=”Joe”; "twittername"="null" }
$TwitterHandles += @{ “firstname”="null"; "twittername"="null" }

I had two data fields to cover issues with; twittername always being my first key and the possibility of substituting the firstname.
Now, the resulting code I wrote in JavaScript.  And there is the possibility for 'null' and null.  This is null as a string vs. null as an object / value.  These go right along with missing or blank values.

Suddenly I have something with much better coverage of the possible cases and thus a much better product.
One hour to get the first version and three to work out all the error handling cases.

the end result is a solid product.  But the lesson is to not focus on getting it done, it is to make it solid.

In case anyone want sot see the javascript, here is it;

// Requirement: If there isn't a twitter handle provided, replace with the first name
if(typeof (msg.params.twittername) !== "undefined" && (msg.params.twittername) !== null) {
 if ( (msg.params.twittername).substring(0,1) === "@" && (msg.params.twittername).substring(1) && (msg.params.twittername) !== "null" ){
  return msg;
 } else {
  if ( (msg.params.firstname).substring(0) && (msg.params.firstname) !== "null" ) {
   return {
     twittername: msg.params.firstname
} else {
 if(typeof (msg.params.firstname) !== "undefined" && (msg.params.firstname) !== null && (msg.params.firstname) !== "null") {
  return {
    twittername: msg.params.firstname

Thursday, September 24, 2015

PowerShell to manipulate Skype for Business and Lync converations

A recent project left me playing with the Lync SDK (Skype for Business).

The Skype for Business skin was clad onto the Lync 2013 client.  And thus the Lync 2013 SDK is the one I worked with.
Much of the SDK documentation is centered around writing your own application integration with Lync, event listeners, triggers, etc.  I am just wanting to drive Lync, not write a replacement for it.

Yes, I do know that Office 2016 released (yesterday) but I am not going there just yet.

Lets do some interesting things with Lync:

First - if you want to get started with Lync and PowerShell there are a few blog posts.  I find the automating Lync with PowerShell tutorial from Trevor Sullivan to be the most comprehensive / useful.  I am not going to re-hash what Trevor has already done pretty well.

He walks you though downloading the SDK, installing it, and invoking the 'model' DLL that you need to perform all of the actions.

If you are not a developer, then you still need to install the SDK, for one particular MSI - the redistributable.

In the install folder of the SDK ( C:\Program Files\Microsoft Office\Office15\LyncSDK\Redist ) is the lyncRuntime.msi.  This will give you only the bare minimum DLL that you need to make this all happen.  This would be the thing you package into your application.

Now, allow me to build upon Trevor's foundation.
I am going to launch a 'conversation', then call someone, then start open 'application sharing', then end the conversation.

The big assumption here is that you are logged in to Lync.  I am not going to test for that, MSFT has examples.

# import the Microsoft.Lync.Model.dll
Add-Type -Path 'C:\Program Files\Microsoft Office\Office15\LyncSDK\Assemblies\Desktop\Microsoft.Lync.Model.dll'

# Get the Lync Client SDK automation object
$Automation = [Microsoft.Lync.Model.LyncClient]::GetAutomation()

At this point in time I could go two directions.  I could use the 'Meet Now' feature, or I could build a conversation object the hard way.
What I have learned through experimentation is that the Meet Now sets up quite a few things for you and is thus pretty useful.  I have gone about it the other way and run into sharing problems that I don't run into when using Meet Now.  So I will take advantage of the fact that they have provided this.

# Launch a 'Meet Now' conversation
$meetNow = $Automation.BeginMeetNow({}, 0)
# Get the conversation window to manipulate the conversation.
$conversationWindow = $Automation.EndMeetNow( $meetNow )
# Get the conversation
$conversation = $conversationWindow.Conversation

The first thing that I noticed is that I have something that looks no more than an 'InstantMessage' modality conversation.   That is developer speak for I started a conversation and began a session of the type called instant message.
My experimentation shows that you always have IM in the background, it appears to be the base of the conversation.

Now, I want to create an empty 'Stage' just illustrate the rest.
So I will add the Application Sharing modality.

$Conversation.Modalities['ApplicationSharing'].BeginConnect({}, 0)

The Conversation Window object, there are a few things you can do to it.
Such as, make it full screen.


Now, I want to call someone.  And to do that, I add a participant.
To add a participant I do need one piece of information, their SIP URL.  For most organizations this is the email address of the individual, but it does not have to be (that is the caveat).

# add a person only knowing the SIP address (they do not need to be in your contacts list)
$conversation.AddParticipant( $LyncClient.ContactManager.GetContactByUri( "" ) )

# they will receive a Lync Call

You can keep adding folks.  If you forgot who you added, you can look:

$conversation.SelfParticipant # this is you
$conversation.Participants # this is everyone

Now, lets begin to close down this meeting example.

# exit full screen
$conversationWindow.ExitFullScreen() # note the application is left maximized.
# lets resize the window
$conversationWindow.Resize( 300, 300 )

# remove a participant (we only have their SIP address)
$removePeep = $conversation.Participants | where { $_.Contact.Uri -Match "" }

That was a sneaky one liner of me.  Note that I took all of the participants (which is always an array BTW) and I looked for the ContactUri that contained the email of my person to kick off the meeting.

$conversation.RemoveParticipant( $removePeep )
# note, the person you remove receives a notice that they were removed from the conversation.

# End the meeting


That is it.  The lifecycle of a Lync meeting from PowerShell

Those objects are powerful.

Say that you already have a meeting running and you want to use PowerShell to find it;
For this we need the Conversation Manager.

$LyncClient = [Microsoft.Lync.Model.LyncClient]::GetClient()
$conversation = $LyncClient.ConversationManager.Conversations

And then find the conversation (as we can have more than one IM conversation at a time).

Now, a few other shortcuts to get you working:

# add IM into IM Window
$Conversation.Modalities['InstantMessage'].BeginSendMessage("Welcome", {}, 0)

# what I can share
$resources = $Conversation.Modalities['ApplicationSharing'].ShareableResources

# share my desktop
$Conversation.Modalities['ApplicationSharing'].BeginShareDesktop( {}, 0)

# share a specific resource
$Conversation.Modalities['ApplicationSharing'].BeginShareResources( $resources[1], {}, 0)

# add voice
$Conversation.Modalities['AudioVideo'].BeginConnect({}, 0)

# remove contect sharing (stop sharing, stage stays present)
$Conversation.Modalities['ApplicationSharing'].BeginDisconnect([Microsoft.Lync.Model.Conversation.ModalityDisconnectReason]::None, {}, 0)

# stop the video call, keep the IM
$conversation.Modalities['AudioVideo'].BeginDisconnect([Microsoft.Lync.Model.Conversation.ModalityDisconnectReason]::None, {}, 0)

# send a thanks for attending IM
$Conversation.Modalities['InstantMessage'].BeginSendMessage("Thanks for attending. Tasks will follow.", {}, 0)