Skip to content

Commit 73c0832

Browse files
committed
Merge branch 'Flight' of https://github.com/Azure/AzureStack-Tools into Flight
pulling updated changes
2 parents 8b55394 + e97c3ad commit 73c0832

10 files changed

Lines changed: 187 additions & 130 deletions

File tree

ComputeAdmin/AzureStack.ComputeAdmin.psm1

Lines changed: 125 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -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+

ComputeAdmin/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Make sure you have the following module prerequisites installed:
55

66
```powershell
77
Install-Module -Name AzureRM -RequiredVersion 1.2.8 -Scope CurrentUser
8-
Install-Module -Name AzureStack
8+
Install-Module -Name AzureStack -RequiredVersion 1.2.8 -Scope CurrentUser
99
```
1010
Then make sure the following modules are imported:
1111

Connect/AzureStack.Connect.psm1

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ function Get-AzureStackAadTenant
5353
$Domain = ""
5454
try {
5555
$uriARMEndpoint = [System.Uri] $ArmEndpoint
56-
$Domain = $ArmEndpoint.Split(".")[-2] + '.' + $ArmEndpoint.Split(".")[-1]
56+
$i = $ArmEndpoint.IndexOf('.')
57+
$Domain = ($ArmEndpoint.Remove(0,$i+1)).TrimEnd('/')
5758
}
5859
catch {
5960
Write-Error "The specified ARM endpoint was invalid"
@@ -101,7 +102,8 @@ function Add-AzureStackAzureRmEnvironment
101102
$Domain = ""
102103
try {
103104
$uriARMEndpoint = [System.Uri] $ArmEndpoint
104-
$Domain = $ArmEndpoint.Split(".")[-3] + '.' + $ArmEndpoint.Split(".")[-2] + '.' + $ArmEndpoint.Split(".")[-1]
105+
$i = $ArmEndpoint.IndexOf('.')
106+
$Domain = ($ArmEndpoint.Remove(0,$i+1)).TrimEnd('/')
105107
}
106108
catch {
107109
Write-Error "The specified ARM endpoint was invalid"
@@ -173,7 +175,8 @@ function Get-AzureStackNatServerAddress
173175
$Domain = ""
174176
try {
175177
$uriARMEndpoint = [System.Uri] $ArmEndpoint
176-
$Domain = $ArmEndpoint.Split(".")[-2] + '.' + $ArmEndpoint.Split(".")[-1]
178+
$i = $ArmEndpoint.IndexOf('.')
179+
$Domain = ($ArmEndpoint.Remove(0,$i+1)).TrimEnd('/')
177180
}
178181
catch {
179182
Write-Error "The specified ARM endpoint was invalid"
@@ -268,7 +271,8 @@ function Connect-AzureStackVpn
268271
$Domain = ""
269272
try {
270273
$uriARMEndpoint = [System.Uri] $ArmEndpoint
271-
$Domain = $ArmEndpoint.Split(".")[-2] + '.' + $ArmEndpoint.Split(".")[-1]
274+
$i = $ArmEndpoint.IndexOf('.')
275+
$Domain = ($ArmEndpoint.Remove(0,$i+1)).TrimEnd('/')
272276
}
273277
catch {
274278
Write-Error "The specified ARM endpoint was invalid"
@@ -353,7 +357,8 @@ function Get-AzureStackAdminSubTokenHeader
353357
$Domain = ""
354358
try {
355359
$uriARMEndpoint = [System.Uri] $ArmEndpoint
356-
$Domain = $ArmEndpoint.Split(".")[-2] + '.' + $ArmEndpoint.Split(".")[-1]
360+
$i = $ArmEndpoint.IndexOf('.')
361+
$Domain = ($ArmEndpoint.Remove(0,$i+1)).TrimEnd('/')
357362
}
358363
catch {
359364
Write-Error "The specified ARM endpoint was invalid"
@@ -394,11 +399,16 @@ function Get-AADTenantGUID ()
394399
{
395400
param(
396401
[parameter(mandatory=$true, HelpMessage="AAD Directory Tenant <myaadtenant.onmicrosoft.com>")]
397-
[string] $AADTenantName = ""
402+
[string] $AADTenantName = "",
403+
[parameter(mandatory=$false, HelpMessage="Azure Cloud")]
404+
[ValidateSet("AzureCloud","AzureChinaCloud","AzureUSGovernment","AzureGermanCloud")]
405+
[string] $AzureCloud = "AzureCloud"
398406
)
399-
$OauthMetadata = (wget -UseBasicParsing "https://login.microsoftonline.com/$AADTenantName/v2.0/.well-known/openid-configuration").Content | ConvertFrom-Json
407+
$ADauth = (Get-AzureRmEnvironment -Name $AzureCloud).ActiveDirectoryAuthority
408+
$endpt = "{0}{1}/.well-known/openid-configuration" -f $ADauth, $AADTenantName
409+
$OauthMetadata = (wget -UseBasicParsing $endpt).Content | ConvertFrom-Json
400410
$AADid = $OauthMetadata.Issuer.Split('/')[3]
401411
$AADid
402-
}
412+
}
403413

404414
Export-ModuleMember Get-AADTenantGUID

Connect/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ As a prerequisite, make sure that you installed the correct PowerShell modules a
22

33
```powershell
44
Install-Module -Name AzureRM -RequiredVersion 1.2.8 -Scope CurrentUser
5-
Install-Module -Name AzureStack
5+
Install-Module -Name AzureStack -RequiredVersion 1.2.8 -Scope CurrentUser
66
```
77

88
This tool set allows you to connect to an Azure Stack PoC (Proof of Concept) instance from an external personal laptop. You can then access the portal or log into that environment via PowerShell.

Identity/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
```powershell
44
Install-Module -Name AzureRM -RequiredVersion 1.2.8 -Scope CurrentUser
5-
Install-Module -Name AzureStack -Scope CurrentUser
5+
Install-Module -Name AzureStack -RequiredVersion 1.2.8 -Scope CurrentUser
66
```
77
Then make sure the following modules are imported:
88

0 commit comments

Comments
 (0)