We communicate through images, movement, sounds, text, symbols, objects…

Bots are evolving so fast! Last October I wrote about how bots are the new apps and shared my thoughts about why bots and about the opportunities they create. Over the past few months, interest has grown and we as a community have iterated on our approaches to build bots. For some, the hype has gotten to a point where everyone wants one, but do we really understand them or the efforts that are required to build them.

So far, my initial thoughts have stood the test of time. 

The following are observations, experiences and thoughts, about what we need to consider when we set out to build a successful bot. 

Bots are the new Apps – Part 2

Bots are defined by an exceptional user experience! And not by the amount of Artificial Intelligence (AI) or by Natural Language Processing (NLP) that is used to build them.

A bot is successful if users actually use it! This is important, because we must build our bots with meaningful telemetry, logging and data collection mechanisms that empower us to measure, validate and iterate. This data forms a foundation that we can use to hypothesize and prioritize our efforts. Then through A/B testing we confirm that we solve the user’s need in the quickest and easiest way possible. This in itself directly impacts our business model and pushes us to grow the end-user consumption and shift our business model to selling through microtransactions. In other words, a bot helps users be successful. Continue Reading…


Getting Around Blocked Ports

Regularly, I find myself in a location that blocks ports to the outside world. In many of those moments, I can’t use Remote Desktop (RDP) sessions to connect to Virtual Machines hosted on Azure. The strategy expressed in this post is one of many possible solutions that also applies to Linux and SSH sessions.

The Strategy

  • Using a Load Balancer and NAT rules to map port 443 to the RDP (3389) port for a Jumpbox Virtual Machine (VM)
  • Using the Jumpbox to RDP into VMs deployed to the Azure Virtual Network.
    Continue Reading…

Migrate a Storage Account to ARM

If you’ve been working with Azure for a while, you may have some of your Azure Storage Accounts deployed on the Classic deployment model (ASM). To simplify the deployment and management of resources, Microsoft recommends that we use Azure Resource Manager (ARM) for new resources. If possible, it’s also recommended that we redeploy existing resources through Azure Resource Manager (ARM), because the two models are not completely compatible with each other.

Fortunately, moving resources like Azure Storage is possible through PowerShell. Use
the Move-AzureStorageAccount cmdlet to prepare, migrate and to validate that the migrated Azure Storage Account is moved successfully to a resource group in the Azure Resource Manager (ARM).

Validates the Azure Storage Account for migration.

Move-AzureStorageAccount -Validate `
                         -StorageAccountName "ContosoStorageName"

Prepare the Azure Storage Account for migration.

Move-AzureStorageAccount -Prepare `
                         -StorageAccountName "ContosoStorageName"

Kick-off the migration.

Move-AzureStorageAccount -Commit `
                         -StorageAccountName "ContosoStorageName"

Source: Move-AzureStorageAccount


Getting to Know Containers

Containers have sparked genuine interest over the last few years. As a developer, I’ve had my fair share of “It Works on My Machine” days, where I spent an interesting amount of my time trying to identify why my code doesn’t run in a given environment. Did I make a mistake? Did someone else make a mistake? Uncertainty, risk and the Human Factor definitely make for adrenaline packed all-nighters. Continue Reading…


Using PS to Add a Key to the Registry

In a recent experiment, I had to disable User Account Control (UAC) on a remote Virtual Machine through WinRM.

Note

To better protect those users who are members of the local Administrators group, we implemented UAC restrictions on the network. This mechanism helps prevent against “loopback” attacks. This mechanism also helps prevent local malicious software from running remotely with administrative rights.

Whenever I deal with the registry, I always feel like the guy in the picture above. You never know if you’re going to regret making changes…

Anyway, this was an experiment, so please, use this wisely.

$registryPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$Name = "LocalAccountTokenFilterPolicy"
$value = "1"

New-ItemProperty -Path $registryPath `
                 -Name $name `
                 -Value $value `
                 -PropertyType DWORD `
                 -Force | Out-Null

# Restart the VM to apply the changes
Restart-Computer -Force

What’s this all about?

In the old days, R&D was about features, marketing was about promoting products to prospective decision makers, sales were about getting big deals, and service was about implementing and fixing things. Today, it’s all about growing end-user consumption and selling microtransactions to consumers.

The risk is on us, and our reward only happens if our end-users are successful.

Success doesn’t magically happen… Product marketing must design for it, development must build for it, services must contribute heavily to consumption research, marketing must translate the findings into offers, offer management technology must deliver it, services must access it during every service transaction…

In short, consumption is everything. If end-users underutilize our software, chances are that at some point the company we code for, won’t be able to pay for our services. We are all responsible for crafting successful software. From developers to sellers, everyone is liable to provide feedback, insights and value to the end-users. This is a team effort and can be supported through practices like DevOps, Business Intelligence and Artificial Intelligence. This requires communication and collaboration. It’s time to forget about silos and to move from a one-time sale to a pay-per-use model. Continue Reading…


Unzip a file in PowerShell

Automating configurations on remote machines can sometimes make simple things interesting. In this specific scenario, I needed to use WinRm to Upload a file to a Virtual Machine (VM) on Microsoft Azure. Then I needed to unzip the file and finally go ahead with the configuration of the said software.

Searching the web gave me an appreciable amount of creative ways to go about unzipping files. This was by far the simplest approach I found. Keep in mind that it requires .NET 4.5.

$sourceFile = 'C:\assets\Microsoft.Azure.ServiceFabric.WindowsServer.5.3.204.9494.zip'
$targetFolder = 'C:\Microsoft.Azure.ServiceFabric.WindowsServer'

[System.Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
[System.IO.Compression.ZipFile]::ExtractToDirectory($sourceFile, $targetFolder)

What if you could increase the accessibility of your App? While we’re at it, what if you reached a greater audience, reduced deployment complexity and reduced training costs?

Bots are the new Apps

In 2016, companies are facing unique challenges in their efforts to transform themselves. In their quest for diversity and inclusion, companies are challenged to step away from their comfort zones and to unlock new opportunities. Imagine for a moment that you are tasked with hiring a niche candidate. The company you work for is primarily English-speaking and the best candidate for the job speaks Spanish, is blind and deaf. Would you pass up this opportunity because of accessibility? Continue Reading…


Ignite has been over for a little while, and I finally have some time on my hands to dive deep. This is the script I use to bring the videos offline for further filtering and to be able to watch the sessions on my own terms.

Download All Sessions in SD Quality

$feedUrl = 'https://s.ch9.ms/Events/Ignite/2016/RSS'
 
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title
    )
     
    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension

    $fileName = $fileName -replace "’", ''
    $fileName = $fileName -replace "\?", ''
    $fileName = $fileName -replace ":", ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace ",", ''
    $fileName = $fileName -replace '"', ''

    $fileName
            
    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile $fileName
    }
}
  
$feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)
 
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*mid.mp4' `
                     } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}

# Find and Download Keynotes

foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*KEY0*' `
                        -and $_.type -eq 'video/mp4' `
                       
                     } `
                     | Select-Object -Unique `
                     | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}

Quick Thoughts

Businesses need to be agile to compete in today’s global economy. Programmers use various tools and techniques in order to meet this business requirement. The challenge is great and quite complex. Going too fast without the right approach can lead to ephemeral success.

I believe that Microservices give us the agility and architectural patterns that empower us to scale and create value at a far greater pace for the business compared to using a traditional tiered architectures approach.

Forget about 3-tier architectures, they just doesn’t scale. Stateless services need to rebuild their internal state for every call, and they can generate tremendous pressure on data stores. Consequently, this generates back pressure that bubbles up through the layers of our solution and reaches out to the edge. Back pressure then translates into unavailable services. The key is Data Locality and Stateful Services.

statemonolithic-vs-micro

Continue Reading…