Skip to content

Commit 95237a8

Browse files
Added Get-VMImage and validation
1 parent 110041e commit 95237a8

2 files changed

Lines changed: 98 additions & 21 deletions

File tree

ComputeAdmin/AzureStack.ComputeAdmin.psm1

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
<#
77
.SYNOPSIS
8-
Contains 3 functions.
8+
Contains 4 functions.
99
Add-VMImage: Uploads a VM Image to your Azure Stack and creates a Marketplace item for it.
1010
Remove-VMImage: Removes an existing VM Image from your Azure Stack. Does not delete any
1111
maketplace items created by Add-VMImage.
1212
New-Server2016VMImage: Creates and Uploads a new Server 2016 Core and / or Full Image and
1313
creates a Marketplace item for it.
14+
Get-VMImage: Gets a VM Image from your Azure Stack as an Administrator to view the provisioning state of the image.
1415
#>
1516

1617
Function Add-VMImage{
@@ -99,16 +100,15 @@ Function Add-VMImage{
99100
$ARMEndpoint = 'https://' + $ARMEndpoint
100101
}
101102
}
102-
103+
103104
if($CreateGalleryItem -eq $false -and $PSBoundParameters.ContainsKey('title')) {
104105
Write-Error -Message "The title parameter only applies to creating a gallery item." -ErrorAction Stop
105106
}
106107

107108
if($CreateGalleryItem -eq $false -and $PSBoundParameters.ContainsKey('description')) {
108109
Write-Error -Message "The description parameter only applies to creating a gallery item." -ErrorAction Stop
109110
}
110-
111-
111+
112112
$resourceGroupName = "addvmimageresourcegroup"
113113
$storageAccountName = "addvmimagestorageaccount"
114114
$containerName = "addvmimagecontainer"
@@ -117,7 +117,7 @@ Function Add-VMImage{
117117

118118
#pre validate if image is not already deployed
119119
$VMImageAlreadyAvailable = $false
120-
if (Get-AzureRmVMImage -Location $location -PublisherName $publisher -Offer $offer -Skus $sku -Version $version -ErrorAction SilentlyContinue) {
120+
if ($(Get-VMImage -publisher $publisher -offer $offer -sku $sku -version $version -ArmEndpoint $ArmEndpoint -tenantID $tenantID -azureStackCredentials $azureStackCredentials -location $location -ErrorAction SilentlyContinue).Properties.ProvisioningState -eq 'Succeeded') {
121121
$VMImageAlreadyAvailable = $true
122122
Write-Verbose -Message ('VM Image with publisher "{0}", offer "{1}", sku "{2}", version "{3}" already is present.' -f $publisher,$offer,$sku,$version) -Verbose -ErrorAction Stop
123123
}
@@ -235,7 +235,7 @@ Function Add-VMImage{
235235
Invoke-RestMethod -Method PUT -Uri $uri -Body $RequestBody -ContentType 'application/json' -Headers $Headers
236236
}
237237

238-
$platformImage = Invoke-RestMethod -Method GET -Uri $uri -ContentType 'application/json' -Headers $Headers
238+
$platformImage = Get-VMImage -publisher $publisher -offer $offer -sku $sku -version $version -ArmEndpoint $ArmEndpoint -tenantID $tenantID -azureStackCredentials $azureStackCredentials -location $location
239239

240240
$downloadingStatusCheckCount = 0
241241
while($platformImage.Properties.ProvisioningState -ne 'Succeeded') {
@@ -321,8 +321,8 @@ Function Remove-VMImage{
321321
$subscription, $headers = (Get-AzureStackAdminSubTokenHeader -TenantId $tenantId -AzureStackCredentials $azureStackCredentials -ArmEndpoint $ArmEndpoint)
322322

323323
$VMImageExists = $false
324-
if (Get-AzureRmVMImage -Location $location -PublisherName $publisher -Offer $offer -Skus $sku -Version $version -ErrorAction SilentlyContinue -ov images) {
325-
Write-Verbose "VM Image has been added to Azure Stack - continuing" -Verbose
324+
if (Get-VMImage -publisher $publisher -offer $offer -sku $sku -version $version -ArmEndpoint $ArmEndpoint -tenantID $tenantID -azureStackCredentials $azureStackCredentials -location $location -ErrorAction SilentlyContinue) {
325+
Write-Verbose "VM Image is present in Azure Stack - continuing to remove" -Verbose
326326
$VMImageExists = $true
327327
}
328328
else{
@@ -333,14 +333,21 @@ Function Remove-VMImage{
333333
$uri = $armEndpoint + '/subscriptions/' + $subscription + '/providers/Microsoft.Compute.Admin/locations/' + $location + '/artifactTypes/platformImage/publishers/' + $publisher
334334
$uri = $uri + '/offers/' + $offer + '/skus/' + $sku + '/versions/' + $version + '?api-version=2015-12-01-preview'
335335

336-
try{
337-
if($VMImageExists){
338-
Invoke-RestMethod -Method DELETE -Uri $uri -ContentType 'application/json' -Headers $headers
336+
if($VMImageExists){
337+
$maxAttempts = 5
338+
for ($retryAttempts = 1; $retryAttempts -le $maxAttempts; $retryAttempts++) {
339+
try {
340+
Write-Verbose -Message "Deleting VM Image Attempt $retryAttempts" -Verbose
341+
Invoke-RestMethod -Method DELETE -Uri $uri -ContentType 'application/json' -Headers $headers
342+
break
343+
}
344+
catch {
345+
if($retryAttempts -ge $maxAttempts){
346+
Write-Error -Message ('Deletion of VM Image with publisher "{0}", offer "{1}", sku "{2}" failed with Error:"{3}.' -f $publisher,$offer,$sku,$Error) -ErrorAction Stop
347+
}
348+
}
339349
}
340350
}
341-
catch{
342-
Write-Error -Message ('Deletion of VM Image with publisher "{0}", offer "{1}", sku "{2}" failed with Error:"{3}.' -f $publisher,$offer,$sku,$Error) -ErrorAction Stop
343-
}
344351

345352
if(-not $KeepMarketplaceItem){
346353
Write-Verbose "Removing the marketplace item for the VM Image." -Verbose
@@ -559,7 +566,7 @@ function New-Server2016VMImage {
559566

560567
#Pre-validate that the VM Image is not already available
561568
$VMImageAlreadyAvailable = $false
562-
if (Get-AzureRmVMImage -Location $PublishArguments.location -PublisherName $PublishArguments.publisher -Offer $PublishArguments.offer -Skus $sku -Version $PublishArguments.version -ErrorAction SilentlyContinue) {
569+
if ($(Get-VMImage -publisher $PublishArguments.publisher -offer $PublishArguments.offer -sku $sku -version $PublishArguments.version -ArmEndpoint $ArmEndpoint -tenantID $tenantID -azureStackCredentials $azureStackCredentials -location $PublishArguments.location -ErrorAction SilentlyContinue).Properties.ProvisioningState -eq 'Succeeded') {
563570
$VMImageAlreadyAvailable = $true
564571
Write-Verbose -Message ('VM Image with publisher "{0}", offer "{1}", sku "{2}", version "{3}" already is present.' -f $publisher,$offer,$sku,$version) -Verbose -ErrorAction Stop
565572
}
@@ -592,7 +599,7 @@ function New-Server2016VMImage {
592599

593600
#Pre-validate that the VM Image is not already available
594601
$VMImageAlreadyAvailable = $false
595-
if (Get-AzureRmVMImage -Location $PublishArguments.location -PublisherName $PublishArguments.publisher -Offer $PublishArguments.offer -Skus $sku -Version $PublishArguments.version -ErrorAction SilentlyContinue) {
602+
if ($(Get-VMImage -publisher $PublishArguments.publisher -offer $PublishArguments.offer -sku $sku -version $PublishArguments.version -ArmEndpoint $ArmEndpoint -tenantID $tenantID -azureStackCredentials $azureStackCredentials -location $PublishArguments.location -ErrorAction SilentlyContinue).Properties.ProvisioningState -eq 'Succeeded') {
596603
$VMImageAlreadyAvailable = $true
597604
Write-Verbose -Message ('VM Image with publisher "{0}", offer "{1}", sku "{2}", version "{3}" already is present.' -f $publisher,$offer,$sku,$version) -Verbose -ErrorAction Stop
598605
}
@@ -646,16 +653,15 @@ Function CreateGalleyItem{
646653
expand-archive -Path "$workdir\CustomizedVMGalleryItem.zip" -DestinationPath $extractedGalleryItemPath -Force
647654

648655
$extractedName = 'MarketplaceItem.zip'
649-
$retryAttempts = 1
650-
while ($retryAttempts -le 5) {
656+
$maxAttempts = 5
657+
for ($retryAttempts = 1; $retryAttempts -le $maxAttempts; $retryAttempts++) {
651658
try {
652659
Write-Verbose -Message "Downloading Azure Stack Marketplace Item Generator Attempt $retryAttempts" -Verbose
653660
Invoke-WebRequest -Uri http://www.aka.ms/azurestackmarketplaceitem -OutFile "$workdir\MarketplaceItem.zip"
654661
break
655662
}
656663
catch {
657-
$retryAttempts = $retryAttempts + 1
658-
if($retryAttempts -ge 5){
664+
if($retryAttempts -ge $maxAttempts){
659665
Write-Error "Failed to download Azure Stack Marketplace Item Generator" -ErrorAction Stop
660666
}
661667
}
@@ -721,3 +727,58 @@ Function CreateGalleyItem{
721727
return Get-Item -LiteralPath $azpkg
722728
}
723729

730+
Function Get-VMImage{
731+
Param(
732+
[Parameter(Mandatory=$true)]
733+
[ValidatePattern([a-zA-Z0-9-]{3,})]
734+
[String] $publisher,
735+
736+
[Parameter(Mandatory=$true)]
737+
[ValidatePattern([a-zA-Z0-9-]{3,})]
738+
[String] $offer,
739+
740+
[Parameter(Mandatory=$true)]
741+
[ValidatePattern([a-zA-Z0-9-]{3,})]
742+
[String] $sku,
743+
744+
[Parameter(Mandatory=$true)]
745+
[ValidatePattern(\d+\.\d+\.\d+)]
746+
[String] $version,
747+
748+
[Parameter(Mandatory=$true)]
749+
[ValidateNotNullorEmpty()]
750+
[String] $tenantID,
751+
752+
[String] $location = 'local',
753+
754+
[System.Management.Automation.PSCredential] $azureStackCredentials,
755+
756+
[string] $ArmEndpoint = 'https://api.local.azurestack.external'
757+
758+
)
759+
760+
if(!$ARMEndpoint.Contains('https://')){
761+
if($ARMEndpoint.Contains('http://')){
762+
$ARMEndpoint = $ARMEndpoint.Substring(7)
763+
$ARMEndpoint = 'https://' + $ARMEndpoint
764+
}else{
765+
$ARMEndpoint = 'https://' + $ARMEndpoint
766+
}
767+
}
768+
769+
$ArmEndpoint = $ArmEndpoint.TrimEnd("/")
770+
771+
$subscription, $headers = (Get-AzureStackAdminSubTokenHeader -TenantId $tenantId -AzureStackCredentials $azureStackCredentials -ArmEndpoint $ArmEndpoint)
772+
773+
$uri = $armEndpoint + '/subscriptions/' + $subscription + '/providers/Microsoft.Compute.Admin/locations/' + $location + '/artifactTypes/platformImage/publishers/' + $publisher
774+
$uri = $uri + '/offers/' + $offer + '/skus/' + $sku + '/versions/' + $version + '?api-version=2015-12-01-preview'
775+
776+
try{
777+
$platformImage = Invoke-RestMethod -Method GET -Uri $uri -ContentType 'application/json' -Headers $Headers
778+
return $platformImage
779+
}catch{
780+
return $null
781+
}
782+
783+
}
784+

Connect/AzureStack.Connect.psm1

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ function Add-AzureStackAzureRmEnvironment {
104104
}
105105
}
106106

107+
$ArmEndpoint = $ArmEndpoint.TrimEnd("/")
108+
107109
$Domain = ""
108110
try {
109111
$uriARMEndpoint = [System.Uri] $ArmEndpoint
@@ -357,6 +359,14 @@ function Get-AzureStackAdminSubTokenHeader {
357359
$ARMEndpoint = 'https://' + $ARMEndpoint
358360
}
359361
}
362+
363+
$ArmEndpoint = $ArmEndpoint.TrimEnd("/")
364+
365+
try{
366+
Invoke-RestMethod -Method Get -Uri "$($ARMEndpoint.ToString().TrimEnd('/'))/metadata/endpoints?api-version=2015-01-01" -ErrorAction Stop | Out-Null
367+
}catch{
368+
Write-Error "The specified ARM endpoint: $ArmEndpoint is not valid for this environment. Please make sure you are using the correct administrator ARM endpoint for this environment." -ErrorAction Stop
369+
}
360370

361371
$Domain = ""
362372
try {
@@ -380,7 +390,13 @@ function Get-AzureStackAdminSubTokenHeader {
380390

381391
Login-AzureRmAccount -EnvironmentName "AzureStack" -TenantId $tenantID -Credential $azureStackCredentials | Out-Null
382392

383-
$subscription = Get-AzureRmSubscription -SubscriptionName $subscriptionName
393+
try {
394+
$subscription = Get-AzureRmSubscription -SubscriptionName $subscriptionName
395+
}
396+
catch {
397+
Write-Error "Verify that the login credentials are for the administrator and that the specified ARM endpoint: $ArmEndpoint is the valid administrator ARM endpoint for this environment." -ErrorAction Stop
398+
}
399+
384400
$subscription | Select-AzureRmSubscription | Out-Null
385401

386402
$powershellClientId = "0a7bdc5c-7b57-40be-9939-d4c5fc7cd417"

0 commit comments

Comments
 (0)