This post is a part of a series of posts on Azure Powershell:
Azure Tip 10: Advanced Powershell Tricks (Web Services, StopWatch, Remoting, COM Interop)
Azure Tip 9: More Azure Powershell (pipes, filters, output formatting, exporting)
Azure Tip 8: Getting Started with Azure Powershell
Powershell Pipelines
An important concept in Powershell are pipelines. You can use the pipe operator to forward the results of the first cmdlet to the 2nd cmdlet.
The following example consists of the following parts that are combined by pipe operators:
Get files from a directory Sort the files by size Select the properties Fullname and Length Pick the first 5 items
Get-ChildItem D:\__TEMP -Recurse | Sort-Object Length -Descending | Select-Object Fullname, Length -First 5
FullName Length
-------- ------
D:\__TEMP\orchard\1246_glimpsev2.mp3 57537015
D:\__TEMP\orchard\1237_githubfundamentals.mp3 56979039
D:\__TEMP\orchard\1252_numl.mp3 56507999
D:\__TEMP\orchard\1242_messaging.mp3 56176140
D:\__TEMP\orchard\1253_onboarding_is_culture.mp3 53080948
Powershell Alias
Powershell uses a concept called Aliases. These are shorthand notations for commands:
#Alias Examples
gcm -> Get-Command
cp -> Copy-Item
icm -> Invoke-Command
wget -> Invoke-WebRequest
#Retrieve the full list of Aliases
Get-Alias
#Use the New-Alias CmdLet to create your own aliases
New-Alias -Name k -Value kubectl
#You can now use "k" in order to run kubectl.exe. Noice!
#Using aliases and shortcuts, we can write cmdlets in a very concise manner.
#Before
Get-ChildItem D:\__TEMP -Recurse | Sort-Object Length -Descending | Select-Object Fullname, Length -First 5
#After
gci D:\__TEMP -r | sort Length -d | select Fullname, Length -f 5
Powershell Objects
Everything in Powershell is an object. And to be even more precise: Since Powershell is based on the .NET Framework, you can say that everything in Azure is a .NET object. And a .NET object contains of properties and methods. The Get-Member cmdlet can be used to look at the members (properties and methods) on an object:
PS: C:\> Get-Date | Get-Member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method datetime Add(timespan value)
AddDays Method datetime AddDays(double value)
AddHours Method datetime AddHours(double value)
AddMilliseconds Method datetime AddMilliseconds(double value)
AddMinutes Method datetime AddMinutes(double value)
#...
#As in .NET Programming, we can use the dot "." notation to access members:
PS: C:\> (Get-Date).DayOfWeek
Friday
PS: C:\> (Get-Date).ToShortDateString()
12.02.2016
Filtering
The “Where-Object” cmdlet can be used to filter results. The following operators are available:
- equal: -eq
- not equal: -ne
- less than: -lt
- less than or equal: -le
- greater than: -gt
- greater than or equal: -ge
- contains: -contains
- not contains: -notcontains
- like: -like, -notlike
- match/notmatch: -match, -notmatch
- replace: -replace
One needs to get used to the syntax that is used for filtering. But no worries, you can get used to it:
#Note: $_ stands for the "object to be filtered"
PS C:\> Get-Service | Where-Object {($_.Status -eq "Running") -and ($_.Name -match "Network")}
#The Where-Object cmdlet can be abbreviated by using "where" or even only "?".
Output Formatting and Grouping
#Table Formatting
PS C:\> $bigFiles = Get-ChildItem D:\__TEMP -Recurse | Sort-Object Length -Descending | Select-Object Name, Length, CreationTime, LastAccessTime -First 5
PS: C:\> $bigFiles | Format-Table
Name Length CreationTime
---- ------ ------------
1246_glimpsev2.mp3 57537015 09.02.2016 00:02:40
1252_numl.mp3 56507999 09.02.2016 00:01:55
1242_messaging.mp3 56176140 09.02.2016 00:06:59
1253_onboarding_is_culture.mp3 53080948 09.02.2016 00:01:32
1248_microservices_in_azure.mp3 52134474 09.02.2016 00:02:20
#List Formatting
PS: C:\> $bigFiles | Format-List
Name : 1246_glimpsev2.mp3
Length : 57537015
CreationTime : 09.02.2016 00:02:40
Name : 1252_numl.mp3
Length : 56507999
CreationTime : 09.02.2016 00:01:55
Name : 1242_messaging.mp3
Length : 56176140
CreationTime : 09.02.2016 00:06:59
#Grouping of Data
PS: C:\> $bigFiles | sort IsReadOnly -d | ft -GroupBy IsReadOnly
IsReadOnly: True
Name Length CreationTime IsReadOnly
---- ------ ------------ ----------
1246_glimpsev2.mp3 57537015 09.02.2016 00:02:40 True
1242_messaging.mp3 56176140 09.02.2016 00:06:59 True
IsReadOnly: False
Name Length CreationTime IsReadOnly
---- ------ ------------ ----------
1252_numl.mp3 56507999 09.02.2016 00:01:55 False
1253_onboarding_is_culture.mp3 53080948 09.02.2016 00:01:32 False
1248_microservices_in_azure.mp3 52134474 09.02.2016 00:02:20 False
Exporting Data From Powershell
In this section we take a look at the following cmdlets:
- Export-Csv
- ConvertTo-Json
- ConvertTo-Html
- ConvertTo-Xml
- ConvertTo-Csv
#Export data to CSV
PS: C:\> $bigFiles | Export-Csv D:\bigFiles.csv
"Name","Length","CreationTime","IsReadOnly"
"1246_glimpsev2.mp3","57537015","09.02.2016 00:02:40","True"
"1252_numl.mp3","56507999","09.02.2016 00:01:55","False"
"1242_messaging.mp3","56176140","09.02.2016 00:06:59","True"
"1253_onboarding_is_culture.mp3","53080948","09.02.2016 00:01:32","False"
"1248_microservices_in_azure.mp3","52134474","09.02.2016 00:02:20","False"
#Export data to JSON
PS: C:\> $bigFiles | ConvertTo-Json
[
{
"Name": "1246_glimpsev2.mp3",
"Length": 57537015,
"CreationTime": "\/Date(1454972560452)\/",
"IsReadOnly": true
},
{
"Name": "1252_numl.mp3",
"Length": 56507999,
"CreationTime": "\/Date(1454972515623)\/",
"IsReadOnly": false
}
]
#Export data to HTML
PS: C:\> $bigFiles | ConvertTo-Html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/><col/></colgroup>
<tr><th>Name</th><th>Length</th><th>CreationTime</th><th>IsReadOnly</th></tr>
<tr><td>1246_glimpsev2.mp3</td><td>57537015</td><td>09.02.2016 00:02:40</td><td>True</td></tr>
<tr><td>1252_numl.mp3</td><td>56507999</td><td>09.02.2016 00:01:55</td><td>False</td></tr>
</table>
</body></html>
#Export to XML
PS: C:\> $xml = $bigFiles | ConvertTo-Xml
PS: C:\> $xml.Save(“D:\bigFiles.xml”)
<?xml version="1.0"?>
<Objects>
<Object>
<Property Name="Name">1246_glimpsev2.mp3</Property>
<Property Name="Length">57537015</Property>
<Property Name="CreationTime">09.02.2016 00:02:40</Property>
<Property Name="IsReadOnly">True</Property>
</Object>
<Object>
<Property Name="Name">1252_numl.mp3</Property>
<Property Name="Length">56507999</Property>
<Property Name="CreationTime">09.02.2016 00:01:55</Property>
<Property Name="IsReadOnly">False</Property>
</Object>
</Objects>
PS: C:\> $bigFiles | ConvertTo-Csv
"Name","Length","CreationTime","IsReadOnly"
"1246_glimpsev2.mp3","57537015","09.02.2016 00:02:40","True"
"1252_numl.mp3","56507999","09.02.2016 00:01:55","False"
I am a great fan of the ConvertTo-Html cmdlet. Imagine the possibilities. You could automate the creation of an Html report that shows all the Windows Services running on an application server. It is just a line of Powershell Code:
PS C:\> Get-Service | Select-Object Name, Status -First 10 |Sort-Object Status -Descending | ConvertTo-Html | Out-File "D:\ServiceReport.html"
Another interesting output format is provided by the Out-GridView cmdlet. It will display the data in a desktop window that provides search and filtering:
$bigFiles = Get-ChildItem D:\__TEMP -Recurse | Sort-Object Length -Descending | Select-Object Name, Length, CreationTime, LastAccessTime -First 5
$bigfiles | Out-GridView