@@ -90,15 +90,6 @@ Function Add-VMImage{
9090 [bool ] $CreateGalleryItem = $true
9191 )
9292
93- $Domain = " "
94- try {
95- $uriARMEndpoint = [System.Uri ] $ArmEndpoint
96- $Domain = $ArmEndpoint.Split (" ." )[-3 ] + ' .' + $ArmEndpoint.Split (" ." )[-2 ] + ' .' + $ArmEndpoint.Split (" ." )[-1 ]
97- }
98- catch {
99- Write-Error " The specified ARM endpoint was invalid"
100- }
101-
10293 if ($CreateGalleryItem -eq $false -and $PSBoundParameters.ContainsKey (' title' ))
10394 {
10495 Write-Error - Message " The title parameter only applies to creating a gallery item." - ErrorAction Stop
@@ -127,20 +118,24 @@ Function Add-VMImage{
127118 }
128119
129120 # same for storage
130- if (-not (Get-AzureRmStorageAccount - Name $storageAccountName - ResourceGroupName $resourceGroupName - ErrorAction SilentlyContinue)) {
121+ $storageAccount = Get-AzureRmStorageAccount - Name $storageAccountName - ResourceGroupName $resourceGroupName - ErrorAction SilentlyContinue
122+ if (-not ($storageAccount )) {
131123 $storageAccount = New-AzureRmStorageAccount - Name $storageAccountName - Location $location - ResourceGroupName $resourceGroupName - Type Standard_LRS
132124 }
133125 Set-AzureRmCurrentStorageAccount - StorageAccountName $storageAccountName - ResourceGroupName $resourceGroupName
134126 # same for container
135- if (-not (Get-AzureStorageContainer - Name $containerName - ErrorAction SilentlyContinue)) {
136- New-AzureStorageContainer - Name $containerName - Permission Blob
127+ $container = Get-AzureStorageContainer - Name $containerName - ErrorAction SilentlyContinue
128+ if (-not ($container )) {
129+ $container = New-AzureStorageContainer - Name $containerName - Permission Blob
137130 }
138131
139132 if ($pscmdlet.ParameterSetName -eq " VMImageFromLocal" )
140133 {
134+ $storageAccount.PrimaryEndpoints.Blob
141135 $script :osDiskName = Split-Path $osDiskLocalPath - Leaf
142- $script :osDiskBlobURIFromLocal = " https://$storageAccountName .blob.$Domain /$containerName /$osDiskName "
143- Add-AzureRmVhd - Destination $osDiskBlobURIFromLocal - ResourceGroupName $resourceGroupName - LocalFilePath $osDiskLocalPath - OverWrite
136+ $script :osDiskBlobURIFromLocal = ' {0}{1}/{2}' -f $storageAccount.PrimaryEndpoints.Blob.AbsoluteUri , $containerName , $osDiskName
137+ # Add-AzureRmVhd -Destination $osDiskBlobURIFromLocal -ResourceGroupName $resourceGroupName -LocalFilePath $osDiskLocalPath -OverWrite
138+ Set-AzureStorageBlobContent - File $osDiskLocalPath - Container $containerName - Blob $osDiskName
144139
145140 $script :dataDiskBlobURIsFromLocal = New-Object System.Collections.ArrayList
146141 if ($PSBoundParameters.ContainsKey (' dataDisksLocalPaths' ))
@@ -155,6 +150,7 @@ Function Add-VMImage{
155150 }
156151 }
157152
153+ $ArmEndpoint = $ArmEndpoint.TrimEnd (" /" )
158154 $uri = $armEndpoint + ' /subscriptions/' + $subscription + ' /providers/Microsoft.Compute.Admin/locations/' + $location + ' /artifactTypes/platformImage/publishers/' + $publisher
159155 $uri = $uri + ' /offers/' + $offer + ' /skus/' + $sku + ' /versions/' + $version + ' ?api-version=2015-12-01-preview'
160156
@@ -265,97 +261,14 @@ Function Add-VMImage{
265261
266262 if ($CreateGalleryItem -eq $true -And $platformImage.Properties.ProvisioningState -eq ' Succeeded' )
267263 {
268- Add-Type - AssemblyName System.IO.Compression.FileSystem
269- $basePath = Split-Path - Parent $MyInvocation.MyCommand.Module.Path
270- $compressedGalleryItemPath = Join-Path $basePath ' CustomizedVMGalleryItem.azpkg'
271- $extractedGalleryItemPath = Join-Path $basePath ' galleryItem'
272-
273- New-Item - ItemType directory - Path $extractedGalleryItemPath
274-
275- [System.IO.Compression.ZipFile ]::ExtractToDirectory($compressedGalleryItemPath , $extractedGalleryItemPath )
276-
277- $createUIDefinitionPath = Join-Path $extractedGalleryItemPath ' DeploymentTemplates\CreateUIDefinition.json'
278- $JSON = Get-Content $createUIDefinitionPath | Out-String | ConvertFrom-Json
279- $JSON.parameters.osPlatform = $osType
280- $JSON.parameters.imageReference.publisher = $publisher
281- $JSON.parameters.imageReference.offer = $offer
282- $JSON.parameters.imageReference.sku = $sku
283- $JSON | ConvertTo-Json - Compress| set-content $createUIDefinitionPath
284-
285- $manifestPath = Join-Path $extractedGalleryItemPath ' manifest.json'
286- $JSON = Get-Content $manifestPath | Out-String | ConvertFrom-Json
287-
288- $displayName = ' '
289- if ($PSBoundParameters.ContainsKey (' title' ))
290- {
291- $displayName = $title
292- }
293- else
294- {
295- $displayName = " {0}-{1}-{2}" -f $publisher , $offer , $sku
296- }
297-
298- $name = " $offer$sku "
299- # Remove periods so that the offer and sku can be part of the MarketplaceItem name
300- $name = $name -replace " \." , " -"
301-
302- $JSON.name = $name
303- $JSON.publisher = $publisher
304- $JSON.version = $version
305- $JSON.displayName = $displayName
306- $JSON.publisherDisplayName = $publisher
307- $JSON.publisherLegalName = $publisher
308- $JSON | ConvertTo-Json - Compress| set-content $manifestPath
309-
310- $stringsPath = Join-Path $extractedGalleryItemPath ' strings\resources.resjson'
311- $JSON = Get-Content $stringsPath | Out-String | ConvertFrom-Json
312-
313- $descriptionToSet = ' '
314- if ($PSBoundParameters.ContainsKey (' description' ))
315- {
316- $descriptionToSet = $description
317- }
318- else
319- {
320- $descriptionToSet = " Create a virtual machine from a VM image. Publisher: {0}, Offer: {1}, Sku:{2}, Version: {3}" -f $publisher , $offer , $sku , $version
321- }
322-
323- $extractedName = ' MarketplaceItem.zip'
324- $compressedGalleryPackagerPath = Join-Path $basePath $extractedName
325- $extractedGalleryPackagerPath = Join-Path $basePath ' MarketplaceItem'
326-
327- $JSON.longSummary = $descriptionToSet
328- $JSON.description = $descriptionToSet
329- $JSON.summary = $descriptionToSet
330- $JSON | ConvertTo-Json - Compress | set-content $stringsPath
331-
332- Invoke-WebRequest - Uri http:// www.aka.ms/ azurestackmarketplaceitem - OutFile $compressedGalleryPackagerPath
333-
334- [System.IO.Compression.ZipFile ]::ExtractToDirectory($compressedGalleryPackagerPath , $extractedGalleryPackagerPath )
335-
336- $extractedGalleryPackagerExePath = Join-Path $extractedGalleryPackagerPath " Azure Stack Marketplace Item Generator and Sample\AzureGalleryPackageGenerator"
337-
338- $galleryItemName = $publisher + " ." + $name + " ." + $version + " .azpkg"
339- $newPKGPath = Join-Path $extractedGalleryPackagerExePath $galleryItemName
340-
341- $currentPath = $pwd
342-
343- cd $extractedGalleryPackagerExePath
344-
345- .\AzureGalleryPackager.exe package - m $manifestPath - o .
346-
347- cd $currentPath
348-
349- $galleryItemURI = " https://$storageAccountName .blob.$Domain /$containerName /$galleryItemName "
350-
351- $blob = Set-AzureStorageBlobContent –Container $containerName –File $newPKGPath –Blob $galleryItemName
264+ $GalleryItem = CreateGalleyItem - publisher $publisher - offer $offer - sku $sku - version $version - osType $osType - title $title - description $description
265+ $blob = $container | Set-AzureStorageBlobContent –File $GalleryItem.FullName –Blob $galleryItem.Name
266+ $galleryItemURI = ' {0}{1}/{2}' -f $storageAccount.PrimaryEndpoints.Blob.AbsoluteUri , $containerName , $galleryItem.Name
352267
353268 Add-AzureRMGalleryItem - SubscriptionId $subscription - GalleryItemUri $galleryItemURI - ApiVersion 2015 - 04 - 01
354269
355270 # cleanup
356- Remove-Item $extractedGalleryItemPath - Recurse - Force
357- Remove-Item $extractedGalleryPackagerPath - Recurse - Force
358- Remove-Item $compressedGalleryPackagerPath
271+ Remove-Item $GalleryItem
359272 }
360273
361274 Remove-AzureStorageContainer –Name $containerName - Force
@@ -408,6 +321,7 @@ Function Remove-VMImage{
408321 Write-Error - Message (' VM Image with publisher "{0}", offer "{1}", sku "{2}" is not present.' -f $publisher , $offer , $sku ) - ErrorAction Stop
409322 }
410323
324+ $ArmEndpoint = $ArmEndpoint.TrimEnd (" /" )
411325 $uri = $armEndpoint + ' /subscriptions/' + $subscription + ' /providers/Microsoft.Compute.Admin/locations/' + $location + ' /artifactTypes/platformImage/publishers/' + $publisher
412326 $uri = $uri + ' /offers/' + $offer + ' /skus/' + $sku + ' /versions/' + $version + ' ?api-version=2015-12-01-preview'
413327
@@ -459,6 +373,9 @@ function New-Server2016VMImage {
459373
460374 [ValidateNotNullorEmpty ()]
461375 [String ] $TenantId ,
376+
377+ [Parameter ()]
378+ [bool ] $CreateGalleryItem = $true ,
462379
463380 [switch ] $Net35
464381 )
@@ -619,8 +536,15 @@ function New-Server2016VMImage {
619536 try {
620537 Write-Verbose - Message " Creating Server Core Image"
621538 CreateWindowsVHD @ConvertParams - VHDPath $ImagePath - Edition $CoreEdition - ErrorAction Stop - Verbose
622- $description = " This evaluation image should not be used for production workloads."
623- Add-VMImage - sku " 2016-Datacenter-Core" - osDiskLocalPath $ImagePath @PublishArguments - title " Windows Server 2016 Datacenter Core Eval" - description $description
539+ if ($CreateGalleryItem )
540+ {
541+ $description = " This evaluation image should not be used for production workloads."
542+ Add-VMImage - sku " 2016-Datacenter-Core" - osDiskLocalPath $ImagePath @PublishArguments - title " Windows Server 2016 Datacenter Core Eval" - description $description - CreateGalleryItem $CreateGalleryItem
543+ }
544+ else
545+ {
546+ Add-VMImage - sku " 2016-Datacenter-Core" - osDiskLocalPath $ImagePath @PublishArguments - CreateGalleryItem $CreateGalleryItem
547+ }
624548 } catch {
625549 Write-Error - ErrorRecord $_ - ErrorAction Stop
626550 }
@@ -630,8 +554,15 @@ function New-Server2016VMImage {
630554 Write-Verbose - Message " Creating Server Full Image" - Verbose
631555 try {
632556 CreateWindowsVHD @ConvertParams - VHDPath $ImagePath - Edition $FullEdition - ErrorAction Stop - Verbose
633- $description = " This evaluation image should not be used for production workloads."
634- Add-VMImage - sku " 2016-Datacenter" - osDiskLocalPath $ImagePath @PublishArguments - title " Windows Server 2016 Datacenter Eval" - description $description
557+ if ($CreateGalleryItem )
558+ {
559+ $description = " This evaluation image should not be used for production workloads."
560+ Add-VMImage - sku " 2016-Datacenter" - osDiskLocalPath $ImagePath @PublishArguments - title " Windows Server 2016 Datacenter Eval" - description $description - CreateGalleryItem $CreateGalleryItem
561+ }
562+ else
563+ {
564+ Add-VMImage - sku " 2016-Datacenter" - osDiskLocalPath $ImagePath @PublishArguments - CreateGalleryItem $CreateGalleryItem
565+ }
635566 } catch {
636567 Write-Error - ErrorRecord $_ - ErrorAction Stop
637568 }
@@ -642,3 +573,92 @@ function New-Server2016VMImage {
642573 }
643574 }
644575}
576+
577+ Function CreateGalleyItem {
578+ Param (
579+ [ValidatePattern (“ [a-zA-Z0-9-]{3,}” )]
580+ [String ] $publisher ,
581+ [ValidatePattern (“ [a-zA-Z0-9-]{3,}” )]
582+ [String ] $offer ,
583+ [ValidatePattern (“ [a-zA-Z0-9-]{3,}” )]
584+ [String ] $sku ,
585+ [ValidatePattern (“ \d+\.\d+\.\d+” )]
586+ [String ] $version ,
587+ [ValidateSet (' Windows' , ' Linux' )]
588+ [String ] $osType ,
589+ [string ] $title ,
590+ [string ] $description
591+ )
592+ $workdir = ' {0}\{1}' -f $env: TEMP , [System.Guid ]::NewGuid().ToString()
593+ New-Item $workdir - ItemType Directory | Out-Null
594+ $basePath = (Get-Module AzureStack.ComputeAdmin).ModuleBase
595+ $compressedGalleryItemPath = Join-Path $basePath ' CustomizedVMGalleryItem.azpkg'
596+ Copy-Item - Path $compressedGalleryItemPath - Destination " $workdir \CustomizedVMGalleryItem.zip"
597+ $extractedGalleryItemPath = Join-Path $workdir ' galleryItem'
598+ New-Item - ItemType directory - Path $extractedGalleryItemPath | Out-Null
599+ expand-archive - Path " $workdir \CustomizedVMGalleryItem.zip" - DestinationPath $extractedGalleryItemPath - Force
600+
601+ $extractedName = ' MarketplaceItem.zip'
602+ Invoke-WebRequest - Uri http:// www.aka.ms/ azurestackmarketplaceitem - OutFile " $workdir \MarketplaceItem.zip"
603+ Expand-Archive - Path " $workdir \MarketplaceItem.zip" - DestinationPath $workdir - Force
604+
605+ # region UIDef
606+ $createUIDefinitionPath = Join-Path $extractedGalleryItemPath ' DeploymentTemplates\CreateUIDefinition.json'
607+ $JSON = Get-Content $createUIDefinitionPath | Out-String | ConvertFrom-Json
608+ $JSON.parameters.osPlatform = $osType
609+ $JSON.parameters.imageReference.publisher = $publisher
610+ $JSON.parameters.imageReference.offer = $offer
611+ $JSON.parameters.imageReference.sku = $sku
612+ $JSON | ConvertTo-Json - Compress| set-content $createUIDefinitionPath
613+ # endregion
614+
615+ # region Manifest
616+ $manifestPath = Join-Path $extractedGalleryItemPath ' manifest.json'
617+ $JSON = Get-Content $manifestPath | Out-String | ConvertFrom-Json
618+
619+ if (! $title )
620+ {
621+ $title = " {0}-{1}-{2}" -f $publisher , $offer , $sku
622+ }
623+ $name = " $offer$sku "
624+ # Remove periods so that the offer and sku can be part of the MarketplaceItem name
625+ $name = $name -replace " \." , " -"
626+ $JSON.name = $name
627+ $JSON.publisher = $publisher
628+ $JSON.version = $version
629+ $JSON.displayName = $title
630+ $JSON.publisherDisplayName = $publisher
631+ $JSON.publisherLegalName = $publisher
632+ $JSON | ConvertTo-Json - Compress| set-content $manifestPath
633+
634+ # endregion
635+
636+ # region Strings
637+ if (! $description )
638+ {
639+ $description = " Create a virtual machine from a VM image. Publisher: {0}, Offer: {1}, Sku:{2}, Version: {3}" -f $publisher , $offer , $sku , $version
640+ }
641+ $stringsPath = Join-Path $extractedGalleryItemPath ' strings\resources.resjson'
642+ $JSON = Get-Content $stringsPath | Out-String | ConvertFrom-Json
643+ $JSON.longSummary = $description
644+ $JSON.description = $description
645+ $JSON.summary = $description
646+ $JSON | ConvertTo-Json - Compress | set-content $stringsPath
647+ # endregion
648+
649+ $extractedGalleryPackagerExePath = Join-Path $workdir " Azure Stack Marketplace Item Generator and Sample\AzureGalleryPackageGenerator"
650+ $galleryItemName = $publisher + " ." + $name + " ." + $version + " .azpkg"
651+ $currentPath = $pwd
652+ cd $extractedGalleryPackagerExePath
653+ .\AzureGalleryPackager.exe package - m $manifestPath - o $workdir
654+ cd $currentPath
655+
656+ # cleanup
657+ Remove-Item $extractedGalleryItemPath - Recurse - Force
658+ Remove-Item " $workdir \Azure Stack Marketplace Item Generator and Sample" - Recurse - Force
659+ Remove-Item " $workdir \CustomizedVMGalleryItem.zip"
660+ Remove-Item " $workdir \MarketplaceItem.zip"
661+ $azpkg = ' {0}\{1}' -f $workdir , $galleryItemName
662+ return Get-Item - LiteralPath $azpkg
663+ }
664+
0 commit comments