-
Notifications
You must be signed in to change notification settings - Fork 2
/
Create-Azure-Bastion-shareable-link.ps1
192 lines (140 loc) · 8.99 KB
/
Create-Azure-Bastion-shareable-link.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<#
.SYNOPSIS
A script used to create an Azure Bastion shareable link for a specific VM.
.DESCRIPTION
A script used to create an Azure Bastion shareable link for a specific VM.
The script will do all of the following:
Remove the breaking change warning messages.
Validate if the target VM exists, and if so, find the subscription it belongs to; otherwise, exit the script.
Validate if an Azure Bastion host exists, and if so, save the Bastion host as a variable if it uses the Standard SKU; otherwise, exit the script.
Create the shareable link for the VM using the REST API.
Get the shareable link for the VM using the REST API.
.NOTES
Filename: Create-Azure-Bastion-shareable-link.ps1
Created: 20/01/2023
Last modified: 23/03/2023
Author: Wim Matthyssen
Version: 2.0
PowerShell: Azure PowerShell
Requires: PowerShell Az (v9.3.0)
Action: Change variables as needed to fit your needs.
Disclaimer: This script is provided "as is" with no warranties.
.EXAMPLE
Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx" (if not using the default tenant)
.\Create-Azure-Bastion-shareable-link.ps1 -VMName <"your VM name here">
-> Create-Azure-Bastion-shareable-link.ps1 -VMName swpdc003
.LINK
https://wmatthyssen.com/2023/01/11/azure-bastion-connect-to-an-azure-vm-without-accessing-the-azure-portal-by-using-a-shareable-link/
#>
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Parameters
param(
# $vmName -> Name of the target Azure Windows VM
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $vmName
)
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
$subscriptionNameVM = ""
$vmObject = $null
$httpsUriStart = "https://management.azure.com/subscriptions/"
$createApiVersion = "createShareableLinks?api-version=2022-07-01"
$getApiVersion = "GetShareableLinks?api-version=2022-07-01"
$authenticationType = "Bearer"
$method = "Post"
$contentType = "application/json"
$global:currenttime= Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime= Get-Date -UFormat "%A %m/%d/%Y %R"}
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$foregroundColor3 = "Red"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Remove the breaking change warning messages
Set-Item -Path Env:\SuppressAzurePowerShellBreakingChangeWarnings -Value $true | Out-Null
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script started
Write-Host ($writeEmptyLine + "# Script started. Without errors, it takes up to 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Validate if the target VM exists, and if so, find the subscription it belongs to; otherwise, exit the script
$allSubscriptions = Get-AzSubscription | Where-Object { "Enabled" -eq $_.State}
if ($allSubscriptions){
foreach ($subscription in $allSubscriptions){
Set-AzContext -Subscription $Subscription.Name | Out-Null
$vmObject = Get-AzVM -Name $vmName
if ($vmObject) {
$subscriptionNameVM = $subscription.Name
Write-Host ($writeEmptyLine + "# Target VM $vmName found in subscription $subscriptionNameVM" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
break
}
}
}
if (-not $vmObject) {
Write-Host ($writeEmptyLine + "# VM not found" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
Start-Sleep -s 3
Write-Host ($writeEmptyLine + "# Press any key to exit the script ..." + $writeEmptyLine)`
-foregroundcolor $foregroundColor1 $writeEmptyLine;
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null;
return
}
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Validate if an Azure Bastion host exists, and if so, save the Bastion host as a variable if it uses the Standard SKU; otherwise, exit the script
$bastionObject = Get-AzBastion
$bastionName = ($bastionObject).Name
if ($null -eq $bastionObject){
Write-Host ($writeEmptyLine + "# There is no Bastion host included in the current subscription" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
Start-Sleep -s 3
Write-Host ($writeEmptyLine + "# Press any key to exit the script ..." + $writeEmptyLine)`
-foregroundcolor $foregroundColor1 $writeEmptyLine;
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null;
return
} else {
if ($bastionObject.SkuText.Contains("Basic")) {
Write-Host ($writeEmptyLine + "# Bastion host runs with the Basic SKU, please upgrade to Standard SKU" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor3 $writeEmptyLine
Start-Sleep -s 3
Write-Host ($writeEmptyLine + "# Press any key to exit the script ..." + $writeEmptyLine)`
-foregroundcolor $foregroundColor1 $writeEmptyLine;
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null;
return
} else {
Write-Host ($writeEmptyLine + "# Bastion host $bastionName exists in the current subscription; the script will continue" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
}
}
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create the shareable link for the VM using the REST API
# Get subscription ID
$subscriptionObject = Get-AzContext | Select-Object Subscription
$subscriptionID = $subscriptionObject.Subscription.Id
# Get Bastion parameters
$bastionResourceGroupName = ($bastionObject).ResourceGroupName
# Create REST API parameters
$uri = $httpsUriStart + $subscriptionID + "/resourceGroups/$($bastionResourceGroupName)/providers/Microsoft.Network/bastionHosts/$bastionName/$createApiVersion"
$token = (Get-AzAccessToken).Token | ConvertTo-SecureString -AsPlainText -Force
$body = @{vms = @(@{vm = @{id = $(($vmObject).Id) }})} | ConvertTo-Json -Depth 10
# Send an HTTP or HTTPS request to a REST API endpoint
Invoke-WebRequest -Uri $uri -Authentication $authenticationType -Token $token -Method $method -Body $body -ContentType $contentType | Out-Null
# Wait for the link to be created, to avoid errors
Write-Host ($writeEmptyLine + "# Waiting for the shareable link for VM $vmName to be created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
Start-Sleep -Seconds 5
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Get the shareable link for the VM using the REST API
# Get REST API parameters
$uri = $httpsUriStart + $subscriptionID + "/resourceGroups/$($bastionResourceGroupName)/providers/Microsoft.Network/bastionHosts/$bastionName/$getApiVersion"
$getShareableLink = Invoke-RestMethod -Uri $uri -Authentication $authenticationType -Token $token -Method $method -Body $body -ContentType $contentType
$shareableLink = $getShareableLink.value.bsl
Write-Host ($writeEmptyLine + "# Shareable link for VM $vmName available: $shareableLink" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------