Showing posts with label powershell. Show all posts
Showing posts with label powershell. Show all posts

December 9, 2016

Day 9 - One year of PowerShell or DevOps in the Microsoft world...

Written by: Dominique Broeglin (@dbroeglin)
Edited by: Matt Stratton (@mattstratton)

Holidays are a time for reflection and giving back. This year, I thought I would reflect on my ongoing Linux to Microsoft transition and give back a few tidbits I learned about DevOps in the Microsoft world. This article is meant to illustrate a journey from Linux to Microsoft in hopes that the “from the trenches” perspective will help others attempting the same transition.

Let’s start with a quick background to set the stage.

Background

After an education in both software engineering and distributed systems, I worked for several IT companies, small and big, in a variety of domains such as telcos, education, justice, transportation, luxury goods, or the press. I was lucky enough to have the opportunity to work with bright people very early in my career. I’m very grateful to all of them, as I learned a lot from them and was spared quite a few mistakes. One of the subjects I was introduced to early is automation, both through my co-workers and through seminal books like The Pragmatic Programmer: From Journeyman to Master and its sequel Pragmatic Project Automation. This pushed me towards automated configuration management in the early days.

If memory serves, I discovered Linux somewhere around 1994 and was instantly hooked. I still recall that first Slackware distribution with its 50-something floppy disks. For twenty years, I’ve worked mainly on Linux and Unices, trying studiously to avoid any Microsoft product. Some people may even recall me swearing that I would never work on Windows. However, a few years ago Microsoft changed its approach, and I was, coincidentally, presented opportunities in Microsoft environments. As was once said by John H. Patterson, “Only fools and dead men don’t change their minds.” So I went on and changed mine, one step at a time…

Armed with almost 20 years of Linux experience and ten years of automated configuration management, I jumped into Microsoft automated configuration management.

Step 1: Develop on Windows, Deploy on Linux

The first step was a Java project that was starting. In that early design and setup phase, only a few people were involved. I was brought in to help with Java architecture and software factory setup. Having set up quite a few factories already that part was not new to me. However, we would have to onboard a sizable number of people in a small amount of time. That would be a challenge. Because, at the time it took quite a bit of time to setup a working environment for a developer, tester, architect or DBA.

During previous projects, I had used Vagrant to setup development environments that could be shared easily. Vagrant is a wrapper around a virtualization tool (at the time VirtualBox, but in the meantime, Hyper-V and VMWare were added too) that helps in setting up a virtual machine. It starts with a fixed base image, but allows for additional setup instructions to be declared in a file that can be shared in the project’s source control repository. Everything needed to setup the environment is declared in a file called Vagrantfile and when a developer wishes to set up his he just executes vagrant up.

A few minutes later, a fully operational environment is running inside a virtual machine which in turn runs on his desktop environment. In a MacOS X or Linux environment, the developer usually edits files by running his editor on the host system but builds, deploys and tests the system in the virtual machine. Moreover, Vagrant allows for provisioning scripts declared in the Vagrantfile but it also allows integrating with a Puppet or Chef infrastructure. Which means that the development virtual machine can be provisioned exactly like the test and production environments.

It also allows for a nice DevOps pipeline by permitting each developer to experiment with an infrastructure change on his own virtual machine. When satisfied she can then share that change through source control. Her fellow developers will benefit from the change by refreshing their sources and executing a simple vagrant provision command. The change can then be merged, again through source control, in the test and production environments. Developers and operation people can experiment in their environment without fear and at a very low cost. Breaking their environment would only mean that they have to revert their changes through source control and execute a vagrant destroy; vagrant up command (with the additional benefit that they get to grab a cup of coffee while this is running).

However, after a few experimentation with Vagrant on Windows, we quickly found out that the developer experience was not satisfactory. The performance was very degraded, editing on Windows while building on Linux proved to be quite challenging. On the other hand, the JEE technology with thousands of Java, XML and ZIP files was posing a greater challenge to virtualized environment than the more common Rails, Node or Python environments.

As we already planned on using Puppet for test and production environment deployment, we settled on deploying each developer’s desktop environment with the same tool. This allowed us to almost completely automate desktop environment setup. It had a few drawbacks, though. Mainly, for those project members that worked on their laptop and had previously installed tooling, the setup process might interfere with those tools or fail altogether because they were set up in an unexpected way. We also had the common issues that were found out only in the test environment because developers tested on their own Windows environment.

Step 2: Deploy on Windows in a Linux shop

The second step was a bit different. This time, we were both developing and deploying on Windows. The project was only a few months old; the deployment process was manual, and configuration management was starting to become an issue. Most of the rest of the company was deploying applications on Linux, and the infrastructure team had already introduced Puppet to manage those hosts. We ourselves used Puppet to deploy our hosts to build on existing experience and to prepare for an eventual migration from Windows to Linux.

All environments were managed by the same system which allowed developers to have local setups almost identical to test and production environments. Deployments and configuration changes were propagated along the pipeline by successively merging from development to test and from test to production. Configuration data was stored in HieraDB a part of Puppet that provides a hierarchical configuration database.

This particular software, we were developing, required complicated configuration management, and we rapidly reaped the benefits of introducing automation. Especially when deployments started multiplying.
However, it revealed much more vividly than in step 1 that Puppet, or any tool that grew up in the Linux world, has an impedance mismatch when deployed on Windows. Basically, Unices are based on files and executables whereas Windows is much more complex. The registry, the right management system, drivers, host processes, services, etc. All those concepts are not hugely different from Linux equivalents. But nonetheless, different enough to make things complicated with tools like Puppet, Chef, Ansible, Salt, etc. Nothing is completely impossible, but you have to work harder to achieve the same result on Windows than in their native OSes.

Especially, when you cannot handle the task with pre-existing resources and need to add some new behavior to the configuration management tool. This can be achieved either by extending them with Ruby code for Puppet and Chef or Python code for Ansible and Salt. But even general purpose languages like Ruby and Python that are ported to Windows show some of that impedance mismatch. Additionally, most of the time, they are not known by existing IT professional. We chose to use Bash through the MSysGit toolbox because both developers and IT professionals were familiar with it. However, that still was not satisfactory. Even if that version of Bash is very well integrated with Windows, it still does not work seamlessly. Very simple tasks like creating a properly configured Windows service required juggling with different concepts and commands.

Note: in the meantime, Microsoft has released a beta version of Bash on Windows which is another version of Bash running on Windows. We did not use it as much as the MSysGit version, but it seems to exhibit the same inherent difficulties.

Step 3: What the heck, let’s learn PowerShell

The latest step of our journey occurred in a full Microsoft environment. Development and deployment happened almost exclusively on Windows. Modern configuration management like Puppet or Chef was not yet introduced. However, several efforts were made to introduce automation, but mostly of the mechanization sort (see below). Repetitive tasks have been accumulated together into scripts, in some cases, those scripts are called through workflow like graphical interfaces, but mostly, the control and knowledge remained with the IT professional.

This time around, people already were familiar with PowerShell, the scripting language introduced by Microsoft in 2006. The approach we took was to expand on that existing body of knowledge with extensive training and systematic exploration of PowerShell solutions to our issues before even considering more advanced but also more alien solutions. We found that PowerShell provided most of the required building blocks for a full deployment and configuration management stack.

PowerShell

PowerShell is a scripting language introduced by Microsoft in 2006. But it was already laid out in the Monad Manifesto by Jeffrey Snover in 2002. As explained in the manifesto, PowerShell takes a new approach to old issues. It is a shell with a pipeline. However, PowerShell passes objects down the pipeline, not text or binary data like its Unix relatives. This saves quite a bit of work when composing simpler commands together.

PowerShell also leverages the .Net framework which makes it as powerful as any general purpose programming language. Access to the .Net framework means that any API available to .Net programmers will also be accessible through PowerShell. But it does not stop there. It also provides jobs, remoting, workflows, package managment and many other features. Among those, two are of particular interest when building an automation solution: Desired State Configuration and Just Enough Administration.

Desired State Configuration

DSC builds on top of PowerShell to implement configuration management building blocks called resources. Those resources, are very similar to Puppet resources and similarly allow IT professionals to declaratively express what the state of the system should be. The actual imperative implementation that changes the system to the desired state is implemented by a PowerShell module.

DSC also provides a declarative domain specific language to express a system’s configuration and an agent that can apply that configuration to a specific host. The agent is an integral part of the Windows Management Framework which means that it will be deployed everywhere PowerShell is.

Transforming traditional imperative scripts into DSC resources allows us to achieve idempotence. Which in turn allows us to handle any configuration change like a simple change in the declared configuration. DSC will then ensure the system ends in the required state from the previous state. Even, a manual change, of the system would be caught by DSC as a configuration drift and could be automatically corrected, depending on the agent’s configuration.

DSC can do much more. However, it is not as mature a solution as Puppet or Chef. It lacks the ecosystem around it: a configuration database, reporting tools, easy but powerful configuration composition and reuse, etc. Therefore, our current approach is to associate both tools. The impedance mismatch mentioned earlier can be solved by letting Puppet or Chef use DSC resources to effect configuration changes on Windows, creating a win/win situation. Benefit from all the power behind the Puppet and Chef ecosystems, while still leveraging PowerShell, which is native to Windows and already known to IT professionals.

Our current preference is to use Chef. Chef is a bit less mature than Puppet, but it seems that Chef and Microsoft actively work together to integrate both solutions.

Just Enough Administration

JEA is a tool that helps reduce administrative rights dissemination. Lots of operations require administrative or at least somehow elevated rights to be performed. That usually means that if you have to perform one of those operations (even if just is a read-only operation), you will get administrative rights. Or some ad hoc solution would be put in place to somehow allow you to do what you needed to. This can lead to pretty complex and fragile solutions.

From my Linux background point of view, JEA is like sudo on steroids. It handles both privilege elevation, RBAC, remoting and integrates nicely with PowerShell scripting. It can easily be deployed via DSC which helps to ensure limited and uniform access rights throughout the whole system.

Perspective

That latest step is still quite new and, for some parts, a work in progress. We have solved all the issues encountered in previous experiences and even a few new ones, which leads us to think we are on the right track. Moreover, it seems the vision we have created aligns nicely with the “new” Microsoft. For instance, the recent open sourcing of .Net and PowerShell, while at the same time porting it to Linux and MacOSX, opens new avenues for automating our few existing Linux systems.

Lessons learned

The following lessons were learned the hard way. They are a bit opinionated. But, all are rooted in real life situations where not following them meant failure…

Start small.

In my experience, trying to automate the whole system at once ends badly. At best, only those parts of the system that were easy end up automated, leaving huge gaps where manual intervention is still needed. At worst, the effort fails completely.

Start small by considering only a single part of the system. However, ensure that that part is entirely automated. Do not leave some manual steps in-between automated parts. The automation should encompass all use cases, even those considered exceptions. If it looks like they are too different to be automated, it usually means that the automation system is too rigid, too specialized to some local or current way of doing things. Not being able to handle today’s exceptions is a good indicator that the system we are creating will probably not be able to handle future either. Also, partial coverage means that we cannot have full confidence in our ability to reconstruct the system. Be it because we are facing a major disaster or, just because we need to experiment with a copy of the actual system.

This makes for slower progress but allows you to get a solid foothold on the automated ground. Expanding from that solid ground will be much easier in the future.

“Mechanization” is not automation…

In my experience, in environments where the concept of automation is new, it is often confused with mechanization. It is what might be called the reduce 10 steps to 1 syndrome.

Wikipedia defines Mechanization as:

Mechanization is the process of changing from working largely or exclusively by hand or with animals to doing that work with machinery.

Too often, automation is confused with mechanization. Allowing developers to submit an SQL schema migration through a form is a form of automation. The developer does not need to open a SQL tool, enter the proper credentials and execute the SQL file by hand. However, it is not automation yet. The process is still almost exclusively under the control of a human being (animal labor is now mostly eliminated from our IT operations, although we still occasionally see some developers talking to ducks). Wikipedia defines Automation as:

Automation is the use of various control systems for operating equipment […] with minimal or reduced human intervention.

To fully automate our SQL database schema migrations, human intervention should be entirely eliminated. Which means that the developer should only specify which version of the database schema is required and automation will take care of bringing the database to the proper state. Tools like Liquibase or Flyway can help a lot with that. To the point that humans do not even need to ask for a database schema version change. The application can, upon starting, check that the database is in the proper state and, if not, apply the relevant migrations.

While introducing automation instead of mechanization is a bit harder it has tremendous advantages down the road. To quote Wikipedia one last time:

The biggest benefit of automation is that it saves labor; however, it is also used to save energy and materials and to improve quality, accuracy, and precision.

Automation completely eliminates human error by eliminating human decision from the process. Which in turn improves quality and repeatability.

Keep away from shiny tools

With the introduction of Infrastructure as Code IT professionals became de facto developers. That means their activity has changed from simply deploying and operating software to actually building the software that deploys that software -even when that software is some piece of infrastructure.

That poses a challenge to any IT professional that did not start his career as a developer. However, in the Linux world, any IT professional has been exposed to a variety of scripting languages which performed a lot of tasks from the most mundane to some quite sophisticated (for instance Gentoo’s build system, ebuild). The Microsoft world, however, has long relied on graphical user interfaces and manual operations. It is thus natural to turn to graphical tools that promise to simplify infrastructure as code by allowing building complex automation through graphical manipulation. I have yet to find a graphical tool that fulfills that promise. During the last years, I found quite a few instances where they made things way worse.

Coding is coding. To this day, most of the coding occurs by writing code. Yes, there are a few specialized tasks that are better handled by graphical tools, but general coding tasks usually involve editing some form of text. So, even if you can leverage graphical tools for some of your automation tasks, in the end, a general purpose scripting language will always be necessary.

The language of choice, on Microsoft Windows, is PowerShell. It is still a Shell with its roots firmly planted in the Unix world but is also very well integrated with the Windows system and Windows applications. All of which makes your life so much easier. If you only learned PowerShell by doing the same stuff you did with .BAT files and sprinkling a bit of Stack Overflow, try to get some formal training. It will be time and money well spent that will pay for itself time and time again.

Involve IT professionals

Automation should be built by the people who are the most intimate with the system being automated. If the automation solution is built by outside people, it often lacks the proper adoption that would permit it to grow. In some extreme cases, the knowledge of what the automation actually does is lost in the system. Developers move on to building other systems, and IT professionals lack the expertise to actually dig into the system when needed.

Of course, in most occurrences, IT professionals are not yet developers and lack the set of skills required to build the automation tools. In which case, bringing in external resources to help mentor them in those new fields will speed things up and prevent fundamental mistakes. However, at the end of the process, IT professionals should be in charge and complete control of their toolchain.

One way to flatten their learning curve while still leaving them in charge is to help them set up a software factory and software tooling very early in the process. If PowerShell module scaffolds can be generated, tests automatically executed, modules packaged and deployed automatically to the repository, etc. they can concentrate on what really matters: the automation system they are building.

The release pipeline model

Earlier this year Microsoft published a white paper about the Release Pipeline Model which neatly sums up everything we mentioned here (and more). I strongly encourage anyone attempting an automated deployment and configuration management effort in the Microsoft world to read it. Most of what you would need to start, but is not mentioned in this post, can be found in it.

Looking forward

It is probably too soon to gain enough perspective on how automated configuration management will evolve in the Microsoft world. On the other hand, all pieces seem to fall neatly in place and work well together.

December 4, 2015

Day 4 - End to End Deployment with Microsoft Azure

Written by: @samcogan
Edited by: @phrawzty

If you're a sysadmin who needs to deploy resources in Microsoft's Azure platform your choices have been limited to either the web portal or complex scripts. Today I want to highlight a set of new technologies that when combined together provide a way to move away from manual processes and complex scripts and instead produce a declarative, reusable, and easy to manage and maintain solution for deployment to Azure. Using these tools we will be able to stop focussing on defining "how" we deploy, and instead start defining recipes for “what” we want to deploy and let the technology take care of “how”. By the time you’ve finished this article you’ll see the power of these technologies and the agility they can bring to your deployment process.

Before we dive in, let’s take a step back and understand what the problem is we are trying to solve. Deploying resources to any cloud provider usually involves more than a few moving parts such as storage, virtual machines, websites, and databases -all with dependencies on each other. This gets even more complex when talking about test or development environments where there is a need to regularly create and destroy environments.

In this sort of world what is needed is a way to easily define an environment, automate the deployment and tear down of that environment, and then do it all again with the same results. Additionally you also want to apply software development practices such as testing, version control, patterns and practices to your deployment process - collectively, this is often referred to as "Infrastructure as Code" (IaC).

Up until recently this has been difficult (if not impossible) to do with Microsoft’s Azure platform. Sure you could create PowerShell scripts to deploy resources, but this all happened in a serial fashion with each resource having no knowledge or dependencies on other resources. This was more like "Infrastructure as scripts that failed as often as they worked". This lagged behind platforms such as AWS where solutions like Cloudformation offer a relatively straightforward way to represent your infrastructure as JSON.

This has all changed in the last year with the release of new tools and enhancement of existing ones to allow an Infrastructure as code approach to Azure deployments.

Azure Resource Manager

Azure Resource Manager (ARM) is the first new feature that enables moving to a code based deployment. ARM introduces a number of features, but the ones key to an IaC approach are:

  • Creation of resources inside a resource group so they can be managed collectively.

  • Declarative templates to define deployments.

  • Idempotent deployments that can be re-applied to ensure a consistent state.

  • Deployment of non-dependant resources in parallel to improve deployment times.

With these four components it is now possible to create recipes for your deployments using JSON templates. These templates define both the resources themselves and the relationships between them.

Once your templates are finished you can then deploy these to a resource group. If this is the first time you have deployed to this resource group it will create your resources; however, if you're running against an existing deployment it will validate the state of the deployment and amend or re-deploy resources as required.

Finally, if you want to delete your deployment, all you need to do is delete the resource group and that will delete and cleanup all the resources contained within. If you want to re-deploy, just run the deployment again.

Because your deployment is now in a declarative template you can store this in your version control tool, add it to your testing process, and use them as part of your build process to create test environments. You can also use Visual Studio to create your templates (ensure you have the latest Azure SDK and PowerShell tools for Visual Studio installed).

Templates are not limited solely to deploying top level resources! For example, a template that deploys an Azure Website can include a resource that downloads an MS Deploy package and deploys it to the website. Similarly, with a virtual machine you can use ARM to install various extension to provide things like anti virus protection, monitoring, or further configuration of the VM which we will discuss in the next section. Follow the link for the Azure Quick Start Templates page in the resources section to see examples of what can be achieved with Azure Resource Manager.

Below is an example of a ARM resource that deploys a website and downloads and applies an MS Deploy package for the content.

"resources": [
    {
      "apiVersion": "2014-06-01",
      "type": "Microsoft.Web/serverfarms",
      "name": "[parameters('hostingPlanName')]",
      "location": "[resourceGroup().location]",
      "properties": {
          "name": "[parameters('hostingPlanName')]",
          "sku": "[parameters('hostingPlanSku')]",
          "workerSize": "0",
          "numberOfWorkers": 1
      }
    },
    {
      "apiVersion": "2014-06-01",
      "type": "Microsoft.Web/sites",
      "name": "[parameters('siteName')]",
      "location": "[resourceGroup().location]",
      "tags": {
          "environment": "test",
      },
      "dependsOn": [
          "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
      ],
      "properties": {
          "name": "[parameters('siteName')]",
          "serverFarm": "[parameters('hostingPlanName')]"
      },
      "resources": [
          {
              "apiVersion": "2014-06-01",
              "type": "Extensions",
              "name": "MSDeploy",
              "properties": {
                "packageUri": "https://storageaccount.blob.core.windows.net/packages/website.zip",
                "dbType": "None",
                "connectionString": "",
                "setParameters": {
                  "Application Path": "[parameters('siteName')]"
                }
              }
          }
      ]
    }
]

It’s worth noting that ARM only works with V2 Azure resources, meaning V2 VMs and Storage, SQL V12, and so on. Some resources are not yet deployable using ARM such as Azure AD, Azure Service Bus, and Azure Remote App.

Powershell Desired State Configuration

Azure resource manager lets you deploy Azure resources and if you're solely deploying websites or SQL databases that may be enough. However, if you're deploying VMs, be aware that ARM won’t directly configure the VM operating system or install software; for this, you’ll need to use Azure Extensions. There are three Extensions that can be used to configure a VM and install software: Chef, Puppet, and PowerShell Desired State Configuration (DSC). We will focus on DSC for this article, but if you have existing Chef or Puppet deployments you can easily use these standalone or alongside DSC.

Where ARM allowed you to define Azure resources using JSON, DSC defines the configuration of your Windows VM resources using PowerShell. DSC provides hundreds of resources to configure Windows VMs as well as providing a way to write your own custom resources, or use custom scripts in your resources to do exactly what you want. Using the DSC extension then allows you to define the DSC file to be applied to any VM built using your ARM template.

Once you have defined your DSC files, Windows compiles these down to industry standard MOF files, and it's the MOF files that get applied to the VM. This means that you can easily integrate DSC with tools like Puppet and Chef if required and get the benefit of Windows specific resources.

Finally, the DSC engine will continuously apply the DSC configuration you have provided to prevent configuration drift and also apply any changes you make to the template over time. In this way your VM should remain in line with your configuration definition at all times. Windows will automatically test the machine against the configuration file at regular intervals and bring the machine back in-line if required. You can also manually trigger a test with the "Test-DSCConfiguration" command.

Below is an example PowerShell DSC configuration that will install IIS onto a VM, add the .net 4.5 role and then create a website.

configuration IISInstall
{ 
    Import-DscResource -Module xWebAdministration             

    # Install the IIS role 
    WindowsFeature IIS  
    {  
        Ensure          = "Present"  
        Name            = "Web-Server"  
    }  

    # Install the ASP .NET 4.5 role 
    WindowsFeature AspNet45  
    {  
        Ensure          = "Present"  
        Name            = "Web-Asp-Net45"  
    }  

    # Stop the default website 
    xWebsite DefaultSite  
    {  
        Ensure          = "Present"  
        Name            = "Default Web Site"  
        State           = "Stopped"  
        PhysicalPath    = "C:\inetpub\wwwroot"  
        DependsOn       = "[WindowsFeature]IIS"  
    }  

    # Copy the website content 
    File WebContent  
    {  
        Ensure          = "Present"  
        SourcePath      = "C:\Program Files\WindowsPowerShell\Modules\Website" 
        DestinationPath = "C:\inetpub\Website" 
        Recurse         = $true  
        Type            = "Directory"  
        DependsOn       = "[WindowsFeature]AspNet45"  
    }  

    # Create a new website 
    xWebsite WebSite  
    {  
        Ensure          = "Present"  
        Name            = "Website" 
        State           = "Started"  
        PhysicalPath    = "C:\inetpub\Website"  
        DependsOn       = "[File]WebContent"  
    }  
}

Azure Automation

The combination of ARM and DSC is enough to go from zero to a fully configured and ready to use deployment; however triggering and maintaining the deployments is either a manual process, or will require an external orchestration tool. An alternative to this approach is to make use of Azure Automation.

By storing your ARM scripts in Azure Automation you can trigger deployments manually, on a schedule, or allow an external application or process to trigger them using webhooks. Azure Automation could allow you to build a self service way for your users to deploy and tear down their own environments.

Where Azure Automation really comes into its own is the recent update to use DSC and in particular to provide a DSC pull server. A pull server provides an alternative way to get your DSC files to the hosts. Instead of using the ARM script to apply the DSC extension and a particular DSC file to a host, the host registers with the DSC pull server and pulls its configuration from here. By using Azure Automation to act as a pull server you can maintain a centralised repository of DSC scripts which you can easily update and have all of your host pull the changes, rather than updating the scripts on each host. You can also easily see the status of each of your nodes and whether they are in compliance with your desired configuration.

Tips and Tricks

ARM and DSC are not without their issues and idiosyncrasies. Below are some tips when working with these technologies:

  • Ensure you keep the version of the DSC Extension you are deploying in your ARM scripts up to date as new versions are released all the time, and older versions of the extension are occasionally disabled automatically. Consider using the "autoUpgradeMinorVersion" flag.
"properties": { 
    "publisher": "Microsoft.Powershell", 
    "type": "DSC", 
    "typeHandlerVersion": "2.8", 
    "autoUpgradeMinorVersion": "true" 
        … 
}
  • If you are installing multiple VM extensions using ARM, configure your dependencies so that the extensions install one by one. Installing multiple extensions at the same time can cause errors in the deployment to occur.

  • ARM scripts can become large and difficult to navigate. Use Visual Studio and the built in JSON explorer to make navigation between objects and viewing hierarchy easier (requires the Azure SDK).

  • Keep your scripts and configurations in version control. This will let you keep a full history and audit trail of the changes made to configurations over time.

Bringing It All Together

We’ve discussed three different technologies in this article: ARM, DSC, and Azure Automation. Hopefully it’s clear now that each of these present part of the solution to an end to end deployment. Used together these solutions allow you build an automated solution to deploying and configuring resources in Azure and keeping these resources in line with your desired configuration throughout their lifetimes.

There is no one way that these tools can be used - they can be combined together to meet your needs. For example, if you're deploying a website with an SQL backend you’ll likely use ARM but never touch DSC. If you're already using tools like Chef and Puppet you may not use ARM, but you might choose to use DSC to give you the benefit of the Windows specific tools that still compile down to MOF files. If you're a System Centre user you may not need the automation and orchestration that Azure Automation provides, but still want to use the deployment tools available in ARM and DSC.

Hopefully this article has given you an insight into how these exciting new features in the Azure platform could help your deployment process become more agile and error free. Using these tools you can focus on "what" you want to deploy, and let PowerShell and Windows take care of “how”. Once we do that we can start reaping of benefits of more reusable, testable, economical and automated deployment processes.

If you're interested in finding out more about these technologies take a look at some of the links in the resources section, or drop me a line on email or Twitter.

Useful Resources

Azure Resource Manger Quick Start Templates - https://azure.microsoft.com/en-gb/documentation/templates/

PowerShell DSC Overview - https://msdn.microsoft.com/en-us/PowerShell/DSC/overview

PowerShell DSC Resources Gallery - https://www.powershellgallery.com/

Azure DS Extension - http://blogs.msdn.com/b/powershell/archive/2014/08/07/introducing-the-azure-powershell-dsc-desired-state-configuration-extension.aspx

Azure Automation and Powershell DSC - https://azure.microsoft.com/en-gb/documentation/articles/automation-dsc-overview/

Pester - PowerhShell Testing Framework - https://github.com/pester/Pester

December 7, 2013

Day 7 - Managing Windows with PowerShell

Written By: Steven Murawski (@stevenmurawski)
Edited By: Adam Compton (@comptona)

Thanks for stopping in today. I've got the honor of sharing a bit about a management technology I use to wrangle my Windows Server environment into compliance. Windows Server has long appeared unfriendly to command line and scripted management. This is no longer the case (and hasn't been for a few years now). PowerShell is a game-changer for Windows management and management at scale and is a true force multiplier.

The History

PowerShell quietly stole onto the scene back in 2006. PowerShell offered the Windows administrator and power user a better shell experience (and it was not hard to beat cmd.exe). PowerShell touted direct access to all the richness of the .NET Framework, simplified access and discoverability for WMI (Windows Management Instrumentation), and wrappers for working with COM objects (to make access to traditional Windows APIs more accessible). VMWare quickly recognized the effectiveness of the PowerShell platform and was one of the first third parties to embrace and offer PowerShell cmdlets outside of the Windows OS.

PowerShell Version 2 was released in 2009. V2 introduced a number of great enhancements, the biggest of which was PowerShell Remoting. Over time PowerShell's ecosystem grew. Exchange Server was the first Microsoft server product to fully buy in to PowerShell's philosophy of building management functionality and layering a GUI on top of that. Exchange Server went a step further and used the GUI to teach the command line (in a sad turn, the most recent version of Exchange stepped back and no longer teaches the PowerShell commands used). More OS roles and features began to support PowerShell, as did more Microsoft server focused products. Third parties continued to embrace PowerShell as well, especially in the storage and virtualization space.

PowerShell Version 3 came to fruition in 2012. PowerShell V3 brought enhancements to remoting, durable workflows, and most importantly an easy way for wrapping WMI or CIM (Common Information Model - the standard that WMI is based on) APIs with a XML mapping file to generate PowerShell cmdlets. This advance allowed PowerShell cmdlet (the basic unit of operation in PowerShell) coverage to explode. With PowerShell V3 (and Server 2012), Windows Server and its various roles and features became much more automation friendly.

PowerShell Version 4 has followed closely afterwards. Microsoft appears to be accelerating their release cycle and so V4 surfaced only a year after V3. Version 4 brings Desired State Configuration, a configuration management agent (and a DSL for creating configuration descriptions) to Windows Server 2012 R2 (and downlevel to Server 2012 and Server 2008 R2).

The Shell

PowerShell is an object-based shell. This means that the output of native PowerShell commands (cmdlets) are objects. Why is this important you may ask? Well, the Windows management paradigm is better represented in objects. But, the functional purpose for admins is that we get pre-parsed output. This also lets PowerShell supply some standard mechanisms for grouping, sorting, output formatting, and a variety of other common tasks. The PowerShell runtime provides standards for parameter parsing, argument transformation and validation, pipeline input, and support for the Verbose, Debug, Warning, Error, and Output streams. The runtime also provides to all cmdlets and advanced functions (PowerShell scripts that offer similar functionality to cmdlets) common parameters to enable switches to turn on Verbose and Debug output, change error handling behavior, and collect output. In addition, the runtime makes it trivial to offer WhatIf and Confirm behavior for commands with potential destructive or irreversable change.

Remote Server Management

One of the big wins in leveraging PowerShell for your Windows Server management options is the remoting infrastructure. PowerShell supports several scenarios for remote execution - one to one, fan in, and fan out.

One to one remoting offers two scenarios: one that you'd expect, and one that's a little different. The expected scenario is where you can use Enter-PSSession to connect directly to a management session on a remote machine. This is loosely the equivalent to "ssh'ing" to a remote box. The second scenario supported in one to one style remoting is implicit remoting. In this case, you've established a connection to a remote machine and instead of working directly at the remote console you can tell PowerShell to create proxies for the commands on the remote machine and add those to your current PowerShell session (or export them to disk for more permanent use). The proxies created handle connecting to the remote server if a connection is not already present. Your input to the proxies is marshalled across the remoting connection and the commands are executed on the remote server. This type of remoting can be very powerful, but it is one of the least used and least tested (for support by third party or Windows server role and feature commands).

The second variant for remoting is fan in. In this method, you configure an endpoint to offer up commands to users based on roles (or any criteria you want to evaluate). This scenario supports hosted services or where you need to delegate different capabilities to different parties. This scenario is leveraged by administrators connecting in a one to one or fan out scenario.

The third remoting scenario is fan out. This is one of the most powerful variants on how remoting can be leveraged. Invoke-Command offers the ability to reach out to one or more computers and execute a script or arbitrary block of code and return the results to the calling computer. There are options to throttle execution across x number of hosts, to have all the results return in the background (as a background job), and to marshal input to the script or arbitrary code executing remotely. This lets you, from one command, execute the same instructions across tens, hundreds, or thousands of machines at the same time, and have the results streamed back to you for review at your convenience.

Remoting does offer one major hurdle (and several minor ones). A remoting session is much lower overhead than an interactive remote desktop session, because the connection is actually hosted in the Windows Remote Management (WinRM) service. Since the connection is being made to a service, commands are executed in the context of that service (with your credentials). However, by default services are constrained from passing your credentials outside of their own processes (so the service cannot just impersonate you at the service author's whim). This can cause a number of commands to fail due to permissions issues (WinRM runs as Network Service). This means many commands for things like Failover Clustering will require additional rights. There are two ways to work around this, either with Kerberos delegation or by enabling CredSSP; both options have security considerations that should be evaluated before you enable them.

Other Tasty Tidbits

In addition to remoting, PowerShell offers several capabilities to make your management scenarios easier. Version 2 introduced background jobs, where long running tasks can be done in another session and the results retrieved later. PowerShell (since V2) ships with a built-in script editor, the PowerShell ISE, which while not great is "good enough" to get work done and enhance your scripting experience (there are also some nice third party editors, including PowerGUI, PowerShellPlus, and PowerShell Studio.

Each version of PowerShell offers a significantly better experience, so I would encourage you to run the highest version your environment will support. Going from V1 to V2 enables background jobs, remoting, and some other great scenarios. Going from V2 to V3 will offer a tremendous boost in performance. Adding V4 will give you access to Desired State Configuration (my personal favorite).

Regardless of the version of PowerShell you are on, there are a number of features which can help you use PowerShell to learn PowerShell. There is a built in help system (Get-Help or aliased to man). PowerShell includes the ability to set breakpoints in scripts for debugging purposes or step through scripts as they execute. If you really want to go low level, PowerShell offers a window into the engine operations through Trace-Command where you can view tracing messages as commands execute and route that to the console or debugger of your choice.

Come Explore

I hope I've whetted your appetite for PowerShell as a management surface for the Windows Server environment. If you want to learn more, hop on over to Powershell.org for forums, blogs, free e-books, and a welcoming community ready to help. If IRC is your thing, #powershell on Freenode remains a great resource for interactive help and learning. Finally, the bedrock of the PowerShell Community remains the PowerScripting Podcast, which has been shining lights into all areas of PowerShell use since PowerShell was released. Now, I'm going to go back to reading some of the other great SysAdvent articles!

December 4, 2010

Day 4 - Make sense of Perfmon with PAL

This article was written by Sam Cogan (@samcogan)

You've got a performance problem: your Windows server or application isn't performing as well as it should. You need to find out why. When Task Manager isn't enough it's quite likely you'll reach for Perfmon.

If you don't know already, Perfmon is the Windows performance monitor. It can be found under administrative tools on all versions of Windows from Windows 2000 onwards. It provides a way to monitor counters - metrics of your system performance, such as %CPU use, Free Memory etc. Many Windows applications come with their own custom set of counters for their specific application. We can use perfmon to setup sets of counters (Data Collector Sets) to collect data and to allow easy re-use. Once we have created a collector set we can start logging. We can leave it running however long we like, then come back and review the data. Perfmon also provides some step by step wizards to help the beginner start using it quickly.

For more information on using Perfmon, see this article

Perfmon is an excellent tool for collecting data. The problem comes when trying to analyse this data. Often, when we're not sure what the problem is, we'll add a wide range of counters to make sure we've covered all areas. Very quickly we've collected a large amount of data about the performance of the problem machine or machines.

Chances are that if you open up these files in Perfmon, then you'll end up with a selection of lines on a graph, information that seems like it should be useful, but is often hard to decipher what it actually means and if you have a lot of counters you can end up with a mess of colour lines that make a nice picture, but has no meaning whatsoever!

Perfmon Screenshot

What do we do? How do we get some useful information that will help us solve this tricky performance problem?

Yes, you could go through and filter out the lines you don't need. What you really need is a way to give meaning to these lines - to see what is normal or abnormal, or to simplify the data or change its presentation into something more digestable. This is where PAL comes in.

PAL

Perfromance Analyis of Logs or PAL is a tool written by Clint Huffman at Microsoft, to assist in analysing Perfmon logs and to produce an HTML report that will provide detailed graphs, and indications of where a problem may lie. It provides a simple GUI to a complex Powershell script that actually does most of the work.

To understand how to use PAL, we need to look at it's 4 main components

  1. The Log file
  2. The Threshold File
  3. Questions
  4. The End Result

So, let's download PAL, fire up the GUI, and get to work!

Log Files

The Perfmon log file is where all PAL looks for data. A key advantage to using PAL is that you do not need to consider log size when you look at collecting your data. You can include all the counters you might need, and then instruct PAL to only analyse the ones you want and only during a specific time period. The only caveat to this is that PAL will not work as well if you have multiple computers feeding a single log file, as it will assume that the configuration of the machine is the same for each counter.

So, tell PAL where you log file is, and specify a time range for the data you want to analyse if you don't want to look at the whole file (if you have multiple files, we can add them later).

Threshold file

The threshold file is what makes PAL a useful tool. In essence, it's just a simple XML file used to define what kind of analysis you want PAL to do on your log files.

The first thing this file does is to define what counters you want to analyse, meaning you can skip any counters that you're not interested in or don't apply to your current problem.

Next, and the reason it is called a threshold file, it lets you set thresholds on each of your counters. This allows us to add some meaning to the data we have collected. We can define what value for each counter defines a warning state and what defines a critical state and so bring potential problems to our attention.

Finally, the threshold file allows you to specify questions to ask. We will come on to these shortly.

This may sound like a lot of work, but it doesn't have to be. PAL has a number of threshold files included that cover many of the common server configurations, e.g. Exchange, OCS, SQL, and a catch all, systems overview file. Using these built in threshold files, or by downloading additional ones from the Internet you can make extensive use of PAL without ever needing to write any code.

If these threshold files do not meet your needs, or you need one that is tailored to your needs, then PAL includes a GUI that assists you in doing just that. Selection of counters is done via the user interface. However, the calculations used to determine threshold values are written in Powershell, so some ability to write Powershell code is required.

PAL Screenshot

If you haven't yet collected your Perfmon data, you can also use PAL to generate a Perfmon template from a threshold file, so that you only collect the data that this threshold file will generate.

Questions

The questions section asks you for some extra information about the machine this Perfmon log is for, for example number of CPU's, amount of memory etc. These questions are important, because the values you give can be accessed in the Powershell code inside the threshold files. These values can be used to assist in calculating your threshold levels.

Questions are configured inside the threshold file, and can be edited and added through the PAL GUI when creating a threshold file. When you add a question you create a Powershell variable that is available for use later inside threshold calculations.

Running the Analysis

Once you have selected your log, your threshold file, and answered some questions, you are ready to go. At this point, you add your job to the queue. You can then choose to either run this queue now or queue up more jobs to run in a batch. PAL analysis jobs can take a number of hours to run, depending on how much data is contained in your logs, so it is often convenient to queue up jobs to run overnight.

Ok! So, you've run your analysis and PAL has spat out some HTML files, how are these useful?

First off, for those in a rush or who want a quick overview of what problems there may be, there is the alerts section. This looks at the threshold values we had in our threshold file, and gives a visual indication of what areas of this log are in a warning, or critical state. It's very easy to quickly see where the machine is struggling, and where you may want to focus your efforts on fixing the problem.

html output

Once you've been through all your alerts, we then have detailed information on all your selected counters. Each counter is presented separately, with a graph, alert details and statistics. Threshold data is also presented on each graph, allowing us to quickly see at what point there was an issue and how severe it was.

graph example

As you can see from this graph, this job is making the CPU a little unhappy at times and might be something that needs to be looked at!

Summary

Perfmon is a great tool for collecting performance data, but it sucks when it comes to actually analysing this data and getting some meaning from it. What looks like a big spike in the Perfmon viewer could actually be normal operation for that counter - we're missing some helpful context. We can use PAL to give us information that is not only easier to read but also has some meaning to it. From this, we can determine which data is normal and can safely be ignored, and which data is anomalous and is something that we need to investigate.

PAL is by no means perfect; getting useful reports out of this tool relies on having a threshold file that covers the counters you need to analyse with meaningful threshold calculations. If one of the included files, or one found on the internet covers this then that's great, but if not you are stuck needing to write your own using Powershell, which can be quite a complex task if you have lots of counters you want to analyse.

Users who need to analyse perfmon data alot will invest the time in customising their threshold files to get out exactly what they need, however more casual users are going to rely heavily on the pre-constructed files.

That said, more and more product areas are seeing the value in PAL and providing threshold files for their products, Exchange and OCS are two examples of this. There's no magic pixie dust in these threshold files. If you can understand Powershell, then you can write your own to handle any Counter that Perfmon can use, including third party ones. So it's a great option for people who need to analyse uncommon data. It's also open source, so if you want to see how the Powershell code behind the analysis, you can.

It's also not a quick process; log analysis can take hours. If you're looking for an immediate answer to your problem then you are going to have to use other methods of getting your answers.

If, however, you've got the right threshold file, and the time to run the analysis, then this can prove an invaluable tool to help you get meaning, and ultimately solve your problems, from Perfmon data.

Further reading:

December 2, 2008

Day 2 - Windows Powershell

Maybe you're a windows sysadmin. Maybe you're not. Either way, you might find the features in Powershell pretty cool.

Powershell is Windows-only and free to use. Some syntactic differences asside, it looks and feels like a unix shell language. It has standard features you might expect such as functions, recursion, variables, variable scope, objects, and a handful of built-in functionality to help you get work done, but it does many things better.

In addition to these baseline expectations, functions in powershell trivially take flag arguments by simply declaring a function argument (function foo($bar) { ... } can be invoked as foo -bar "somevalue". You can create arbitrary objects with properties and methods defined on the fly. Exception handling, logging, trace debugging, and other goodies are packed in by default.

It supports pipes like your favorite unix shell, except instead of piping text, you pipe objects. The key word is object. When you run 'dir' (or ls, which is an alias), it outputs file objects. When you run 'ps' (which is an alias of get-process), you get process objects. When you run 'get-content' a file, you get an array of strings.

Why is this significant? As a unix sysadmin, you quickly become intimate with piping one command to another, smoothly sandwiching filter invocations between others tools. Filter tools like awk, sed, grep, xargs, etc, all helping you convert one output text into another input text for another command. What if you didn't have to do that, or had to do it less? No more parsing the output of ls(1), stat(1), or du(1) to ask for file attributes when powershell's file object has them. What about getting process attributes?

# Yes, this is a comment in Powershell
# Show the top 3 consumers of virtual memory:
PS > get-process | sort {$_.VirtualMemorySize} | select -last 3

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    745      58    66648       4316   632    21.03   3564 CCC
   1058     107   230788      28384   680   600.23   5048 Steam
    446      78  1328988    1267960  1616 6,223.72   3692 firefox

# Kill firefox
PS > get-process firefox | stop-process
# Alternately
PS > get-process firefox | foreach { $_.kill() }
'select' is an alias for 'select-object' which lets you (among other things) trim an object to only selected properties. Inspection is done with 'get-member' (or 'gm' for short) and you can inspect objects output by 'ls' by doing: ls | gm, or processes with get-process | gm. You can ask an object what type it is with obj.gettype(); such as (get-item .).gettype()

But what if you want to manipulate the registry easily? The registry, filesystem, aliases, variables, environment, functions, and more are all considered "providers" in Powershell. Each provider gives you access to a certain data store using standard built-in commands. A provider can be invoked by prefixing a path with the provider name. For example, to access a registry key, you could use dir Registry::HKEY_CURRENT_USER to list keys in that part of the registry.

In addition to other neat features, you've got nice access to both COM and .NET. Want to create a tempfile?

PS > $tmp = [System.IO.Path]::GetTempFileName()
PS > ls $tmp
    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Users\Jordan\AppData\Local\Temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         12/2/2008   1:25 AM          0 tmp55FC.tmp

PS > rm $tmp

Help is also conveniently available from the powershell prompt. Help, which can be accessed with a muscle-memory-friendly 'man,' comes in different details levels. Try help select-object and then help select-object -detailed. There's also other useful builtins like foreach-object (like 'for' in bourne), select-object (like cut, tail, head, and uniq, but cooler) , sort-object (like sort, but cooler), where-object (like grep, but cooler), measure-object (like wc, but cooler), and format-list and format-table for sanely printing object properties.

Are you still scripting in DOS batch or VBScript? Do you use Cygwin as a means of escaping to a scripting language on windows that is less frustrating or awkward? Are you suddenly facing windows administration when your background is unix? Check out Powershell.

Further reading:

Download Powershell
Powershell homepage
Hey, Scripting Guy!
A pretty good resources for practical powershell examples