powershell

Azure – PowerShell in Azure Cloud Shell

Today we are looking into PowerShell in Azure Cloud Shell. This is still in public preview as of this writing.

If you are wondering why Microsoft would introduce a PowerShell console inside the Azure Cloud Shell, then have a look at the below features:

Features

Browser-based shell experience

Cloud Shell enables access to a browser-based command-line experience built with Azure management tasks in mind. Leverage Cloud Shell to work untethered from a local machine in a way only the cloud can provide.

Choice of preferred shell experience

Azure Cloud Shell gives you the flexibility of choosing the shell experience that best suits the way you work. Linux users can opt for a Bash experience, while Windows users can opt for PowerShell.

Pre-configured Azure workstation

Cloud Shell comes pre-installed with popular command-line tools and language support so you can work faster.
View the full tooling list for Bash experience and PowerShell experience.

Automatic authentication

Cloud Shell securely authenticates automatically on each session for instant access to your resources through the Azure CLI 2.0.

Connect your Azure File storage

Cloud Shell machines are temporary and as a result, require an Azure file share to be mounted as clouddrive to persist your $Home directory. On the first launch, Cloud Shell prompts to create a resource group, storage account, and file share on your behalf. This is a one-time step and will be automatically attached for all sessions. A single file share can be mapped and will be used by both Bash and PowerShell in Cloud Shell.

Below are some conditions that we have to remember:

Cloud Shell runs on a temporary machine provided on a per-session, per-user basis
Cloud Shell times out after 20 minutes without interactive activity
Cloud Shell can only be accessed with a file share attached
Cloud Shell uses the same file share for both Bash and PowerShell
Cloud Shell is assigned one machine per user account
Permissions are set as a regular Linux user (Bash)

Now that we have some background knowledge on the PowerShell in Cloud Shell, let us dig more into the usage of it:

To access the Cloud Shell, click on the PowerShell icon in the Azure portal:

image_1

Once you click on the icon, a pane is opened at the bottom of the screen as shown below. You can choose from two options – BASH or PowerShell. Since we are interested in learning PowerShell in CloudShell, let us choose PowerShell as our desired option.

image_2

When you are starting for the first time, the Shell will configure an Azure File Storage. Cloud Shell machines are temporary and as a result, require an Azure file share to be mounted as clouddrive to persist your $Home directory. Alternatively, if you have multiple subscriptions, you will be allowed to choose your favorite subscription to work with.

image_3

Azure Authentication, Resource Group, Storage Account and File Storage are automatically created as shown below:

image_4

Testing an Azure command. Works perfectly.

image_5

If you are idle for more than 20 minutes, you will be kicked off the session, and you will have to start the session again:

image_6

Discovering the drives under PowerShell in Cloud Shell:

Now let us execute the Get-ChildItem cmdlet and see what we can find.

image_8

As we can see, running the Get-ChildItem in the current scope will list out the subscriptions that your account is associated with.

Traversing one step deeper into the directory, we can see the resources related to the subscription.

image_9

Let us get into the “StroageAccounts” directory to confirm if we get to see a list of Storage Accounts under the selected subscription:

image_10

PowerShell cmdlets to manage PowerShell in Cloud Shell:

From the below information, we can see that Microsoft provides us two cmdlets to work with the cloud shell.

image_12

Get-CloudDrive provides the details of the “Azure File Share” that was created when the cloud shell started. You may continue to use the cloud share. However, if you want a new one, you can dismount and create a new one using the Dismount-CloudDrive cmdlet.

image_11

Note: Once you dismount the Azure file share, your current session will be restarted to set up a new cloud share.

Assumption:

I am assuming that Microsoft is using container service infrastructure to provide a session. You will get the below windows path when you query for the temp drive:

C:\Users\ContainerAdministrator\AppData\Local\Temp

image_11

Note the administrator is a “ContainerAdministrator.” The container here could be a Windows Server or a Windows Container. I am assuming it is a Windows Container since the underlying “image” comes pre-packaged with below tools and a temporary one. A typical use case scenario for Container technology.

image_13

 

If the content is valuable to you, do consider sharing it with your friends and colleagues.

Did I miss out anything? Let me know in the comments section.

 

Download my PowerShell scripts for Free!

 

Advertisements

Powershell – Script to check the Azure VHD lease status

The common miss conception while working with Azure compute is to assume that no billing charges will be incurred once the Azure VM is deleted. This is true to certain extent. Because, once you delete the VM, the billing for compute hours will stop. But the billing continues for the VHD (which was previously associated with the VM) that is still available in the Azure storage account.

As the title of the post states – the idea behind this script is to get a list of “Lease status” of Azure VHDs from all the storage accounts under your subscription. This is particularly helpful to delete any unused VHDs. Thus saving a lot of money for your organization.

The complete script is uploaded in the Microsoft Script Center. Use the below link to download it.

Check the Lease status of VHDs

 

 

Powershell – Script to Monitor Azure VM Availabilty

The idea behind writing this script is to have an automated solution to monitor availability of any Azure VMs. The script fetches the current server status, saves it in an Azure Table. Each script execution is one poll. So the second time the script runs, it fetches the current server status of VMs and then compares it to the previous value. If there are any changes to the server status during polling, such server details will be written to a hash table. Finally the details of the servers can be sent to an email.

Since we are monitoring the VM status from “RUNNING” to “VM STOPPED”, this will eliminate the scenarios, where VMs are stopped manually or as per a scheduled shutdown automation script. In these cases the VM status changes from “RUNNING” to “VM DEALLOCATED”.

Feel free to customize the script to add logic if you want to monitor the status of De-allocated VMs as well.

This script uses SendGrid as an email server. Feel free to add your SMTP address if you have one.

This script is useful when you do not yet have a fully automated monitoring like Nagios/OMS. Maybe you have a couple of servers that you want to monitor and do not want to spend more money on a custom monitoring. Simply create a runbook using this script as a baseline and schedule it in the Azure Automation Account.

The script is uploaded to the Microsoft Script Center. Please download it using the below link:

Monitor Azure VM Availability

Powershell – Truth about default formatting

Have you ever ran a powershell cmdlet and stare at the output, and ever wondered, what makes Powershell display the results in such a way? Is there any hidden configuration that guides the powershell engine to display results in a specific format for one cmdlet and in a different format for another cmdlet??

Read along. This blog will answer your curiosity !

 

Example: Below is the output of Get-service

get-service

 

Below is the output of Get-Process

get-process

 

The answer is Yes. The Powershell Engine is indeed guided by a configuration file that tells powershell on how to display the results. Or we call it as the “Default rules for Formatting” (not an official name :))

You will find the configuration files in the Powershell Installation Folder. Use the “$pshome” variable to find out the Powershell Installation Folder.

PS E:\Work\Powershell\scripts> $pshome
C:\Windows\System32\WindowsPowerShell\v1.0

Change the directory to the Powershell Installation directory and you must be able to find a file named “DotNetTypes.format.ps1xml”.

pshome

Please be cautious, not to edit the file. As it will break the signature and the PowerShell will not be able to use it anymore.

If you want to find out the default rules that are applied, then simply open the file and search for the cmdlet.

Example: If I want to know the default rules for the “Get-Service” cmdlet, I search the file for the keyword “service”. Note that the keyword “Service” should be enclosed within the “Name” tags. That is the correct one. As per the below image.

dotnettypes

 

You can double confirm if it is the correct branch, using the “<TypeName>” tag. This value should equate to the TypeName when you do a Get-Member of that cmdlet.

Example: “System.ServiceProcess.ServiceController” for Get-Service

Now what you are looking in the file are set of directions that the Powershell Engine follows. If you can see in the preceding lines, we can see a <TableControl> tag, which says, that the output should be in the form of table. Next few lines specifies the attributes of the table, such as Width and Height.

 

When you run Get-Service, here’s what happens:

  1. The cmdlet places objects of the type System.ServiceProcess.ServiceController into the pipeline.
  2. At the end of the pipeline is an invisible cmdlet called Out-Default. It is always there, and it’s job is to pick up what ever objects are in the pipeline after all the commands have run.
  3. Out-Default passes the objects to Out-Host, because the PowerShell console is designed to use the screen (called the host) as it’s default form of output.
  4. Most of the Out- cmdlets are incapable of working with normal objects. Instead, they are designed to work with special formatting instructions. So when Out-Host sees that it has been handed normal objects, it passes them to the formatting system.
  5. The formatting system looks at the type of the object and follow an internal set of formatting rules. It uses those rules to produce formatting instructions, which are passed back to Out-Host.
  6. Once Out-Host sees that it has formatting instructions, it follows those instructions  to construct the onscreen display.

So when you run the below cmdlet,

 Get-Process | Out-File process.txt

The out-File will see the normal objects. It will pass them to the formatting system, which will create formatting instructions and then passes back them to the Out-File. The Out-File then constructs the file based on those formatting instructions.

Below are the formatting rules:

  • First Rule: The System looks to see if the type of object it is dealing with has a predefined view. That is what you saw in the DotNetTypes.format.ps1xml.  There are other .format.ps1xml files installed with Powershell, and they are loaded when the powershell starts. You can create your own predefined views as well.

 

  • Second Rule: If the system is not able to find a predefined view, then it will look to see if anyone has declared a “default display property set” for that type of object. You can find that in a configuration file called- “Types.ps1xml” (under the Powershell Home directory)

 

defaultpropertyset

Go back to Powershell and Run:

Get-WmiObject win32_operatingsystem

get-wmiobject

I guess, now you know from where these entries came from. The properties you see are present because they are listed as defaults in the Types.ps1xml. If the formatting system finds a “default display property set”, it will use those set of properties.

 

  • Third Rule: It is about what kind of output to create. If the formatting system will display four or fewer properties, it will use a table. If there are five or more properties, then it will display the results as a list. This is why the Win32_OperatingSystem object was not displayed as a table, as it contained six properties, triggering a list. The theory is that more than 4 properties might not fit into a table, without truncating information.

Powershell – Importance of the position of “Format-” in a pipeline

We have all used the Format-Table, Format-List, Format-Wide cmdlets to make our output more attractive. We know the importance of the Format- cmdlets now. But are we aware of the importance of the position of Format- cmdlets in the pipeline??

Have a look into the below three cmdlet examples:

Get-Process | Format-Table

get-process

 

Get-Process | Get-Member

 

get-process

Get-Process | Format-Table | Get-Member

get-member

When we do a Get-Member, why are we getting “Microsoft.PowerShell.Commands.Internal.Format.FormatStartData” or “Microsoft.PowerShell.Commands.Internal.Format.GroupStartData” instead of  “System.Diagnostics.Process”, with just adding “Format-Table” in the pipeline.

The reason is that the Format-Table cmdlet does not output process objects. It consumes the process objects that you piped in and it outputs the formatting instructions – which is what the Get-Member sees and reports on.

Now try the below cmdlet:

Get-Service | select name, displayname, status | Format-Table | ConvertTo-Html | Out-File services.html

Open the services.html file with your favorite browser and you will be surprised to see the contents of that file, since it does not contain any of the service objects (which you were expecting). This is because you did not pipe the service objects to the ConvertTo-Html cmdlet, instead you have piped the formatting instructions.

This is the reason why the “Format-” cmdlets have to be the last thing on the pipeline.

 

One Object At A Time

We have to avoid putting multiple types of objects into the pipeline. This is because the pipeline is designed to handle only one type of objects.

Enter the cmdlets as below and run them, you will understand what I just said:

Get-Process; Get-Service

The semicolon allows me to put two cmdlets into the single command line, without having to pipe the output of the first cmdlet to the second one. In other words, both the cmdlets will run independently, however they will put the output to the same pipeline.

process-service

 

As you can see in the figure above, the output starts fine, displaying process objects. But the output breaks when displaying the service objects. Rather than producing a table for the service objects, PowerShell reverts to a list.

The  formatting system looks at the first object in the pipeline and uses the type of that object to determine what formatting to produce. If the pipeline contains two or more kinds of objects, the output will not always be complete or useful.

Azure – Setting up Azure Subscription using PowerShell

The very fact that you are here reading this blog is because you have selected to manage your Azure service using Powreshell. Welcome to the team!!

I assume that you are already have a valid Azure subscription. Powershell 3.0 or higher and have the Windows Azure Powershell modules installed. If you do not have the Azure Powershell modules, you can download the Azure PowerShell module here.

Authenticating with a Certificate

You have to download the .publishsettings file from the Microsoft Azure . You can use the below command:

Get-AzurePublishSettingsFile

This will automatically ask you to select your favourite browser, so you can login to Microsoft Azure website.

get-publishfile

Now login with your credentials, that you always do with the Azure Portal

login

The file that we downloaded is very important and we have to handle it with a lot of care. Any one who can get their hands on this file, will have complete access to resources under that subscription. Microsoft imposes a limit on the total number of management certificates that can be associated with a subscription at a time. The number is 100 at the time of writing this blog. Each time you run the Get-AzurePublishSettingsFile cmdlet, Azure generates a new management certificate.

Importing the .pubishsettings file

The next step is to import the .publishsettings file that we just downloaded. I have saved in “E:\Work\Powershell\scripts”, so I am going to run the Import-AzurePublishSettingsFile cmdlet with the complete file path to the settings file.

Import-AzurePublishSettingsFile "E:\Work\Powershell\scripts\Pay-As-You-Go-9-9-2016-credentials.publishsettings"

import-settingfile

As you can see that the cmdlet outputs the subscription information, telling you that the settings are successfully imported.

To double confirm, you can run the Get-AzureSubscription cmdlet.

get-subscription

This cmdlet also tells you, if this subscription is your “Current” / “Default” subscription.

If you have multiple subscriptions, use the Set-AzureSubscription cmdlet to set any azure subscription as “Current” or “Default”.

Also, use the Select-AzureSubscription if you want to switch between subscriptions while working with Powershell.

Powershell – Understanding Select-Object

Understanding how “Select-Object” works, can differentiate an average from a good Powershell user. So lets dedicate some time in understanding how Select-Object works.

Select-Object is mainly used to override the default display of the cmdlets. Example:

select

When you run the Get-Service cmdlet, the output displays the Status, Name and DisplayName. By piping the output of Get-Service to Select-Object, you can override the default display for that object type.

(Piping the Get-Service output to Get-Member, allows you to understand what other properties can be used with the Select-Object)

Select-Object changes the object type

Notice the below two examples and observe the TypeName in both the case.

Get-Service | gm

get-service

Get-Service | Select-Object name | gm

get-service-select

From the above two outputs, you can clearly see that the Select-Object is changing the object from System.ServiceProcess.ServiceController to Selected.System.ServiceProcess.ServiceController. That, it is “Selecting” only few properties from the “original” service object. Now, you will not be able to treat the new object as a service object. Hence you cannot run the operations that you were running on the good-old service object. Hence, the Select-Object HAS to be the last cmdlet in the pipeline.

Selecting subset of objects

Select-Object allows us to choose a subset of objects either from the beginning, from the end, or a chunk of object from a random range. Powershell provides, “First”, “Last” and “Skip” parameters just for these operations.

We are running the below three cmdlets as a demonstration:

Get-Service | Sort-Object name | Select-Object -first 5

Get-Service | Sort-Object name | Select-Object -last 5

Get-Service | Sort-Object name | Select-Object -first 3 -Skip 2

subset

Note: No matter in which order you are specifying the parameters to the Select-Object. If you have specified -Skip, it will ALWAYS execute first, and then -First or -Last (if you have specified along with skip).

Select-Object allows Custom Properties

Custom Properties are the ones which do not come pre-loaded with Powershell. instead they are dynamically created by the user on the go.

Example:

Get-Process | select name, id, @{label='TotalMemory';expression={($_.pm + $_.vm)/ 1MB -as [int]}}

custom properties

What did we just do?

  • We wanted to calculate the TotalMemory of a service. Since we do not have a default parameter that provides us this value. We decided to create a custom property of our own.
  • The structure starting with ‘@‘ sign is called a hash table. A Hash Table contains entries in the form of a name-value pair. Custom Properties comes with two pairs. Each pair is separated by a semi-colon.
  • The first key is called as “Label” or “Name“. The value for this key is what you want to appear in the column header of your custom property.
  • The second key is called the “Expression“. The value for this key,  is the code for the powershell to run/execute to create the resulting row in the custom property.
  • The $_ holder is a place holder for the current object in the pipeline. This can be replaced by $PSItem, both have same meaning.
  • Each @ structure represents a single custom property. You can have as many custom property as you like.

Expanding Properties

Imagine a situation, you want to grab process from the computers [dc=company, dc=pri] in your Active Directory.

You are sure that the below command will fetch the desired computers from the Active Directory.

Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri"

And you also know that the Get-Process has a -ComputerName as a parameter. So you go ahead an happily run the below command:

Get-Process -ComputerName (Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri")

To your surprise the command does not generate the desired result. This is because the Get-AdComputer is generating ADComputer objects. However, the -ComputerName parameter in the Get-Process cmdlet is asking for String[] type input. This is where the -ExpandProperty parameter of the Select-Object shines.

Have a look at this command:

Get-Process -ComputerName (Get-AdComputer -Filter * -SearchBase "dc=company, dc=pri" | Select-Object -ExpandProperty Name)

When Powershell executes this command, it is fetching the desired computers and then expanding the Name property. This has an effect of writing a collection of string to the pipeline, instead of bunch of objects.

-ExpandProperty is a handy technique when you want to save property value to variable.

bits1

As shown above, the Select-Object wrote a ServiceController object into the variable. Hence we need to use a sub-expression to fetch the display name.

bits2

In this case, the Select-Object wrote a String into the variable. This way, it is very easy to access the display name. You can expand single property or a bunch or properties.

From Powershell v3, we have a shortcut way to implicitly expand a property:

(Get-Process).name

implicit

Confirming that the output were String objects:

(Get-Process).name | gm

implicit 2

Some properties are collection of other objects. Example:

expanding1

We can use the -ExpandProperty to “expand” them into their stand-alone objects.

expanding2

We can also use the shortcut trick to get the same results.

expanding3