Archives For PowerShell


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


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

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)

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…


Deploying Azure Marketplace VMs

The first step is to gather information about the Market Place Virtual Machine (VM) image that we want to deploy. For this example I decided to deploy a Tableau Server image.

Login-AzureRmAccount

$location = 'eastus'
  
Get-AzureRmVMImagePublisher -Location $location `
    | Where-Object -Property PublisherName -Like Tableau*
 
$publisherName = 'tableau'
  
Get-AzureRmVMImageOffer -Location $location `
                        -PublisherName $publisherName
 
$offer = 'tableau-server'
  
Get-AzureRmVMImageSku -Location $location `
                      -PublisherName $publisherName `
                      -Offer $offer `
      | Select-Object -Property 'Skus'

Skus                  
----                  
bring-your-own-license

Now that we have the image information, it’s time to create an Azure Resource Manager (ARM) Template. Continue Reading…


Geo-HA Service Fabric Cluster

One of the biggest challenges that we face when we build an Internet-scale solution, is high availability across geographic locations (Geo-HA). Why is this important? Well, there can be a few different reasons. The most common reason, is to be able to survive data center outages. Another reason, is to bring services closer to end users so that we can provide good user experiences.

Geo-HA brings challenges to the table. For example, should we use an Active-Passive or Active-Active strategy for data across regions? Keeping in mind that Active-Active is difficult to get right, we need to take time to analyze and to make the correct choices. We need to consider our Disaster recovery (DR) plan, target RPO and RTO. Azure has a whole bunch of mechanisms for replication, backup and monitoring, so how do we decide what’s the right combination?

Today’s Internet-scale services are built using microservices. Service Fabric is a next-generation middleware platform used for building enterprise-class, Tier-1 services. This microservices platform allows us to build scalable, highly available, reliable, and easy to manage solutions. It addresses the significant challenges in developing and managing stateful services. The Reliable Actors API is one of two high-level frameworks provided by Service Fabric, and it is based on the Actor pattern. This API gives us an asynchronous, single-threaded programming model that simplifies our code while still providing the advantages of scalability and reliability guarantees offered by Service Fabric.

A Service Fabric cluster is HA within its geographic region by default. Thinking about our heritage of on premise data centers, we’ve poured thousands of man-hours to deploy Disaster Recovery sites in secondary physical locations, because we know that everything is possible. Over the past few years, we’ve experienced many interesting scenarios, for example, a cut cable, or a faulty DNS entry broke the Internet. So why should we do anything differently in the cloud? We must treat each region as we treat our own data centers and think about Geo-HA.

The rest of this post is about taking high availably to the next level by deploying a Geo-HA Service Fabric cluster. Continue Reading…


As sessions make their way to Channel 9, we can download them using this PowerShell script.

Download All Sessions in SD Quality

$feedUrl = 'http://s.ch9.ms/Events/Build/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
        }             
    }
}

Continue Reading…