DevOps with Windows Server 2016
上QQ阅读APP看书,第一时间看更新

PowerShell

PowerShell is an object-based, command-line shell and scripting language used for administration, configuration, and management of infrastructure and environments. It is built on top of .NET framework and provides automation capabilities. PowerShell was released in 2006 as version on Windows. PowerShell version 5 is the current version that is available in Windows Server 2016 and Windows 10 out-of-the-box. PowerShell 5 is also available as part of the WMF 5.0.

PowerShell has truly become a first class citizen among IT administrators and automation developers for managing and controlling the Windows environment. Today, almost every Windows environment and its components can be managed by PowerShell. Similarly, almost every aspect of Azure subscription can also be managed by PowerShell.

PowerShell can be pided into two components:

  • PowerShell engine: This is the core engine responsible for executing the PowerShell commands executed through the command line, pipelines, scripts, and functions. The engine provides the execution environment and context in terms of security, concurrency, threading, base .NET framework, extended type system, modules, logging, and auditing. The PowerShell engine exposes runspace interfaces that are used by PowerShell hosts for interacting with it.
  • PowerShell host: These are user-facing applications or command line interfaces responsible for interacting with the user, accepting inputs from them and passing them to the PowerShell engine for execution using the runspace interface provide by the engine. The return values from the engine are displayed to the user using the same host. Each PowerShell host has its own configuration that is accessible through a host provided system variable; $Host. There are two hosts provided out-of-the-box in Windows. They are:
    • PowerShell.exe
    • PowerShell Integrated Scripting Environment (ISE)

PowerShell ISE provided added functionality for authoring PowerShell scripts apart from being a command line interface.

PowerShell features

PowerShell provides lots of features and capabilities and demands a complete book by itself. In this book, we will look into some of the important aspects of PowerShell relevant to us for DevOps.

Cmdlets

PowerShell provides small executable commands called cmdlets which execute a single task or operation. There are hundreds and thousands of cmdlets available in PowerShell. My own machine running Windows 8.1 has more than 3000 cmdlets available. There is a cmdlet available for almost every administration and management activity in PowerShell. Cmdlet names follow verb-noun naming conventions. For example, the Get-Process cmdlet is responsible for retrieving all running processes in a system. Get refers to the verb or action being performed and Process refers to the subject or noun under consideration. PowerShell accepts object-oriented objects as arguments for their parameters and returns back well-defined objects as the return value.

Pipeline

PowerShell is an object-based language which helps in implementing the concepts of pipelines. Pipelines refer to a series of cmdlets defined in a single statement, executed one after another where the output of the previous cmdlet becomes the input of the next cmdlet. Pipelines are defined using the pipe character |.

An example of a pipeline is shown here:

Get-Process -Name Notepad | Stop-Process

The code shows two cmdlets Get-Process and Stop-Process in a pipeline. Execution of the statement executed the first cmdlet first. Get-Process outputs objects of type, System.Diagnostics.Process. If Notepad is running on the system, it will return an object containing details about its process. The same process object is sent to Stop-Process cmdlets as input arguments which stops the Notepad process from running.

Variables

PowerShell provides support for variables which are temporary storage locations in memory to store values that can be used and changed subsequently. They help in making script granular, flexible, and maintainable. PowerShell does not mandate to specify data types while defining variables. In such cases, PowerShell implicitly decides the data type based on values assigned to the variable. When a variable is defined with a data types qualifier, it can accept only those values that adhere to the rules of its data type. The native PowerShell variable data types are string, char, byte, int, long, bool, decimal, single, double, array, and hashtable. Variables in PowerShell are defined using the dollar symbol $.

Examples of variables are:

  • The following code assigns a string value to the OSName variable:
        $OSName = "Windows Server 2016"
Note

Note the $ sign prefixed to OSName.

  • The following code assigns the same string value to the OSName variable however this time, the data type is provided explicitly:
      [string] $OSName = "Windows Server 2016" 
Note

Variables can be referred to by their names prefixed with the dollar $ symbol.

$OSName would print the value stored in OSName variable.

Scripts and modules

PowerShell is also a scripting language. We can use cmdlets, functions, pipelines, and variables within scripts as well. Scripts are reusable code that can be executed multiple times. They encapsulate code, function, data, and logic in a script file with the ps1 extension. The scripts can be loaded and executed in the current execution environment using a technique called Dot-sourcing. Dot-sourcing refers to PowerShell syntax to load a file using dot notation as shown here. Please note the . preceding the script path:

. ./SampleScript.ps1 

PowerShell modules are the means to share scripts, functions, and cmdlets with others. Modules are packaged in a specific format that can be readily deployed on any Windows system. There are well defined locations in the Windows operating system that house modules. System modules are available at: C:\Windows\System32\WindowsPowershell\v1.0\Modules while modules from third-party sources are available at C:\Program Files\WindowsPowershell\Modules . The C:\ drive refers to the system drive here which might be different for you.

The Get-Module cmdlet provides information about all currently loaded modules while Get-Module -ListAvailable provides information about all modules that are available on the system but not loaded in the workspace.

Azure PowerShell development environment

PowerShell will be used heavily in this book throughout all chapters. Since all our environments would be hosted on Azure, the Azure PowerShell module will be a core module for managing Azure through PowerShell. One of the ways to deploy ARM templates is through PowerShell. Before we can use PowerShell to deploy templates in resource groups, we need to install the Azure ARM PowerShell modules. These modules provide the cmdlets, functions, and code to connect and authenticate to Azure, create resource groups, and deploy templates in them. They also provide functionality to peek into the Azure resource group logs to check the status of deployment and also troubleshoot issues. The Azure PowerShell module is available through Web Platform Installer as well as through PowerShell gallery. Windows Server 2016 and Windows 10 provides package management and PowerShellGet modules for quick and easy downloading and installation of PowerShell modules from PowerShell gallery. The cmdlets from these modules are already configured with Powershell gallery source and repository information. The PowerShellGet module provides the Install-Module cmdlet for downloading and installing modules on system. Installation of modules is a simple activity. Simply, copy the module files at well-defined module locations.

Before moving ahead in this section, there should be a PowerShell host, either PowerShell or PowerShell ISE opened as an administrator. Downloading and installing modules requires administrative privileges.

AzureRM modules enable working with Azure ARM from a client machine using PowerShell. Let's download and install the AzureRM module using the Install-Module cmdlet. Before using any cmdlet, we should explicitly import the module into the current workspace as a good practice, although PowerShell will auto load the module if it's not already loaded. This is shown here:

Import-module PowershellGet Install-Module -Name AzureRM -Verbose

The Install-Module cmdlet is dependent on the NuGet provider to interact with NuGet-based repository. The first time a package management cmdlet is used, it will ask to download the same. Click on Yes to any prompts related to downloading NuGet provider. This is shown in Figure 10:

Figure 10: Permission to install NuGet package provider

There will be another prompt stating that the module is downloaded from an Untrusted repository. PSGallery repository is not trusted by default. Click Yes to download the provider. This is shown in Figure 11:

Figure 11: Permission to download from untrusted repository

These prompts can be disabled by using the Force switch as shown here:

Install-Module -Name AzureRM -Verbose -Force

The AzureRM module is a container module that references inpidual sub-modules each representing a resource provider namespace. AzureRM functionality is pided into multiple modules, each AzureRM sub-module representing an ARM resource provider and they contain provider-specific cmdlets and functionality. AzureRM modules can be used to install all sub-modules in one go and it can also be used to install inpidual sub-modules. In the preceding code, AzureRM module is downloaded and installed on the machine it is executed on. This will download all modules related to AzureRM. Similarly, to install only a inpidual or set of modules, the following code can be used. To install inpidual modules, the explicit names should be provided to this cmdlet. The first line installs a single AzureRM.Compute module and the second one installs two sub-modules: AzureRM.Storage and AzureRM.Network:

Install-Module -Name AzureRM.Compute -Verbose 
Install-Module -Name AzureRM.Storage, AzureRM.Network -Verbose 

Before we can do anything with resource groups and templates, we should authenticate with Azure. This is done through the Login-AzureRMAccount cmdlet as shown here:

Login-AzureRmAccount

It is to be noted that cookies must be allowed on the computer from where the authentication is initiated.

This cmdlet can be configured to use the username and password defined in code or it will open a login window. This is shown in Figure 12. Please enter a valid username and password to authenticate and login to Azure:

Figure 12: Azure login window using PowerShell

As seen before, templates are deployed within a Resource group. We should be able to create a resource group using PowerShell and then deploy a template within it after successful login to Azure. The code to create a resource group is shown here:

Import-module AzureRM.Resources
New-AzureRmResourceGroup -Name "myResourceGroup" -Location "West Europe" -Verbose

Here, the Name refers to the name of a newly-created resource group and Location refers to a valid Azure region for the resource group to be created. Verbose provides additional information while executing the cmdlet.

After the resource group is created, templates can be deployed into it.

To deploy a template, cmdlet New-AzueRmResourceGroupDeployment can be used and this is shown here:

New-AzureRmResourceGroupDeployment -Name "FirstDeployment" -ResourceGroup "myResourceGroup" -TemplateFile "C:\template\azureDeploy.json" -verbose

Here Name refers to the name of deployment which is any valid name that can be used to identify the deployment, resource group refers to the name of resource group where this deployment will provision resources and TemplateFile refers to the file location of the ARM template.

To deploy the minimal template that was created earlier, execute the following command from any PowerShell editor. It is to be noted that the storage name must be unique across Azure, and resource group must be unique within a subscription. The resource group is named azureRG provisioned at West Europe region. The Minimal Template takes storageAccountName as a parameter. This parameter must be supplied while deploying the template as shown here:

New-AzureRmResourceGroup -Name "azureRG" -Location "West Europe" -Force -Verbose
New-AzureRmResourceGroupDeployment -Name "Deploy1" -ResourceGroupName "azureRG" -Mode Incremental -TemplateUri "C:\templates\MinimalTemplate\MinimalTemplate \Templates\azuredeploy.json" -Verbose -storageAccountName "auniquename"