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
Calling WebServices with Powershell
#Calling a REST WebService
#Use the google maps api to calculate the distance between 2 cities:
PS C:\> $uri = 'https://maps.googleapis.com/maps/api/directions/json'
PS C:\> $query = '?mode=driving&origin=One Microsoft Way, Redmond, WA 98052, United States&destination=Sägereistrasse 29, 8152 Opfikon, Switzerland'
PS C:\> $response = Invoke-RestMethod $uri$query
#The variable $response contains a json object
PS C:\> $response.routes[0].legs[0].distance
text value
---- -----
35.1 km 35141
PS C:\> $response.routes[0].legs[0].duration
text value
---- -----
27 mins 1615
#Calling a SOAP Web Service with a typed Client
#NOTE: This API is not available anymore. Use the code as an example.
PS C:\> $uri = 'http://www.webservicex.net/airport.asmx?WSDL'
PS C:\> $airportProxy = New-WebServiceProxy -Uri $uri -Namespace ws
PS C:\> $airportProxy.getAirportInformationByAirportCode('ZRH')
Result:
<NewDataSet>
<Table>
<AirportCode>FRA</AirportCode>
<CityOrAirportName>FRANKFURT INTL</CityOrAirportName>
<Country>Germany</Country>
…
#We assign the result to a variable of type XML in order to do some further processing:
PS C:\> [XML]$xml = $airportProxy.getAirportInformationByAirportCode('FRA');
PS C:\> $xml.NewDataSet.Table[0].CityOrAirportName
FRANKFURT INTL
Pro Tip:
Note that you can save web requests in the Chrome Developer Tools (F12 Tools) directly as a PowerShell script:
The result looks like this:
Invoke-WebRequest -Uri "https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-5.0.0" -Headers @{
"method"="GET"
"authority"="docs.microsoft.com"
"scheme"="https"
"path"="/en-us/powershell/azure/install-az-ps?view=azps-5.0.0"
"cache-control"="max-age=0"
"upgrade-insecure-requests"="1"
"user-agent"="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
"accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
"sec-fetch-site"="none"
"sec-fetch-mode"="navigate"
"sec-fetch-user"="?1"
"sec-fetch-dest"="document"
"accept-encoding"="gzip, deflate, br"
"accept-language"="en-US,en;q=0.9"
"if-none-match"="`"BevYgbHK3I9K7WbxPi1FutktnfxT6ySNpBWGQdCiqxY=`""
}
Measure the Execution Time of a Cmdlet
Measure-Command { Get-Service }
Result:
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 10
Ticks : 102564
TotalDays : 1.18708333333333E-07
TotalHours : 2.849E-06
TotalMinutes : 0.00017094
TotalSeconds : 0.0102564
TotalMilliseconds : 10.2564
(Measure-Command { Get-Service }).ToString()
00:00:00.0055617
Powershell Remoting
You want to run a Powershell Command on a remote computer without connecting via RDP? Powershell remoting is here to help.
#Prepare the target machine for PS Remoting
#The Windows Remote Management Service must be running. Verify it using the following cmdlet:
Test-WsMan -ComputerName <computername>
#Activate the remote management service
Enable-PsRemoting -Force
#Option 1: Enter-PSSession
#Open a remote PS Session on the target machine LTMME05
PS C:\> Enter-PSSession –ComputerName LTMME05
#The remote machine name is shown in the command prompt. Cmdlets can be executed on the target machine.
[LTMME05] PS C:\> hostname
LTMME05
#Option2 : Cmdlets with Option –Computername
PS C:\> Get-Process -ComputerName LTMME05 | Select-Object -First 1
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id SI ProcessName
------- ------ ----- ----- ----- ------ -- -- -----------
113 9 6156 7804 64 0.27 8900 1 ACEngSvr
#Option 3 : Invoke-Command (maybe even on multiple machines)
#The examples queries the newest event log entry from 3 different machines
PS C:\> Invoke-Command -ComputerName LTMME05, LTMME06, LTMME07 -ScriptBlock {Get-EventLog Security -Newest 1}
#As an Alternative, you can read the computer names from a txt file:
PS C:\> Invoke-Command –ComputerName (Get-Content machinelist.txt)…
COM Interop
Powershell can be used to access COM components on Windows, such as the voice synthesizer or Microsoft Excel.
#Voice output with COM Interop
$voice = New-Object –ComObject SAPI.SPVoice
$voice.Speak("Hello Azure Guru");
#Reading of the contents of a file
PS C:\> New-Object –ComObject SAPI.SPVoice
PS C:\> $text = Get-Content C:\File.txt
PS C:\> $voice.Speak($text)
#Create an Excel Sheet from OS data using Excel Interop
[Threading.Thread]::CurrentThread.CurrentCulture = "EN-us"
$ex = New-Object -ComObject Excel.Application
$ex.visible = $true
$exWb = $ex.Workbooks.Add()
$exWs = $exWb.Worksheets.Item(1)
$exWs.Cells.Item(2, 1).EntireColumn.ColumnWidth = 40
$exWs.Cells.Item(2,1) = "Services Name"
$exWs.Cells.Item(2,2) = "Service Status"
$row = 3
$services = Get-Service | Select-Object -First 20
foreach($Service in $services)
{
$exWs.Cells.Item($row,1) = $Service.DisplayName
$exWs.Cells.Item($row, 2) = $Service.Status.ToString()
if($Service.Status -eq "Running")
{
$exWs.Cells.Item($row,1).Font.ColorIndex = 10
$exWs.Cells.Item($row,2).Font.ColorIndex = 10
}
elseif($Service.Status -eq "Stopped")
{
$exWs.Cells.Item($row,1).Font.ColorIndex = 3
$exWs.Cells.Item($row,2).Font.ColorIndex = 3
}
$row++
Write-Host "row++"
}
$exWs.SaveAs("C:\ServiceStatusReport.xlsx");
The result of the Excel Interop Script is an Excel Workbook that contains the windows services: