Welcome to the fourth article of the series on Shareable Links for Azure Bastion. As promised in the previous article, I will try to automate deleting a shareable link for Azure Bastion. In this article, I intend to build a PowerShell function to delete a shareable Azure Bastion link. Let's see how we can do it.
I have decided to name the function should be Remove-AzBastionShareAbleLink
. It will delete a shareable link for Azure Bastion. The function will interact with the REST API directly. I will try to use the same approach that I used in the previous article. Say it is now a beta version. I will try to improve it in the future.
๐ฌ Structure of the PowerShell Functionโ
First, In the function, I will use the endpoint of GetShareableLink
so that I can get the details of the shareable link. I intend to use this endpoint to get the creation time of the shareable link. Then I will use the endpoint of DeleteShareableLink
to delete the shareable link. The function should return the details of the shareable link that is deleted.
๐ Parameters of the PowerShell Functionโ
The function will have the following parameters.
- VmNames: It will be an array of virtual machine names. It will be mandatory.
- BastionNames: It can be an array of Azure Bastion names. It will be mandatory.
- SubscriptionId: It will be the subscription ID of the Azure Bastion. It will be mandatory.
๐งโ๐ป Execution of the PowerShell Functionโ
Function name is Remove-AzBastionShareAbleLink
. It will delete a shareable link for Azure Bastion. It will return the details of the shareable link that is deleted.
Function Remove-AzBastionShareAbleLink {
<#
.SYNOPSIS
This function will remove a shareable link/links for the Bastion Host
Author: Hasan Gural - Azure VMP
Version: BETA
.DESCRIPTION
There is no way to remove a shareable link for the Bastion Host in the Azure PowerShell module. This function will hit the REST API directly to remove the shareable link.
.NOTES
This function won't enable the shareable link feature for the Bastion Host. This needs to be done manually or see previous article on how to do this.
.EXAMPLE
Remove-AzBastionShareAbleLink -VMNames @("vm-01", "vm-03", "vm-02") -BastionNames @("bastion-vnt-0001","bastion-vnt-0003") -SubscriptionId $subscriptionId
Function will support multiple VMs and Bastion Hosts. Just pass in the names of the VMs and Bastion Hosts and the subscription ID.
You can run the script multiple for removing the shareable links. Existing links will remain intact.
#>
[CmdletBinding()]
param (
[Parameter()]
[array]
$VMNames,
[Parameter()]
[array]
$BastionNames,
[Parameter()]
$SubscriptionId
)
$links = @() # Array to store deleted links
$header = @{
"Content-Type" = "application/json"
Authorization = ("Bearer " + (Get-AzAccessToken).Token)
}
ForEach ($bastion in $BastionNames) {
$getBastion = Get-AzBastion -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $bastion }
if ($getBastion.ProvisioningState -eq "Succeeded") {
$taskCount = 1 # Task counter
$ResourceGroupName = $getBastion.ResourceGroupName
$Location = $getBastion.Location
$SubscriptionId = $getBastion.Id.Split('/')[2]
$Name = $getBastion.Name
Write-Output "[INFO] - ---------------------------------"
Write-Output "[INFO] - Bastion Host Name: $bastion "
Write-Output "[INFO] - Resource Group: $ResourceGroupName"
Write-Output "[INFO] - Subscription: $SubscriptionId"
Write-Output "[INFO] - Location: $Location"
Write-Output "[INFO] - ---------------------------------"
Foreach ($vm in $VMNames) {
$getVM = Get-AzVM -ErrorAction SilentlyContinue | Where-Object { $_.Name -eq $vm }
if ($getVM.ProvisioningState -eq "Succeeded") {
$requestBody = @{
"vms" = @(
@{
"vm" = @{
"id" = $getVM.Id
}
}
)
}
if ($null -ne $requestBody) {
Write-Output "[TASK 1.$($taskCount)] - Retrieving the shareable link for $vm. Please wait."
$uri = "https://management.azure.com/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.Network/bastionHosts/$($Name)/GetShareableLinks?api-version=2022-07-01"
$getBastionLink = Invoke-RestMethod -Method Post -Uri $uri -Headers $header -Body (ConvertTo-Json $requestBody -Depth 10) -SkipHttpErrorCheck
if ($null -ne $getBastionLink.value) {
$uri = "https://management.azure.com/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.Network/bastionHosts/$($Name)/deleteShareableLinks?api-version=2022-07-01"
$response = Invoke-WebRequest -Method Post -Uri $uri -Headers $header -Body (ConvertTo-Json $requestBody -Depth 10)
Start-Sleep -Seconds 5 # Wait for the link to be created. This is to avoid the error "The link is not ready yet. Please try again later."
$links += [PSCustomObject]@{
"Task" = "TASK 1.$($taskCount)"
"VMName" = $vm
"Bastion" = $bastion
"ResourceGroup" = $ResourceGroupName
"Link" = $getBastionLink.value.bsl
"Created Date" = $getBastionLink.value.createdAt
"Deleted Date" = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
}
Write-Output "[TASK 1.1] - Shareable Link has deleted for the Virtual Machine: $vm"
$taskCount++ # Increment the task counter
}
else {
Write-Output "[Error] - Shareable Link does not exist for the Virtual Machine: $vm"
continue
}
}
}
else {
Write-Output "[Error] - Virtual Machine $vm does not exist. Please check the name and try again."
continue
}
}
}
else {
Write-Output "[Error] - Bastion Host $bastion does not exist. Please check the name and try again."
continue
}
return $links | Format-Table -AutoSize
}
}
The PowerShell function is ready. Let's test it. Imagine that we have two virtual machines and two Azure Bastion Hosts. We want to delete the shareable links for the virtual machines. Shareable links are created for the virtual machines. We will use the function to delete the shareable links.
$params = @{
VMNames = @("vm-01", "vm-02")
BastionNames = @("bastion-vnt-0001")
SubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
Remove-AzBastionShareAbleLink @params
After running the function, we can see that the shareable links are deleted. We can see the details of the deleted links and the date and time when the shareable links are created or deleted. Also, I have introduced a new property called "Task." This property will help us to identify the task number. Quickly identify the task number if we have multiple VMs and Bastion Hosts. This will help us to troubleshoot the issues.
Let's check the shareable links again. I would like to confirm that the shareable links are deleted on Azure Bastion Host.
As we can see, the shareable links are deleted. I am heading to the end of the article. I hope you enjoyed the article. If you have any questions, please feel free to ask me. I will be happy to help you.