Skip to content

Commit a6fdafd

Browse files
authored
Merge pull request #349 from troettinger/vnext
Add Offline Marketplace synidcation Tool
2 parents 4ac125c + c944d5e commit a6fdafd

File tree

3 files changed

+241
-0
lines changed

3 files changed

+241
-0
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# See LICENSE.txt in the project root for license information.
3+
4+
<#
5+
.SYNOPSIS
6+
List all Azure Marketplace Items available for syndication and allows to download them
7+
Requires an Azure Stack System to be registered for the subscription used to login
8+
#>
9+
10+
function Sync-AzSOfflineMarketplaceItem{
11+
[CmdletBinding(DefaultParameterSetName='SyncOfflineAzsMarketplaceItem')]
12+
13+
Param(
14+
[Parameter(Mandatory=$false, ParameterSetName='SyncOfflineAzsMarketplaceItem')]
15+
[ValidateNotNullorEmpty()]
16+
[String] $Cloud = "AzureCloud",
17+
18+
[Parameter(Mandatory=$true, ParameterSetName='SyncOfflineAzsMarketplaceItem')]
19+
[ValidateNotNullorEmpty()]
20+
[String] $Destination,
21+
22+
[Parameter(Mandatory=$false, ParameterSetName='SyncOfflineAzsMarketplaceItem')]
23+
[ValidateNotNullorEmpty()]
24+
[String] $AzureTenantID,
25+
26+
[Parameter(Mandatory=$false, ParameterSetName='SyncOfflineAzsMarketplaceItem')]
27+
[ValidateNotNullorEmpty()]
28+
[String] $AzureSubscriptionID
29+
30+
)
31+
32+
33+
If ($tenantid.isPresent)
34+
{
35+
$azureAccount = Add-AzureRmAccount -TenantId $AzureTenantID
36+
}
37+
38+
elseif($AzureSubscriptionID.isPresent)
39+
{
40+
Add-AzureRmAccount -subscriptionid $AzureSubscriptionID
41+
}
42+
43+
else
44+
{
45+
$azureAccount = Add-AzureRmAccount
46+
}
47+
48+
49+
$azureEnvironment = Get-AzureRmEnvironment -Name $Cloud
50+
51+
$subscription=Get-AzureRmSubscription
52+
$subscriptionId=$subscription[0].SubscriptionId
53+
54+
$resources=Get-AzureRmResource
55+
$resource=$resources.resourcename
56+
$registrations=$resource|where-object {$_ -like "AzureStack*"}
57+
$registration = $registrations[0]
58+
59+
# Retrieve the access token
60+
$tokens = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.TokenCache.ReadItems()
61+
$token = $tokens |Where Resource -EQ $azureEnvironment.ActiveDirectoryServiceEndpointResourceId |Where DisplayableId -EQ $azureAccount.Context.Account.Id |Sort ExpiresOn |Select -Last 1
62+
63+
64+
$uri1 = "$($azureEnvironment.ResourceManagerUrl.ToString().TrimEnd('/'))/subscriptions/$($subscriptionId.ToString())/resourceGroups/azurestack/providers/Microsoft.AzureStack/registrations/$($Registration.ToString())/products?api-version=2016-01-01"
65+
$Headers = @{ 'authorization'="Bearer $($Token.AccessToken)"}
66+
$products = (Invoke-RestMethod -Method GET -Uri $uri1 -Headers $Headers).value
67+
68+
69+
$Marketitems=foreach ($product in $products)
70+
{
71+
switch($product.properties.productKind)
72+
{
73+
'virtualMachine'
74+
{
75+
Write-output ([pscustomobject]@{
76+
Id = $product.name.Split('/')[-1]
77+
Type = "Virtual Machine"
78+
Name = $product.properties.displayName
79+
Description = $product.properties.description
80+
Publisher = $product.properties.publisherDisplayName
81+
Version = $product.properties.offerVersion
82+
Size = Set-String -size $product.properties.payloadLength
83+
})
84+
}
85+
86+
'virtualMachineExtension'
87+
{
88+
Write-output ([pscustomobject]@{
89+
Id = $product.name.Split('/')[-1]
90+
Type = "Virtual Machine Extension"
91+
Name = $product.properties.displayName
92+
Description = $product.properties.description
93+
Publisher = $product.properties.publisherDisplayName
94+
Version = $product.properties.productProperties.version
95+
Size = Set-String -size $product.properties.payloadLength
96+
})
97+
}
98+
99+
Default
100+
{
101+
Write-Warning "Unknown product kind '$_'"
102+
}
103+
}
104+
}
105+
106+
107+
108+
$Marketitems|Out-GridView -Title 'Azure Marketplace Items' -PassThru|foreach{
109+
110+
$productid=$_.id
111+
112+
# get name of azpkg
113+
$uri2 = "$($azureEnvironment.ResourceManagerUrl.ToString().TrimEnd('/'))/subscriptions/$($SubscriptionId.ToString())/resourceGroups/azurestack/providers/Microsoft.AzureStack/registrations/$Registration/products/$($productid)?api-version=2016-01-01"
114+
Write-Debug $URI2
115+
$Headers = @{ 'authorization'="Bearer $($Token.AccessToken)"}
116+
$productDetails = Invoke-RestMethod -Method GET -Uri $uri2 -Headers $Headers
117+
$azpkgName = $productDetails.properties.galleryItemIdentity
118+
119+
120+
# get download location for apzkg
121+
$uri3 = "$($azureEnvironment.ResourceManagerUrl.ToString().TrimEnd('/'))/subscriptions/$($SubscriptionId.ToString())/resourceGroups/azurestack/providers/Microsoft.AzureStack/registrations/$Registration/products/$productid/listDetails?api-version=2016-01-01"
122+
$uri3
123+
$downloadDetails = Invoke-RestMethod -Method POST -Uri $uri3 -Headers $Headers
124+
125+
#Create Legal Terms POPUP
126+
$a = new-object -comobject wscript.shell
127+
$intAnswer = $a.popup($productDetails.properties.description, `
128+
0,"Legal Terms",4)
129+
If ($intAnswer -eq 6)
130+
131+
{
132+
# download azpkg
133+
$azpkgsource = $downloadDetails.galleryPackageBlobSasUri
134+
$FileExists=Test-Path "$destination\$azpkgName.azpkg"
135+
$DestinationCheck=Test-Path $destination
136+
If ($DestinationCheck -eq $false)
137+
{
138+
new-item -ItemType Directory -force $destination} else{}
139+
140+
If ($FileExists -eq $true) {Remove-Item "$destination\$azpkgName.azpkg" -force} else {
141+
New-Item "$destination\$azpkgName.azpkg"}
142+
$azpkgdestination = "$destination\$azpkgName.azpkg"
143+
Start-BitsTransfer -source $azpkgsource -destination $azpkgdestination -Priority High
144+
145+
146+
147+
# download vhd
148+
$vhdName = $productDetails.properties.galleryItemIdentity
149+
$vhdSource = $downloadDetails.properties.osDiskImage.sourceBlobSasUri
150+
$FileExists=Test-Path "$destination\$productid.vhd"
151+
If ($FileExists -eq $true) {Remove-Item "$destination\$productid.vhd" -force} else {
152+
New-Item "$destination\$productid.vhd" }
153+
$vhdDestination = "$destination\$productid.vhd"
154+
Start-BitsTransfer -source $vhdSource -destination $vhdDestination -Priority High
155+
}
156+
157+
else {
158+
$a.popup("Legal Terms not accpeted, canceling")
159+
}
160+
161+
}
162+
}
163+
164+
165+
166+
function Set-String {
167+
param (
168+
[parameter(mandatory=$true)]
169+
[long] $size
170+
)
171+
172+
if ($size -gt 1073741824) {
173+
return [string]([math]::Round($size / 1073741824)) + " GB"
174+
} elseif ($size -gt 1048576) {
175+
return [string]([math]::Round($size / 1048576)) + " MB"
176+
} else {return "<1 MB"}
177+
}
178+
179+
Export-ModuleMember -Function Sync-AzSOfflineMarketplaceItem

Syndication/demosyndicate.gif

2.35 MB
Loading

Syndication/readme.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Offline Marketplace Syndication
2+
3+
When Azure Stack is deployed in disconnect mode (Without Internet connectivity) you can
4+
not use the build in portal feature to syndicate Azure Market place items and make them
5+
available to your users.
6+
7+
This Tool allows you to download Azure Marketplace Items with a machine that has internet connectivity and side load them.
8+
The downloaded needs to transferred to machine with has connectivity to the Azure Stack deployment and imported.
9+
10+
![](demosyndicate.gif)
11+
12+
## Requirements
13+
14+
- Azure Stack RP registered within your Azure Subscription
15+
- Azure Stack System must be registered
16+
- AzureRM PowerShell needs to be installed
17+
(https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-configure-quickstart)
18+
19+
20+
## Import the Module
21+
```powershell
22+
Import-Module .\AzureStack.MarketplaceSyndication.psm1
23+
```
24+
25+
26+
## Launch the Tool
27+
```powershell
28+
Sync-AzSOfflineMarketplaceItems -destination c:\donwloadfolder
29+
```
30+
31+
## Optional Parameters
32+
33+
Parameter: Cloud
34+
35+
Default: AzureCloud
36+
37+
Description: Once Azure Stack RP is available in other Clouds like Azure China you can specify which one to use
38+
39+
40+
Parameter: AzureTenantID
41+
42+
Description: Specify the Azure Tenant ID for Authentication
43+
44+
45+
Parameter: SubscriptionID
46+
47+
Description: Specify the Azure Subscription ID for Authentication when having multiple subscriptions
48+
49+
## Importing into Azure Stack
50+
51+
Once the download has been transferred to a machine that can access Azure Stack, you need to import the VHD and publish the Gallery Item.
52+
53+
54+
## Importing the VHD
55+
You can use the Portal or PowerShell.
56+
57+
https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-add-vm-image
58+
59+
## Publishing the Gallery Item
60+
You need to use PowerShell
61+
62+
https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-create-and-publish-marketplace-item

0 commit comments

Comments
 (0)