diff --git a/ComputeAdmin/AzureStack.ComputeAdmin.psm1 b/ComputeAdmin/AzureStack.ComputeAdmin.psm1
index fb084f24..7a691c35 100644
--- a/ComputeAdmin/AzureStack.ComputeAdmin.psm1
+++ b/ComputeAdmin/AzureStack.ComputeAdmin.psm1
@@ -88,7 +88,7 @@ function Add-AzsVMImage {
[Parameter(Mandatory = $true, ParameterSetName = 'VMImageFromLocal')]
[Parameter(Mandatory = $true, ParameterSetName = 'VMImageFromAzure')]
- [ValidatePattern("[a-zA-Z0-9-]{3,}")]
+ [ValidatePattern("[a-zA-Z0-9-\.]{3,}")]
[String] $Sku,
[Parameter(Mandatory = $true, ParameterSetName = 'VMImageFromLocal')]
@@ -189,7 +189,7 @@ function Add-AzsVMImage {
if ($PSBoundParameters.ContainsKey('dataDisksLocalPaths')) {
foreach ($dataDiskLocalPath in $dataDisksLocalPaths) {
$dataDiskName = Split-Path $dataDiskLocalPath -Leaf
- $dataDiskBlobURI = "https://$storageAccountName.blob.$Domain/$containerName/$dataDiskName"
+ $dataDiskBlobURI = '{0}{1}/{2}' -f $storageAccount.PrimaryEndpoints.Blob.AbsoluteUri, $containerName, $dataDiskName
$dataDiskBlobURIsFromLocal.Add($dataDiskBlobURI)
Add-AzureRmVhd -Destination $dataDiskBlobURI -ResourceGroupName $resourceGroupName -LocalFilePath $dataDiskLocalPath -OverWrite
}
@@ -334,7 +334,7 @@ function Remove-AzsVMImage {
[String] $Offer,
[Parameter(Mandatory = $true)]
- [ValidatePattern("[a-zA-Z0-9-]{3,}")]
+ [ValidatePattern("[a-zA-Z0-9-\.]{3,}")]
[String] $Sku,
[Parameter(Mandatory = $true)]
@@ -353,7 +353,7 @@ function Remove-AzsVMImage {
$VMImageExists = $false
if (Get-AzsVMImage -publisher $publisher -offer $offer -sku $sku -version $version -location $location -ErrorAction SilentlyContinue) {
- Write-Verbose "VM Image is present in Azure Stack - continuing to remove" -Verbose
+ Write-Verbose "VM Image is present in Azure Stack - continuing to remove"
$VMImageExists = $true
}
else {
@@ -370,7 +370,7 @@ function Remove-AzsVMImage {
ApiVersion = "2015-12-01-preview"
}
- Write-Verbose -Message "Deleting VM Image" -Verbose
+ Write-Verbose -Message "Deleting VM Image"
Remove-AzureRmResource @params -Force
}
catch {
@@ -380,7 +380,7 @@ function Remove-AzsVMImage {
}
if (-not $KeepMarketplaceItem) {
- Write-Verbose "Removing the marketplace item for the VM Image." -Verbose
+ Write-Verbose "Removing the marketplace item for the VM Image."
$name = "$offer$sku"
#Remove periods so that the offer and sku can be retrieved from the Marketplace Item name
$name = $name -replace "\.", "-"
@@ -409,7 +409,7 @@ function Get-AzsVMImage {
[String] $Offer,
[Parameter(Mandatory = $true)]
- [ValidatePattern("[a-zA-Z0-9-]{3,}")]
+ [ValidatePattern("[a-zA-Z0-9-\.]{3,}")]
[String] $Sku,
[Parameter(Mandatory = $true)]
@@ -474,9 +474,15 @@ function New-AzsServer2016VMImage {
[Parameter()]
[bool] $Net35 = $true,
+
[Parameter()]
- [string] $MarketPlaceZipPath
+ [string] $MarketPlaceZipPath,
+
+
+
+ [Parameter()][alias('sku_version')]
+ [version]$osImageSkuVersion = (date -Format yyyy.MM.dd).ToString()
)
begin {
@@ -567,7 +573,7 @@ function New-AzsServer2016VMImage {
process {
$location = Get-AzsHomeLocation -Location $location
- Write-Verbose -Message "Checking ISO path for a valid ISO." -Verbose
+ Write-Verbose -Message "Checking ISO path for a valid ISO."
if (!$IsoPath.ToLower().contains('.iso')) {
Write-Error -Message "ISO path is not a valid ISO file." -ErrorAction Stop
}
@@ -596,7 +602,7 @@ function New-AzsServer2016VMImage {
else {
if ($IncludeLatestCU) {
#for latest CU, check https://support.microsoft.com/en-us/help/4000825/windows-10-and-windows-server-2016-update-history
- $Uri = 'http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/10/windows10.0-kb4041691-x64_6b578432462f6bec9b4c903b3119d437ef32eb29.msu'
+ $Uri = 'http://download.windowsupdate.com/d/msdownload/update/software/updt/2018/05/windows10.0-kb4103720-x64_c1fb7676d38fffae5c28b9216220c1f033ce26ac.msu'
$OutFile = "$ModulePath\update.msu"
}
else {
@@ -612,7 +618,7 @@ function New-AzsServer2016VMImage {
}
$CurrentProgressPref = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
- Write-Verbose -Message "Starting download of CU. This will take some time." -Verbose
+ Write-Verbose -Message "Starting download of CU. This will take some time."
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing
$ProgressPreference = $CurrentProgressPref
Unblock-File -Path $OutFile
@@ -636,7 +642,7 @@ function New-AzsServer2016VMImage {
$PublishArguments = @{
publisher = 'MicrosoftWindowsServer'
offer = 'WindowsServer'
- version = '1.0.0'
+ version = $osImageSkuVersion.ToString()
osType = 'Windows'
location = $location
}
@@ -656,7 +662,7 @@ function New-AzsServer2016VMImage {
try {
if ((!(Test-Path -Path $ImagePath)) -and (!$VMImageAlreadyAvailable)) {
Write-Verbose -Message "Creating Server Core Image"
- CreateWindowsVHD @ConvertParams -VHDPath $ImagePath -Edition $CoreEdition -ErrorAction Stop -Verbose
+ CreateWindowsVHD @ConvertParams -VHDPath $ImagePath -Edition $CoreEdition -ErrorAction Stop
}
else {
Write-Verbose -Message "Server Core VHD already found."
@@ -690,8 +696,8 @@ function New-AzsServer2016VMImage {
}
if ((!(Test-Path -Path $ImagePath)) -and (!$VMImageAlreadyAvailable)) {
- Write-Verbose -Message "Creating Server Full Image" -Verbose
- CreateWindowsVHD @ConvertParams -VHDPath $ImagePath -Edition $FullEdition -ErrorAction Stop -Verbose
+ Write-Verbose -Message "Creating Server Full Image"
+ CreateWindowsVHD @ConvertParams -VHDPath $ImagePath -Edition $FullEdition -ErrorAction Stop
}
else {
Write-Verbose -Message "Server Full VHD already found."
@@ -725,7 +731,7 @@ Function CreateGalleryItem {
[ValidatePattern("[a-zA-Z0-9-]{3,}")]
[String] $Offer,
- [ValidatePattern("[a-zA-Z0-9-]{3,}")]
+ [ValidatePattern("[a-zA-Z0-9-\.]{3,}")]
[String] $Sku,
[ValidatePattern("\d+\.\d+\.\d")]
@@ -749,6 +755,7 @@ Function CreateGalleryItem {
New-Item -ItemType directory -Path $extractedGalleryItemPath | Out-Null
expand-archive -Path "$workdir\CustomizedVMGalleryItem.zip" -DestinationPath $extractedGalleryItemPath -Force
+
# Check if we were provided with the MarketPlace Item Generator File
if ( $MarketPlaceZipPath -eq '' )
{
@@ -765,6 +772,7 @@ Function CreateGalleryItem {
Write-Error "Failed to download Azure Stack Marketplace Item Generator" -ErrorAction Stop
}
}
+
}
}
else
diff --git a/Connect/AzureStack.Connect.psm1 b/Connect/AzureStack.Connect.psm1
index b1774734..9acdce0e 100644
--- a/Connect/AzureStack.Connect.psm1
+++ b/Connect/AzureStack.Connect.psm1
@@ -2,7 +2,7 @@
# See LICENSE.txt in the project root for license information.
#requires -Version 4.0
-#requires -Modules AzureRM.Profile, VpnClient, AzureRM.AzureStackAdmin
+#requires -Modules AzureRM.Profile, VpnClient
<#
.SYNOPSIS
diff --git a/Deployment/asdk-installer.ps1 b/Deployment/asdk-installer.ps1
index 6c37b5d5..50e5be38 100644
--- a/Deployment/asdk-installer.ps1
+++ b/Deployment/asdk-installer.ps1
@@ -97,8 +97,34 @@ $Xaml = @'
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- Title="Microsoft Azure Stack Development Kit" Height="650" Width="664" Background="#2D2D2F" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
+ Title="Microsoft Azure Stack Development Kit" Height="650" Width="664" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
+
+
+
+
+
+
+
+
+
-
-
-
-
@@ -231,6 +351,25 @@ $Xaml = @'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -242,130 +381,259 @@ $Xaml = @'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
@@ -400,7 +668,6 @@ $Xaml = @'
-
@@ -533,6 +937,19 @@ $Xaml = @'
+
+
+
@@ -545,42 +962,42 @@ $Xaml = @'
-
-
-
+
+
+
-
-
+
+
-
-
+
-
+
-
+
-
+
@@ -596,27 +1013,27 @@ $Xaml = @'
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
@@ -630,26 +1047,26 @@ $Xaml = @'
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
@@ -664,13 +1081,13 @@ $Xaml = @'
-
+
-
+
@@ -680,6 +1097,68 @@ $Xaml = @'
+
+
+
@@ -693,16 +1172,16 @@ $Xaml = @'
-
+
-
+
-
+
@@ -714,37 +1193,37 @@ $Xaml = @'
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
@@ -757,19 +1236,19 @@ $Xaml = @'
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
@@ -783,11 +1262,11 @@ $Xaml = @'
-
-
+
+
-
+
@@ -799,7 +1278,7 @@ $Xaml = @'
-
+
@@ -810,7 +1289,7 @@ $Xaml = @'
-
+
@@ -921,9 +1400,9 @@ $S_NetInterfaces = {
$syncHash.Control_NetInterface_Stp_Wait.Dispatcher.Invoke([action]{$syncHash.Control_NetInterface_Stp_Wait.Visibility="Collapsed"},"Normal")
- $NetInterfaces | Sort-Object ConnectionState, IPv4DefaultGateway, InterfaceMetric, Ipv4Address -Descending | ForEach-Object {
+ $NetInterfaces | Sort-Object ConnectionState, IPv4DefaultGateway, InterfaceMetric, Ipv4Address -Descending | ForEach-Object {
$syncHash.Control_NetInterface_Lvw_Nics.Dispatcher.Invoke([action]{$syncHash.Control_NetInterface_Lvw_Nics.AddChild($_)},"Normal")
- }
+ }
}
$S_PrepareVHDX = {
@@ -1462,7 +1941,7 @@ Function F_Regex {
else {
#parent stackpanel
$control.value.ToolTip = $null
- $control.value.BorderBrush="#ABADB3"
+ $control.value.BorderBrush=[System.Windows.SystemColors]::ActiveBorderBrush
}
}
@@ -1812,7 +2291,7 @@ $syncHash.Control_Mode_Btn_Left.Add_Click({
$syncHash.Control_Prepare_Stp.Visibility = "Visible"
$syncHash.Control_Header_Tbl_Title.Text = $Text_SafeOS.Prepare_Title
}
- elseif ($Script:Initialized -eq "CloudBuilder_Install") {
+ elseif ($Script:Initialized -eq "CloudBuilder_Install") {
$syncHash.Control_Creds_Stp.Visibility = "Visible"
$syncHash.Control_Header_Tbl_Title.Text = $Text_Install.Credentials_Title
}
@@ -2050,6 +2529,10 @@ $syncHash.Control_Creds_Btn_Next.Add_Click({
$Runspace_Jobs.AddScript($S_NetInterfaces) | Out-Null
$Runspace_Jobs.Runspace = $Runspace_Jobs_Properties
$Runspace_Jobs_Output = $Runspace_Jobs.BeginInvoke()
+
+ }
+ Else {
+ $syncHash.Control_Creds_Pwb_LocalPassword.Focus()
}
})
diff --git a/Marketplace/MarketplaceToolkit.ps1 b/Marketplace/MarketplaceToolkit.ps1
index 314956ac..1494a913 100644
--- a/Marketplace/MarketplaceToolkit.ps1
+++ b/Marketplace/MarketplaceToolkit.ps1
@@ -24,7 +24,7 @@ To use the Marketplace Toolkit for Microsoft Azure Stack script you require:
- This script
- The gallerypackager executable (http://www.aka.ms/azurestackmarketplaceitem)
-- Access as Azure Atack administrator to the Azure Stack environment. This is only required if you want to publish the generated package to the marketplace. For this you will also need to install the current PowerShell modules to support Azure Stack on the machine that runs this script (https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-install).
+- Access as Azure Stack administrator to the Azure Stack environment. This is only required if you want to publish the generated package to the marketplace. For this you will also need to install the current PowerShell modules to support Azure Stack on the machine that runs this script (https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-install).
The Marketplace Toolkit script for Microsoft Azure Stack is based on PowerShell and the Windows Presentation Foundation. It is published in this public repository so you can make improvements to it by submitting a pull request.
@@ -572,43 +572,30 @@ $XAML = @'
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
-
@@ -657,8 +644,6 @@ $X_Input_Tbx_Icon115.Tag = @{'errormessage'='The image size must be 115x115.'}
$X_Input_Tbx_Icon255.Tag = @{'errormessage'='The image size must be 255x115.'}
$X_Input_Tbx_Screenshot.Tag = @{'errormessage'='The image size must be 533x324.'}
$X_Params_Tbx_AddStep.Tag = @{'regex'='[ a-zA-Z]{1,20}';'errormessage'='Maximum 20 characters. Can only contain A-Z, a-z and spaces.'}
-$X_Publish_Pwb_Password1.Tag = @{'errormessage'='Passwords do not match.'}
-$X_Publish_Pwb_Password1.Tag = @{'errormessage'='Passwords do not match.'}
}
function F_Clear {
@@ -681,10 +666,8 @@ $X_Params_Tree_View.Tag = $null
$X_Params_Tree_View.Items.Clear()
$X_Params_Bdr_Steps.Visibility = 'Collapsed'
$X_Publish_Tbx_Package.Text = $null
-$X_Publish_Tbx_Username.Text = $null
-$X_Publish_Pwb_Password1.Password = $null
-$X_Publish_Pwb_Password2.Password = $null
$X_Publish_Tbx_Endpoint.Text = $null
+$X_Publish_Tbx_TenantID.Text = $null
$X_Publish_Lsv_Log.Items.Clear()
$timer.Stop()
}
@@ -715,12 +698,7 @@ if ($regex){
$Script:validation_error = $true
}
}
-if ($compare){
- if (($field_value.Length -gt 0) -and ($field_value -ne $compare)) {
- $Script:validation_error = $true
- $message = "Passwords do not match"
- }
- }
+
if ($extension){
if ($field_value.Length -gt 0){
if (test-path $field_value){
@@ -831,7 +809,6 @@ if ($icon255x115) { $X_Input_Tbx_Icon255.Text = $icon255x115 }
if ($screenshot533x324) { $X_Input_Tbx_Screenshot.Text = $screenshot533x324 }
if ($armTemplate) { $X_Params_Tbx_Template.Text = $armTemplate }
if ($executablePath) { $X_Params_Tbx_Exe.Text = $executablePath }
-if ($userName) { $X_Publish_Tbx_Username.Text = $userName }
if ($endpoint) { $X_Publish_Tbx_Endpoint.Text = $endpoint }
$X_Blade_Preview.Visibility = 'Visible'
}
@@ -887,10 +864,7 @@ $params | foreach {
$param | Add-Member -Type NoteProperty -Name regex -Value '^\d+$'
$param | Add-Member -Type NoteProperty -Name validationMessage -Value 'Only numeric characters are allowed, and it must be a positive value'
}
- if ($_.value.type -eq 'securestring') {
- $param | Add-Member -Type NoteProperty -Name uiType -Value "Microsoft.Common.PasswordBox"
- $param | Add-Member -Type NoteProperty -Name constraints -Value $false
- }
+
# Add each param to the grid varaiable
$Script:Grid += $param
@@ -1295,17 +1269,7 @@ $script:grid | Sort-Object step, tag | forEach {
}
}
- if ($_.uiType -eq 'Microsoft.Common.PasswordBox'){
- $uiDef_param = [pscustomobject]@{
- "name"= $uiDef_param_name
- "type"= "Microsoft.Common.PasswordBox"
- "label"= [pscustomobject]@{
- "password"= "Password"
- "confirmPassword"= "Confirm password"
- }
- "toolTip"= $uiDef_param_description
- }
- }
+
if ($_.step -eq 'elements') {
# element
@@ -1397,22 +1361,20 @@ $X_Params_Tbx_PackagePath.text = $createpackage_azpkg
function F_PublishPackage {
$timer.Start()
$param_Endpoint = $X_Publish_Tbx_Endpoint.Text
-$param_User = $X_Publish_Tbx_Username.Text
-$param_Pass = $X_Publish_Pwb_Password1.Password
$param_ResourceGroup = 'system.staging'
-$param_ResourceGroupLocation = 'local'
+$param_ResourceGroupLocation = $X_Publish_Tbx_Region.Text
$param_StorageAccountName = 'artifacts'
$param_StorageContainerName = 'marketplace'
$param_Package = $X_Publish_Tbx_Package.Text
+$param_TenantID = $X_Publish_Tbx_TenantID.Text
$job_publish_params = @(
$param_Endpoint,
- $param_User,
- $param_Pass,
$param_ResourceGroup,
$param_ResourceGroupLocation,
$param_StorageAccountName,
$param_StorageContainerName
$param_Package
+ $param_TenantID
)
$Script:job = Start-Job -Name "PublishPackage" -ArgumentList $job_publish_params -ScriptBlock $job_publish
}
@@ -1422,13 +1384,12 @@ $Script:job = Start-Job -Name "PublishPackage" -ArgumentList $job_publish_params
$job_publish = {
Param (
[string]$apiEndpoint = $args[0],
-[string]$User = $args[1],
-[string]$Pass = $args[2],
-[string]$ResourceGroup = $args[3],
-[string]$ResourceGroupLocation = $args[4],
-[string]$StorageAccountName = $args[5],
-[string]$StorageContainerName = $args[6],
-[string]$Package = $args[7]
+[string]$ResourceGroup = $args[1],
+[string]$ResourceGroupLocation = $args[2],
+[string]$StorageAccountName = $args[3],
+[string]$StorageContainerName = $args[4],
+[string]$Package = $args[5],
+[string]$TenantID = $args[6]
)
# log
@@ -1446,34 +1407,23 @@ catch {
Exit
}
-# log
-Write-Output 'Creating Credentials object'
-# activity
-$SecurePass = ConvertTo-SecureString $Pass -AsPlainText -Force
-$AdminCreds = New-Object System.Management.Automation.PSCredential ($User, $SecurePass)
+
+
+
# log
write-output 'Creating Environment'
# activity
-$AdminAadID = $user.Split('@')[1]
-$apiEndpointMetadata = Invoke-RestMethod -Uri https://$apiEndpoint/metadata/endpoints?api-version=1.0 -Method Get
-$EnvAzureStackAdmin = Add-AzureRmEnvironment -Name 'AzureStackCloud' `
- -ActiveDirectoryEndpoint ($apiEndpointMetadata.authentication.loginEndpoint + $AdminAadID + '/') `
- -ActiveDirectoryServiceEndpointResourceId $apiEndpointMetadata.authentication.audiences[0] `
- -ResourceManagerEndpoint "https://$apiEndpoint/" `
- -GalleryEndpoint $apiEndpointMetadata.galleryEndpoint `
- -GraphEndpoint $apiEndpointMetadata.graphEndpoint
+
+
+$EnvAzureStackAdmin = Add-AzureRmEnvironment -Name 'AzureStackCloud' -ARMEndpoint https://$apiEndpoint
# log
Write-Output 'Add account to environment'
# activity
-$EnvAccountAzureStackAdmin = Add-AzureRmAccount -Environment $EnvAzureStackAdmin -Credential $AdminCreds
-$rmProfile = Select-AzureRmProfile -Profile $EnvAccountAzureStackAdmin
+Add-AzureRmAccount -Environment $EnvAzureStackAdmin -TenantId $TenantID
+
-# log
-Write-Output 'Select default subscription'
-# activity
-$Subscription = Select-AzureRmSubscription -SubscriptionName 'Default Provider Subscription'
# condition
$Exists = Get-AzureRmResourceGroup -Name $ResourceGroup -Location $ResourceGroupLocation -ErrorAction SilentlyContinue
@@ -1539,7 +1489,7 @@ Remove-item $tempfolder -Force -Recurse
$appName = ($manifest.publisher + '.' + $manifest.name + '.' + $manifest.version)
#condition
-$Exists = Get-AzureRMGalleryItem -ErrorAction SilentlyContinue | where {$_.name -eq $appName}
+$Exists = Get-AzsGalleryItem -ErrorAction SilentlyContinue | where {$_.name -eq $appName}
if ($Exists) {
Write-Output "The Publisher/Name/Version already exists"
Write-Output "Package not published"
@@ -1549,15 +1499,16 @@ Else {
# log
Write-Output 'Upload package to storage container'
# activity
- $blob = Set-AzureStorageBlobContent -Container $StorageContainerName -File $package -Context $StorageContext -Force
+ $blob = Set-AzureStorageBlobContent -Container $StorageContainerName -File $package -Context $StorageContext -Force
+
#log
Write-Output 'Publish package to Marketplace'
#activity
- $publish = Add-AzureRMGalleryItem -GalleryItemUri ($blob.context.BlobEndPoint + $StorageContainerName + '/' + $blob.Name) -Verbose
+ Add-AzsGalleryItem -GalleryItemUri ($blob.context.BlobEndPoint + $StorageContainerName + '/' + $blob.Name) -force
+
}
-if ($publish.StatusCode -eq '201'){ write-output 'Completed succesfully' }
-else { write-output 'Publish item failed' }
+
}
@@ -2028,24 +1979,13 @@ $X_Publish_Tbx_Package.Add_LostFocus({
F_Validation -field 'X_Publish_Tbx_Package' -field_value $X_Publish_Tbx_Package.Text -extension '.azpkg' -columnwidth 190
})
-$X_Publish_Pwb_Password1.Add_LostFocus({
-if ($X_Publish_Pwb_Password2.Password -ne ''){
- F_Validation -field 'X_Publish_Pwb_Password1' -field_value $X_Publish_Pwb_Password1.Password -compare $X_Publish_Pwb_Password2.Password -columnwidth 258
- }
-})
-$X_Publish_Pwb_Password2.Add_LostFocus({
-if ($X_Publish_Pwb_Password1.Password -ne ''){
- F_Validation -field 'X_Publish_Pwb_Password2' -field_value $X_Publish_Pwb_Password2.Password -compare $X_Publish_Pwb_Password1.Password -columnwidth 258
- }
-})
$X_Publish_Btn_Publish.Add_Click({
F_Validation -field 'X_Publish_Tbx_Package' -field_value $X_Publish_Tbx_Package.Text -empty -extension '.azpkg' -columnwidth 190
-F_Validation -field 'X_Publish_Tbx_Username' -field_value $X_Publish_Tbx_Username.Text -empty -columnwidth 258
-F_Validation -field 'X_Publish_Pwb_Password1' -field_value $X_Publish_Pwb_Password1.Password -empty -compare $X_Publish_Pwb_Password2.Password -columnwidth 258
-F_Validation -field 'X_Publish_Pwb_Password2' -field_value $X_Publish_Pwb_Password2.Password -empty -compare $X_Publish_Pwb_Password1.Password -columnwidth 258
F_Validation -field 'X_Publish_Tbx_Endpoint' -field_value $X_Publish_Tbx_Endpoint.Text -empty -columnwidth 258
+F_Validation -field 'X_Publish_Tbx_Region' -field_value $X_Publish_Tbx_Region.Text -empty -columnwidth 258
+F_Validation -field 'X_Publish_Tbx_TenantID' -field_value $X_Publish_Tbx_TenantID.Text -empty -columnwidth 258
$validation = (Get-Variable | where {($_.name -match 'X_Publish_Tbx') -or ($_.name -match 'X_Publish_Pwb')}).value.parent.children | where {$_.GetType().fullname -eq 'System.Windows.Controls.Button' -and $_.Content -eq '!' -and $_.visibility -eq 'visible'}
if ((!($validation)) -and ($Script:job.state -ne 'running')){
$X_Publish_Lsv_Log.Items.Clear()
@@ -2092,10 +2032,9 @@ $X_Dashboard.Visibility = 'Visible'
$X_Wizard_Btn_Publish.Background = 'White'
$X_Wizard_Btn_Input.Background = '#B3EBFB'
F_Validation -field 'X_Publish_Tbx_Package' -field_value $X_Publish_Tbx_Package.Text -columnwidth 190
-F_Validation -field 'X_Publish_Tbx_Username' -field_value $X_Publish_Tbx_Username.Text -columnwidth 258
-F_Validation -field 'X_Publish_Pwb_Password1' -field_value $X_Publish_Pwb_Password1.Password -columnwidth 258
-F_Validation -field 'X_Publish_Pwb_Password2' -field_value $X_Publish_Pwb_Password2.Password -columnwidth 258
F_Validation -field 'X_Publish_Tbx_Endpoint' -field_value $X_Publish_Tbx_Endpoint.Text -columnwidth 258
+F_Validation -field 'X_Publish_Tbx_Region' -field_value $X_Publish_Tbx_Region.Text -columnwidth 258
+F_Validation -field 'X_Publish_Tbx_TenantID' -field_value $X_Publish_Tbx_TenantID.Text -columnwidth 258
if ($script:job.id){ remove-job $script:job.id -ErrorAction SilentlyContinue }
})
#endregion
diff --git a/Marketplace/MarketplaceToolkit_parameters.ps1 b/Marketplace/MarketplaceToolkit_parameters.ps1
index 8e62f0fe..95b2a836 100644
--- a/Marketplace/MarketplaceToolkit_parameters.ps1
+++ b/Marketplace/MarketplaceToolkit_parameters.ps1
@@ -12,5 +12,4 @@ $Icon255x115 = "C:\AzureStack_Marketplace\255.png"
$Screenshot533X324 = "C:\AzureStack_Marketplace\533.png"
$ArmTemplate = ""
$ExecutablePath = ""
-$UserName = "admin@mydomain.onmicrosoft.com"
$Endpoint = "adminmanagement.local.azurestack.external"
\ No newline at end of file
diff --git a/Marketplace/README.md b/Marketplace/README.md
index e10b28c7..67abf484 100644
--- a/Marketplace/README.md
+++ b/Marketplace/README.md
@@ -15,7 +15,9 @@ To use the Marketplace Toolkit for Microsoft Azure Stack script you require:
- This script
- The gallerypackager executable (http://www.aka.ms/azurestackmarketplaceitem)
-- Access as Azure Stack administrator to the Azure Stack environment. This is only required if you want to publish the generated package to the marketplace. For this you will also need to install the current PowerShell modules to support Azure Stack on the machine that runs this script (https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-install).
+- Access as Azure Stack administrator to the Azure Stack environment. This is only required if you want to publish the generated package to the marketplace. For this you will also need to install the current PowerShell modules (1.3.0) to support Azure Stack on the machine that runs this script (https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-install).
+
+
## Download the Marketplace Toolkit
To download the Azure Stack Marketplace Toolkit from this repository, run the following PowerShell script:
@@ -65,8 +67,10 @@ The VM extension on the dashboard is used to create a marketplace item for a VM
## Limitations
-- The current version of the script only supports Azure AD for directly publishing an package to the marketplace. We are working on adding support for ADFS. When you are using ADFS you can still create the marketplace item package with the tool, but publishing the package to the marketplace is a manual process in PowerShell.
## Improvements
+- Added support for AD FS deployments
The Marketplace Toolkit for Microsoft Azure Stack is based on PowerShell and the Windows Presentation Foundation. It is published in this public repository so you can make improvements to it by submitting a pull request.
+
+
diff --git a/README.md b/README.md
index 2b169904..104be236 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,29 @@
-# Azure Stack Development Kit Version
+# Azure Stack Development Kit Version
These tools are meant for use with **Azure Stack Development Kit**.
+## Important Notification 5/8/2018
+
+The following Tools will be deprecated and removed from the repository by 5/31/2018. The new Azure Stack Admin PowerShell Module 1.3.0 will replace those.
+- ComputeAdmin
+- Identity\New-AzsAdGraphServicePrincipal
+- Infrastructure
+- ServiceAdmin
+- CanaryValidator
+
+
## Tools for using Azure and Azure Stack
To use these tools, obtain Azure Stack compatible Azure PowerShell module. Unless you've installed from other sources, one way to do it is to obtain from public package repositories as follows. Note that both of these could still be used to operate against Azure as well as Azure Stack, but may lack some of the latest Azure features.
For PowerShell, install the following:
+
```powershell
Install-Module -Name 'AzureRm.Bootstrapper'
Install-AzureRmProfile -profile '2017-03-09-profile' -Force
-Install-Module -Name AzureStack -RequiredVersion 1.2.11
+Install-Module -Name AzureStack -RequiredVersion 1.3.0
```
Obtain the tools by cloning the git repository.
@@ -56,46 +67,41 @@ Connect to an Azure Stack instance from your personal computer/laptop.
Create and manage identity related objects and configurations for Azure Stack
-- Create Service Principals in a disconnected topology
-
-## [Azure Stack Service Administration](ServiceAdmin)
-
-Manage plans and subscriptions in Azure Stack.
-
-- Add default (unlimited) plans and quotas so that tenants can create new subscriptions
-
-## [Azure Stack Compute Administration](ComputeAdmin)
-
-Manage compute (VM) service in Azure Stack.
-
-- Add VM Image to the Azure Stack Marketplace
-
-## [Azure Stack Infrastructure Administration](Infrastructure)
-
-Manage Azure Stack Infrastructure
-
-- Get Infrastructure Roles
-- Get Infrastructure Role Instances
-- Start Infrastructure Role Instance
-- Stop Infrastructure Role Instance
-- Restart Infrastructure Role Instance
-- Get Storage Capacity
-- Get Storage Shares
-- Get Scale Unit
-- Get Scale Unit Node
-- Get Gateway Pool
-- Get Gateway
-- Get SLB MUX
-- Get IP Pool
-- Add IP Pool
-- Get MAC Address Pool
-- Get Logical network
-- Get Alert
-- Close Alert
-- Get Update Region Summary
-- Get Update
-- Apply Update
-- Get Update run
+## [Azure Stack Service Administration](ServiceAdmin)
+
+- Manage plans and subscriptions in Azure Stack.
+- Add default (unlimited) plans and quotas so that tenants can create new subscriptions
+
+## [Azure Stack Compute Administration](ComputeAdmin)
+
+- Manage compute (VM) service in Azure Stack.
+- Add VM Image to the Azure Stack Marketplace
+
+## [Azure Stack Infrastructure Administration](Infrastructure)
+
+- Manage Azure Stack Infrastructure
+- Get Infrastructure Roles
+- Get Infrastructure Role Instances
+- Start Infrastructure Role Instance
+- Stop Infrastructure Role Instance
+- Restart Infrastructure Role Instance
+- Get Storage Capacity
+- Get Storage Shares
+- Get Scale Unit
+- Get Scale Unit Node
+- Get Gateway Pool
+- Get Gateway
+- Get SLB MUX
+- Get IP Pool
+- Add IP Pool
+- Get MAC Address Pool
+- Get Logical network
+- Get Alert
+- Close Alert
+- Get Update Region Summary
+- Get Update
+- Apply Update
+- Get Update run
## [AzureRM Template Validator](TemplateValidator)
diff --git a/Registration/RegisterWithAzure.psm1 b/Registration/RegisterWithAzure.psm1
index 471d1979..08cb6638 100644
--- a/Registration/RegisterWithAzure.psm1
+++ b/Registration/RegisterWithAzure.psm1
@@ -9,16 +9,33 @@ You must also have access to an account / directory that is an owner or contribu
#>
-# Create log folder / prevent duplicate logs
-$LogFolder = "$env:SystemDrive\MASLogs"
-if (-not (Test-Path $LogFolder))
+# Generate log file(s)
+function New-RegistrationLogFile
{
- New-Item -Path $LogFolder -ItemType Directory -Force | Out-Null
-}
-if(-not $AzureRegistrationLog)
-{
- $AzureRegistrationLog = "$LogFolder\AzureStack.AzureRegistration.$(Get-Date -Format yyyy-MM-dd.HH-mm-ss).log"
- $null = New-Item -Path $AzureRegistrationLog -ItemType File -Force
+ [CmdletBinding()]
+ param(
+ [Parameter(Mandatory=$false)]
+ [String] $LogDate = (Get-Date -Format yyyy-MM-dd),
+
+ [Parameter(Mandatory=$false)]
+ [String] $RegistrationFunction = 'RegistrationOperation'
+ )
+
+ # Create log folder
+ $LogFolder = "$env:SystemDrive\MASLogs\Registration"
+ if (-not (Test-Path $LogFolder))
+ {
+ New-Item -Path $LogFolder -ItemType Directory -Force | Out-Null
+ }
+
+ $logFilePath = "$LogFolder\AzureStack.Activation.$RegistrationFunction-$LogDate.log"
+ Write-Verbose "Writing logs to file: $logFilePath"
+ if (-not (Test-Path $logFilePath -PathType Leaf))
+ {
+ $null = New-Item -Path $logFilePath -ItemType File -Force
+ }
+
+ $Script:registrationLog = $logFilePath
}
################################################################
@@ -169,6 +186,8 @@ function Set-AzsRegistration{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$azureAccountInfo = Get-AzureAccountInfo -AzureContext $AzureContext
@@ -201,7 +220,7 @@ function Set-AzsRegistration{
New-RBACAssignment -SubscriptionId $AzureContext.Subscription.SubscriptionId -ResourceGroupName $ResourceGroupName -RegistrationName $RegistrationName -ServicePrincipal $servicePrincipal
# Activate AzureStack syndication / usage reporting features
- $activationKey = Get-AzsActivationkey -ResourceGroupName $ResourceGroupName -RegistrationName $RegistrationName
+ $activationKey = Get-AzsActivationkey -ResourceGroupName $ResourceGroupName -RegistrationName $RegistrationName -ConnectedScenario
Log-Output "Activating Azure Stack (this may take up to 10 minutes to complete)."
Activate-AzureStack -Session $session -ActivationKey $ActivationKey
@@ -278,6 +297,8 @@ function Remove-AzsRegistration{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$azureAccountInfo = Get-AzureAccountInfo -AzureContext $AzureContext
@@ -390,6 +411,8 @@ Function Get-AzsRegistrationToken{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
if(($BillingModel -eq 'Capacity') -and ([String]::IsNullOrEmpty($AgreementNumber)))
{
Log-Throw -Message "Agreement number is null or empty when BillingModel is set to Capacity" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
@@ -502,6 +525,8 @@ Function Register-AzsEnvironment{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$azureAccountInfo = Get-AzureAccountInfo -AzureContext $AzureContext
@@ -587,6 +612,8 @@ Function UnRegister-AzsEnvironment{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
if (-not $RegistrationName)
@@ -662,9 +689,12 @@ Function Get-AzsRegistrationName{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$session = Initialize-PrivilegedEndpointSession -PrivilegedEndpoint $PrivilegedEndpoint -PrivilegedEndpointCredential $PrivilegedEndpointCredential -Verbose
$registrationName = Get-RegistrationName -Session $session
+ Log-Output "Registration name: $registrationName"
Log-Output "*********************** End log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n`r`n"
return $registrationName
}
@@ -703,12 +733,20 @@ Function Get-AzsActivationKey{
[String] $ResourceGroupName = 'azurestack',
[Parameter(Mandatory = $false)]
- [String] $KeyOutputFilePath
+ [String] $KeyOutputFilePath,
+
+ [Parameter(Mandatory = $false)]
+ [Switch] $ConnectedScenario
)
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ if (-not $ConnectedScenario)
+ {
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$azureAccountInfo = Get-AzureAccountInfo -AzureContext $AzureContext
@@ -799,6 +837,8 @@ param(
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$session = Initialize-PrivilegedEndpointSession -PrivilegedEndpoint $PrivilegedEndpoint -PrivilegedEndpointCredential $PrivilegedEndpointCredential -Verbose
@@ -842,6 +882,8 @@ Function Remove-AzsActivationResource{
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$VerbosePreference = [System.Management.Automation.ActionPreference]::Continue
+ New-RegistrationLogFile -RegistrationFunction $PSCmdlet.MyInvocation.MyCommand.Name
+
Log-Output "*********************** Begin log: $($PSCmdlet.MyInvocation.MyCommand.Name) ***********************`r`n"
$session = Initialize-PrivilegedEndpointSession -PrivilegedEndpoint $PrivilegedEndpoint -PrivilegedEndpointCredential $PrivilegedEndpointCredential -Verbose
@@ -849,6 +891,7 @@ Function Remove-AzsActivationResource{
try
{
$AzureStackStampInfo = Invoke-Command -Session $session -ScriptBlock { Get-AzureStackStampInformation }
+ Log-Output "Logging in to AzureStack administrator account. TenantId: $($AzureStackStampInfo.AADTenantID) Environment: 'AzureStack'"
Login-AzureRmAccount -TenantId $AzureStackStampInfo.AADTenantID -Environment 'AzureStack'
$azureStackContext = Get-AzureRmContext
@@ -1206,7 +1249,7 @@ function New-RBACAssignment{
Log-Output "Setting $RoleName role on '$($RegistrationResource.ResourceId)'"
# Determine if RBAC role has been assigned
- $roleAssignmentScope = "/subscriptions/$($RegistrationResource.SubscriptionId)/resourceGroups/$($RegistrationResource.ResourceGroupName)/providers/Microsoft.AzureStack/registrations/$($RegistrationResource.ResourceName)"
+ $roleAssignmentScope = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.AzureStack/registrations/$($RegistrationResource.Name)"
$roleAssignments = Get-AzureRmRoleAssignment -Scope $roleAssignmentScope -ObjectId $ServicePrincipal.ObjectId
foreach ($role in $roleAssignments)
@@ -1358,13 +1401,46 @@ function Get-AzureAccountInfo{
$AzureSubscription = $AzureContext.Subscription
$tokens = @()
- try{$tokens += [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.TokenCache.ReadItems()}catch{}
- try{$tokens += [Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache]::DefaultShared.ReadItems()}catch{}
- try{$tokens += $AzureContext.TokenCache.ReadItems()}catch{}
+ $exceptions = @()
+ try{
+ $tokens += $AzureContext.TokenCache.ReadItems()
+ if ($tokens.Count -eq 0)
+ {
+ throw "No Tokens collected."
+ }
+ }
+ catch{
+ Log-Warning "Tokens not collected using method: `$AzureContext.TokenCache.ReadItems() `r`n$_"
+ $exceptions += $_.Exception
+ }
+
+ try{
+ $tokens += [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.TokenCache.ReadItems()
+ if ($tokens.Count -eq 0)
+ {
+ throw "No Tokens collected."
+ }
+ }
+ catch{
+ Log-Warning "Tokens not collected using method: [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.TokenCache.ReadItems() `r`n$_"
+ $exceptions += $_.Exception
+ }
- if (-not $tokens -or ($tokens.Count -le 0))
+ try{
+ $tokens += [Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache]::DefaultShared.ReadItems()
+ if ($tokens.Count -eq 0)
+ {
+ throw "No Tokens collected."
+ }
+ }
+ catch{
+ Log-Warning "Tokens not collected using method: [Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache]::DefaultShared.ReadItems() `r`n$_"
+ $exceptions += $_.Exception
+ }
+
+ if ($tokens.Count -lt 1)
{
- Log-Throw -Message "Token cache is empty `r`n$($_)" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ Log-Throw -Message "Token cache is empty `r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name -ExceptionObject $exceptions
}
$token = $tokens |
@@ -1525,22 +1601,60 @@ function Confirm-StampVersion{
[Parameter(Mandatory=$true)]
[System.Management.Automation.Runspaces.PSSession] $PSSession
)
+
+ $registrationVersion = [Version]"1.1806.0.21"
try
{
Log-Output "Verifying stamp version."
$stampInfo = Invoke-Command -Session $PSSession -ScriptBlock { Get-AzureStackStampInformation -WarningAction SilentlyContinue }
- $minVersion = [Version]"1.0.170828.1"
- if ([Version]$stampInfo.StampVersion -lt $minVersion) {
- Log-Throw -Message "Script only applicable for Azure Stack builds $minVersion or later." -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
- }
-
- Log-Output -Message "Running registration actions on build $($stampInfo.StampVersion). Cloud Id: $($stampInfo.CloudID), Deployment Id: $($stampInfo.DeploymentID)"
- return $stampInfo
}
Catch
{
Log-Throw "An error occurred checking stamp information: `r`n$($_)" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
}
+
+ $versionNumber = [Version]$stampInfo.StampVersion
+ $minVersion = [Version]"1.0.170928.1"
+ if ($versionNumber -lt $minVersion)
+ {
+ Log-Throw -Message "Script only applicable for Azure Stack builds $minVersion or later." -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+
+ if ($versionNumber -lt $registrationVersion)
+ {
+ switch ($versionNumber.Build)
+ {
+ "170928"
+ {
+ Log-Warning -Message "Running a newer version of registration with an older version of Azure Stack. Registration version: $registrationVersion Build version: $versionNumber"
+ Log-Warning -Message "NOTE: The below URL is NOT a module and does not need to be imported!"
+ Log-Throw -Message "Please download the correct version of the registration functions from the URL below and retry: `r`nhttps://github.com/Azure/AzureStack-Tools/blob/registration/v1709/Registration/RegisterWithAzure.ps1`r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+ "171020"
+ {
+ Log-Warning -Message "Running a newer version of registration with an older version of Azure Stack. Registration version: $registrationVersion Build version: $versionNumber"
+ Log-Throw -Message "Please download the correct version of the registration functions from the URL below and retry: `r`nhttps://github.com/Azure/AzureStack-Tools/blob/registration/v1710/Registration/RegisterWithAzure.psm1`r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+ "171201"
+ {
+ Log-Warning -Message "Running a newer version of registration with an older version of Azure Stack. Registration version: $registrationVersion Build version: $versionNumber"
+ Log-Throw -Message "Please download the correct version of the registration functions from the URL below and retry: `r`nhttps://github.com/Azure/AzureStack-Tools/blob/registration/v1710/Registration/RegisterWithAzure.psm1`r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+ "180106"
+ {
+ Log-Warning -Message "Running a newer version of registration with an older version of Azure Stack. Registration version: $registrationVersion Build version: $versionNumber"
+ Log-Throw -Message "Please download the correct version of the registration functions from the URL below and retry: `r`nhttps://github.com/Azure/AzureStack-Tools/blob/registration/v1712/Registration/RegisterWithAzure.psm1`r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+ }
+ }
+ elseif (($versionNumber.Build -gt "180106") -and ($versionNumber.Build -lt $registrationVersion))
+ {
+ Log-Warning -Message "Running a newer version of registration with an older version of Azure Stack. Registration version: $registrationVersion Build version: $versionNumber"
+ Log-Throw -Message "Please download the correct version of the registration functions from the URL below and retry: `r`nhttps://github.com/Azure/AzureStack-Tools/blob/registration/v1803/Registration/RegisterWithAzure.psm1`r`n" -CallingFunction $PSCmdlet.MyInvocation.MyCommand.Name
+ }
+
+ Log-Output -Message "Running registration actions on build $($stampInfo.StampVersion). Cloud Id: $($stampInfo.CloudID), Deployment Id: $($stampInfo.DeploymentID)"
+ return $stampInfo
}
<#
@@ -1611,7 +1725,7 @@ function Log-Output{
[object] $Message
)
- "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message" | Out-File $AzureRegistrationLog -Append
+ "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message" | Out-File $Script:registrationLog -Append
Write-Verbose "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message"
}
@@ -1631,7 +1745,7 @@ function Log-Warning{
# Write Error: line seperately otherwise out message will not contain stack trace
Log-Output "*** WARNING ***"
- "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message" | Out-File $AzureRegistrationLog -Append
+ "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message" | Out-File $Script:registrationLog -Append
Write-Warning "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $Message"
Log-Output "*** End WARNING ***"
}
@@ -1650,22 +1764,36 @@ function Log-Throw{
[Object] $Message,
[Parameter(Mandatory=$true)]
- [String] $CallingFunction
+ [String] $CallingFunction,
+
+ [Parameter(Mandatory=$false)]
+ [PSObject] $ExceptionObject
)
$errorLine = "************************ Error ************************"
# Write Error line seperately otherwise out message will not contain stack trace
- "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $errorLine" | Out-File $AzureRegistrationLog -Append
+ "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $errorLine" | Out-File $Script:registrationLog -Append
Write-Verbose "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): $errorLine"
Log-Output $Message
- Log-Output $Message.ScriptStacktrace
+ if ($Message.ScriptStacktrace)
+ {
+ Log-Output $Message.ScriptStacktrace
+ }
+
+ if ($ExceptionObject)
+ {
+ for ($exCount = 0; $exCount -lt $ExceptionObject.Count; $exCount++)
+ {
+ Log-Output "Exception #$exCount`: $($ExceptionObject[$exCount])"
+ }
+ }
Log-OutPut "*********************** Ending registration action during $CallingFunction ***********************`r`n"
- "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): Logs can be found at: $AzureRegistrationLog and \\$PrivilegedEndpoint\c$\maslogs `r`n" | Out-File $AzureRegistrationLog -Append
- Write-Verbose "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): Logs can be found at: $AzureRegistrationLog and \\$PrivilegedEndpoint\c$\maslogs `r`n"
+ "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): Logs can be found at: $Script:registrationLog and \\$PrivilegedEndpoint\c$\maslogs `r`n" | Out-File $Script:registrationLog -Append
+ Write-Verbose "$(Get-Date -Format yyyy-MM-dd.hh-mm-ss): Logs can be found at: $Script:registrationLog and \\$PrivilegedEndpoint\c$\maslogs `r`n"
throw $Message
}
diff --git a/Registration/RegistrationUtilities.psm1 b/Registration/RegistrationUtilities.psm1
new file mode 100644
index 00000000..c942d636
--- /dev/null
+++ b/Registration/RegistrationUtilities.psm1
@@ -0,0 +1,221 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# See LICENSE.txt in the project root for license information.
+
+<#
+
+This module contains utility functions for working with registration resources
+#>
+
+
+<#
+
+.SYNOPSIS
+
+Uses the current Azure Powershell context to retrieve registration resources in Azure from the default resource group
+and with the default resource name (if $AzureStackStampCloudId is provided)
+
+#>
+function Get-AzureRegistrationResource{
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $false)]
+ [String] $AzureStackStampCloudId,
+
+ [Parameter(Mandatory = $false)]
+ [String] $ResourceGroupName = "AzureStack",
+
+ [Parameter(Mandatory = $false)]
+ [String] $ResourceName = "AzureStack"
+)
+
+$VerbosePreference = "Continue"
+$ErrorActionPreference = "Stop"
+
+Write-Verbose "Searching for registration resource using the provided parameters"
+$registrationResources = Find-AzureRmResource -ResourceNameContains $ResourceName -ResourceType 'Microsoft.AzureStack/registrations' -ResourceGroupNameEquals $ResourceGroupName
+$registrations = @()
+foreach ($resource in $registrationResources)
+{
+ $resource = Get-AzureRmResource -ResourceId $resource.ResourceId
+ if($AzureStackStampCloudId)
+ {
+ if ($resource.Properties.CloudId -eq $AzureStackStampCloudId)
+ {
+ Write-Verbose "Registration resource found:`r`n$(ConvertTo-Json $resource)"
+ return $resource
+ }
+ }
+ else
+ {
+ $registrations += $resource
+ }
+}
+
+if ($registrations.Count -gt 0)
+{
+ Write-Verbose "Registrations: $registrations"
+}
+else
+{
+ Write-Verbose "Registration resource(s) could not be located with the provided parameters."
+}
+
+
+}
+
+
+<#
+
+.SYNOPSIS
+
+If the context is set to the Azure Stack environment administrator this will retrieve the activation record in the Azure Stack
+if it has been created via successful registration run.
+
+#>
+function Get-AzureStackActivationRecord{
+
+$currentContext = Get-AzureRmContext
+$contextDetails = @{
+ Account = $currentContext.Account
+ Environment = $currentContext.Environment
+ Subscription = $currentContext.Subscription
+ Tenant = $currentContext.Tenant
+}
+
+if (-not($currentContext.Subscription))
+{
+ Write-Verbose "Current Azure context:`r`n$(ConvertTo-Json $ContextDetails)"
+ Throw "Current Azure context is not currently set. Please call Login-AzureRmAccount to set the Powershell context to Azure Stack service administrator."
+}
+
+$subscriptions = Get-AzureRmSubscription
+if ($subscriptions.Count -eq 1)
+{
+ if ($subscriptions.Name -eq 'Default Provider Subscription')
+ {
+ try
+ {
+ $activation = Get-AzureRmResource -ResourceId "/subscriptions/$($subscriptions.Id)/resourceGroups/azurestack-activation/providers/Microsoft.AzureBridge.Admin/activations/default"
+ return $activation
+ }
+ catch
+ {
+ Write-Warning "Activation record not found. Please register your Azure Stack with Azure: `r`nhttps://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-register`r`n$_"
+ }
+ }
+ else
+ {
+ Write-Warning "Unable to retrieve activation record using the current Azure Powershell context."
+ }
+}
+else
+{
+ foreach ($sub in $subscriptions)
+ {
+ try
+ {
+ Get-AzureRmResource -ResourceId "/subscriptions/$($sub.Id)/resourceGroups/azurestack-activation/providers/Microsoft.AzureBridge.Admin/activations/default"
+ }
+ catch
+ {
+ Write-Warning "Activation record not found. $_"
+ }
+ }
+}
+
+
+}
+
+
+<#
+
+.SYNOPSIS
+
+Sets the current azure powershell context to that of the Azure Stack environment administrator
+
+#>
+function Set-AzureStackPowershellContext{
+[CmdletBinding()]
+param(
+ [Parameter(Mandatory = $true)]
+ [String] $ServiceAdminUsername,
+
+ [Parameter(Mandatory = $true)]
+ [String] $ServiceAdminPassword,
+
+ [Parameter(Mandatory = $true)]
+ [String] $ExternalDomain,
+
+ [Parameter(Mandatory = $true)]
+ [String] $ArmEndpoint,
+
+ [Parameter(Mandatory = $false)]
+ [String] $AadTenantId
+)
+
+
+
+ $endpoints = Get-ResourceManagerMetaDataEndpoints -ArmEndpoint $ArmEndpoint
+
+ $aadAuthorityEndpoint = $endpoints.authentication.loginEndpoint
+ $aadResource = $endpoints.authentication.audiences[0]
+ $galleryEndpoint =$endpoints.galleryEndpoint
+ $graphEndpoint = $endpoints.graphEndpoint
+
+ $azureEnvironmentParams = @{
+ Name = "AzureStack"
+ ActiveDirectoryEndpoint = $($aadAuthorityEndpoint.TrimEnd("/") + "/")
+ ActiveDirectoryServiceEndpointResourceId = $aadResource
+ ResourceManagerEndpoint = $ArmEndpoint
+ GalleryEndpoint = $galleryEndpoint
+ GraphEndpoint = $graphEndpoint
+ GraphAudience = $graphEndpoint
+ AzureKeyVaultDnsSuffix = "adminvault.$ExternalDomain".ToLowerInvariant()
+ EnableAdfsAuthentication = $aadAuthorityEndpoint.TrimEnd("/").EndsWith("/adfs", [System.StringComparison]::OrdinalIgnoreCase)
+ }
+
+ $environment = Add-AzureRmEnvironment @azureEnvironmentParams
+ $environment = Get-AzureRmEnvironment -Name "AzureStack"
+
+ $Credential = New-Object System.Management.Automation.PSCredential ($ServiceAdminUsername,(ConvertTo-SecureString -String $ServiceAdminPassword -AsPlainText -Force))
+
+ if ($AadTenantId)
+ {
+ Add-AzureRmAccount -Environment $environment -Credential $Credential -TenantId $AadTenantId
+ }
+ else
+ {
+ Add-AzureRmAccount -Environment $environment -Credential $Credential
+ }
+
+ $adminSubscription = Get-AzureRmSubscription -SubscriptionName "Default Provider Subscription"
+ Set-AzureRmContext -SubscriptionId $adminSubscription.SubscriptionId
+}
+
+################################################################
+# Helper Functions
+################################################################
+
+<#
+
+.SYNOPSIS
+
+Gets the resource manager endpoints for use in the Set-AzureStackPowershellContext function
+
+#>
+function Get-ResourceManagerMetaDataEndpoints{
+param
+(
+ [Parameter(Mandatory=$true)]
+ [String] $ArmEndpoint
+)
+
+$endpoints = Invoke-RestMethod -Method Get -Uri "$($ArmEndpoint.TrimEnd('/'))/metadata/endpoints?api-version=2015-01-01" -Verbose
+Write-Verbose -Message "Endpoints: $(ConvertTo-Json $endpoints)" -Verbose
+
+Write-Output $endpoints
+}
+
+Export-ModuleMember Get-AzureRegistrationResource
+Export-ModuleMember Get-AzureStackActivationRecord
+Export-ModuleMember Set-AzureStackPowershellContext
diff --git a/Syndication/AzureStack.MarketplaceSyndication.psm1 b/Syndication/AzureStack.MarketplaceSyndication.psm1
index 2225691c..ac418459 100644
--- a/Syndication/AzureStack.MarketplaceSyndication.psm1
+++ b/Syndication/AzureStack.MarketplaceSyndication.psm1
@@ -112,6 +112,21 @@ function Sync-AzSOfflineMarketplaceItem {
$intAnswer = $a.popup($productDetails.properties.description, `
0, "Legal Terms", 4)
If ($intAnswer -eq 6) {
+
+ #Output Parameters required for Import
+ $FileExists = Test-Path "$destination\$azpkgName.txt"
+ $DestinationCheck = Test-Path $destination
+ If ($DestinationCheck -eq $false) {
+ new-item -ItemType Directory -force $destination
+ }
+ else {}
+
+ If ($FileExists -eq $true) {Remove-Item "$destination\$azpkgName.txt" -force} else {
+ New-Item "$destination\$azpkgName.txt"
+ }
+ $productDetails.properties|select publisherIdentifier,offer,offerversion,sku |out-file "$destination\$azpkgName.txt" -Append
+
+
# download azpkg
$azpkgsource = $downloadDetails.galleryPackageBlobSasUri
$FileExists = Test-Path "$destination\$azpkgName.azpkg"
@@ -125,7 +140,23 @@ function Sync-AzSOfflineMarketplaceItem {
New-Item "$destination\$azpkgName.azpkg"
}
$azpkgdestination = "$destination\$azpkgName.azpkg"
- Start-BitsTransfer -source $azpkgsource -destination $azpkgdestination -Priority High
+
+ #Select Premium Download
+ $a = new-object -comobject wscript.shell
+ $intAnswer = $a.popup("Would yuu like to use Premium download? This requires Azure Storage Tools to be installed", `
+ 0, "Premium Download", 4)
+ If ($intAnswer -eq 6) {
+ ($checktool= test-path 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' )
+ If ($checktool -eq $true){
+ & 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' /Source:$azpkgsource /Dest:$azpkgdestination /Y
+ }
+ else{
+ $a.popup("Please install Azure Storage Tools first, canceling")
+ }
+
+ } else {
+ {(New-Object System.Net.WebClient).DownloadFile("$azpkgsource",$azpkgdestination) }
+ }
switch ($downloadDetails.productKind) {
'virtualMachine' {
@@ -139,8 +170,20 @@ function Sync-AzSOfflineMarketplaceItem {
New-Item "$destination\$vhdName.vhd"
}
$vhdDestination = "$destination\$vhdName.vhd"
-
- Start-BitsTransfer -source $vhdSource -destination $vhdDestination -Priority High
+
+ #Select Premium Download
+ $a = new-object -comobject wscript.shell
+ $intAnswer = $a.popup("Would yuu like to use Premium download? This requires Azure Storage Tools to be installed", `
+ 0, "Premium Download", 4)
+ If ($intAnswer -eq 6) {
+ ($checktool= test-path 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' )
+ If ($checktool -eq $true){
+ & 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' /Source:$vhdsource /Dest:$vhddestination /Y
+ }
+ else{
+ $a.popup("Please install Azure Storage Tools first,canceling")
+ }
+ }else{(New-Object System.Net.WebClient).DownloadFile("$vhdsource",$vhddestination) }
}
}
'virtualMachineExtension' {
@@ -153,8 +196,19 @@ function Sync-AzSOfflineMarketplaceItem {
New-Item "$destination\$zipName.zip"
}
$zipDestination = "$destination\$zipName.zip"
-
- Start-BitsTransfer -source $zipsource -destination $zipDestination -Priority High
+ #Select Premium Download
+ $a = new-object -comobject wscript.shell
+ $intAnswer = $a.popup("Would yuu like to use Premium download? This requires Azure Storage Tools to be installed", `
+ 0, "Premium Download", 4)
+ If ($intAnswer -eq 6) {
+ ($checktool= test-path 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' )
+ If ($checktool -eq $true){
+ & 'C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\AzCopy.exe' /Source:$zipsource /Dest:$zipdestination /Y
+ }
+ else{
+ $a.popup("Please install Azure Storage Tools first,canceling")
+ }
+ }else{(New-Object System.Net.WebClient).DownloadFile("$zipsource",$zipdestination)}
}
}
diff --git a/Syndication/readme.md b/Syndication/readme.md
index 78293716..380a5b11 100644
--- a/Syndication/readme.md
+++ b/Syndication/readme.md
@@ -5,7 +5,7 @@ not use the build in portal feature to syndicate Azure Market place items and ma
available to your users.
This Tool allows you to download Azure Marketplace Items with a machine that has internet connectivity and side load them.
-The downloaded needs to transferred to machine with has connectivity to the Azure Stack deployment and imported.
+The downloaded items need to be transferred to a machine with has connectivity to the Azure Stack deployment before importing them.
![](demosyndicate.gif)
@@ -14,9 +14,13 @@ The downloaded needs to transferred to machine with has connectivity to the Azur
- Azure Stack RP registered within your Azure Subscription
- Azure Subscription used to register Azure Stack System (Multi Node or ASDK)
-- AzureRM 1.2.11 PowerShell needs to be installed
+- AzureStack 1.3.0 PowerShell needs to be installed
+
+(https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-install)
+
+- Optional: For best download performance (Premium Download) Azure Storage Tools are required
+(http://aka.ms/downloadazcopy)
-(https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-configure-quickstart)
## Import the Module