From 0414268d490b6e995e73f9236337373cbb19f97c Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Wed, 3 Dec 2025 14:35:07 +0100 Subject: [PATCH 01/11] enable shared key access to storage account --- ...mplate - SQL Hackathon - Network - v2.json | 303 +++++++++--------- 1 file changed, 152 insertions(+), 151 deletions(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json index 3aca771..6200cb5 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json @@ -1,151 +1,152 @@ -{ - - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - - "contentVersion": "1.0.0.0", - - "variables": { - "location": "[resourceGroup().location]", - "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", - "storageAccountName": "[concat('sqlhacksa', uniqueString(resourceGroup().id))]", - "uniquevaluerg":"[uniqueString(resourceGroup().id)]", - "addressPrefix": "10.0.0.0/16", - "MIsubnetName": "ManagedInstance", - "MIsubnetPrefix": "10.0.1.0/24", - "GatewaySubnetName": "GatewaySubnet", - "GatewaySubnetPrefix": "10.0.0.0/24", - "ManagementSubnetName": "Management", - "ManagementSubnetPrefix": "10.0.2.0/24", - "TeamVMSubnetName": "TeamJumpServers", - "TeamVMSubnetPrefix": "10.0.3.0/24", - "BastionSubnetName": "AzureBastionSubnet", - "BastionSubnetPrefix":"10.0.4.0/24" - }, - "outputs": { - "UniqueRgValue": { - "type": "string", - "value": "[variables('uniquevaluerg')]" - } - }, - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2019-04-01", - "name": "[variables('storageAccountName')]", - "location": "[variables('location')]", - "sku": { - "name": "Standard_LRS", - "tier": "Standard" - }, - "kind": "StorageV2", - "properties": { - "networkAcls": { - "bypass": "AzureServices", - "virtualNetworkRules": [], - "ipRules": [], - "defaultAction": "Allow" - }, - "supportsHttpsTrafficOnly": true, - "minimumTlsVersion": "TLS1_0", - "encryption": { - "services": { - "file": { - "enabled": true - }, - "blob": { - "enabled": true - } - }, - "keySource": "Microsoft.Storage" - }, - "accessTier": "Hot" - } - }, - { - - "name": "[variables('virtualNetworkName')]", - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2019-04-01", - "location": "[variables('location')]", - "dependsOn": [], - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - - { - "name": "[variables('gatewaySubnetName')]", - "properties": { - "addressPrefix": "[variables('gatewaySubnetPrefix')]" - } - }, - { - "name": "[variables('MIsubnetName')]", - "properties": { - "addressPrefix": "[variables('MIsubnetPrefix')]" - } - }, - { - "name": "[variables('managementSubnetName')]", - "properties": { - "addressPrefix": "[variables('managementSubnetPrefix')]" - } - }, - { - "name": "[variables('TeamVMSubnetName')]", - "properties": { - "addressPrefix": "[variables('TeamVMSubnetPrefix')]" - } - }, - { - "name": "[variables('BastionSubnetName')]", - "properties": { - "addressPrefix": "[variables('BastionSubnetPrefix')]" - } - } - ] - } - }, - { - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2020-11-01", - "name": "BastionPublicIP", - "location": "[variables('location')]", - "sku": { - "name": "Standard" - }, - "properties": { - "publicIPAllocationMethod": "Static" - } - }, - { - "apiVersion": "2020-07-01", - "type": "Microsoft.Network/bastionHosts", - "name": "TEAM_VMs-BA", - "location": "[variables('location')]", - "dependsOn": [ - "[resourceId('Microsoft.Network/publicIpAddresses', 'BastionPublicIP')]", - "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - - ], - "properties": { - "ipConfigurations": [ - { - "name": "IpConf", - "properties": { - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('BastionSubnetName'))]" - }, - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIpAddresses', 'BastionPublicIP')]" - } - } - } - ] - } - } - ] -} +{ + + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + + "contentVersion": "1.0.0.0", + + "variables": { + "location": "[resourceGroup().location]", + "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", + "storageAccountName": "[concat('sqlhacksa', uniqueString(resourceGroup().id))]", + "uniquevaluerg":"[uniqueString(resourceGroup().id)]", + "addressPrefix": "10.0.0.0/16", + "MIsubnetName": "ManagedInstance", + "MIsubnetPrefix": "10.0.1.0/24", + "GatewaySubnetName": "GatewaySubnet", + "GatewaySubnetPrefix": "10.0.0.0/24", + "ManagementSubnetName": "Management", + "ManagementSubnetPrefix": "10.0.2.0/24", + "TeamVMSubnetName": "TeamJumpServers", + "TeamVMSubnetPrefix": "10.0.3.0/24", + "BastionSubnetName": "AzureBastionSubnet", + "BastionSubnetPrefix":"10.0.4.0/24" + }, + "outputs": { + "UniqueRgValue": { + "type": "string", + "value": "[variables('uniquevaluerg')]" + } + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2019-04-01", + "name": "[variables('storageAccountName')]", + "location": "[variables('location')]", + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "StorageV2", + "properties": { + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + }, + "supportsHttpsTrafficOnly": true, + "minimumTlsVersion": "TLS1_0", + "encryption": { + "services": { + "file": { + "enabled": true + }, + "blob": { + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + }, + "accessTier": "Hot", + "allowSharedKeyAccess": true + } + }, + { + + "name": "[variables('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2019-04-01", + "location": "[variables('location')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + + { + "name": "[variables('gatewaySubnetName')]", + "properties": { + "addressPrefix": "[variables('gatewaySubnetPrefix')]" + } + }, + { + "name": "[variables('MIsubnetName')]", + "properties": { + "addressPrefix": "[variables('MIsubnetPrefix')]" + } + }, + { + "name": "[variables('managementSubnetName')]", + "properties": { + "addressPrefix": "[variables('managementSubnetPrefix')]" + } + }, + { + "name": "[variables('TeamVMSubnetName')]", + "properties": { + "addressPrefix": "[variables('TeamVMSubnetPrefix')]" + } + }, + { + "name": "[variables('BastionSubnetName')]", + "properties": { + "addressPrefix": "[variables('BastionSubnetPrefix')]" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2020-11-01", + "name": "BastionPublicIP", + "location": "[variables('location')]", + "sku": { + "name": "Standard" + }, + "properties": { + "publicIPAllocationMethod": "Static" + } + }, + { + "apiVersion": "2020-07-01", + "type": "Microsoft.Network/bastionHosts", + "name": "TEAM_VMs-BA", + "location": "[variables('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIpAddresses', 'BastionPublicIP')]", + "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + + ], + "properties": { + "ipConfigurations": [ + { + "name": "IpConf", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('BastionSubnetName'))]" + }, + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIpAddresses', 'BastionPublicIP')]" + } + } + } + ] + } + } + ] +} From 23d9ff6acc8d19b7bacbefaae43e72d539cc58da Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Wed, 3 Dec 2025 14:35:37 +0100 Subject: [PATCH 02/11] add SecurityControl tag to storage account --- .../ARM Template - SQL Hackathon - Network - v2.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json index 6200cb5..ed2d7f3 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json @@ -38,6 +38,9 @@ "tier": "Standard" }, "kind": "StorageV2", + "tags": { + "SecurityControl": "Ignore" + }, "properties": { "networkAcls": { "bypass": "AzureServices", From 16da0a1549091dfafbb97a39c1ad1c72e3268349 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Fri, 5 Dec 2025 10:05:47 +0100 Subject: [PATCH 03/11] move public IP SKU to standard --- ...e - SQL Hackathon - Jump Servers - v2.json | 494 +++++++++--------- 1 file changed, 247 insertions(+), 247 deletions(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json index 77ea603..155880c 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json @@ -1,248 +1,248 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.1", - "parameters": { - "vmCount": - { - "type": "int", - "defaultvalue": 2, - "metadata": { - "description": "Select the number of TEAM Virtual Jump boxes to add." - } - }, - "adminUsername": { - "defaultValue": "DemoUser", - "type": "string", - "metadata": { - "description": "Administrator user name for logging into the virtual machine and SQL MI." - } - }, - "adminPassword": { - "type": "securestring", - "metadata": { - "description": "The password must be between 16 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter. Default value is Password.1234567890" - } - }, - "SharedResourceGroup": { - "defaultValue": "SQLHACK-SHARED", - "type": "string", - "metadata": { - "description": "The Shared Resource Group" - } - }, - "SASURIKey": { - "defaultValue": "SQLHACK-SHARED", - "type": "string", - "maxLength": 256, - "metadata": { - "description": "The SASURI for the hack" - } - }, - "StorageAccount": { - "type": "string", - "maxLength": 128, - "metadata": { - "description": "The sa the hack" - } - } - }, - "variables": { - "location": "[resourceGroup().location]", - "virtualMachineSize": "Standard_D2s_v3", - "jbVirtualMachineName": "vm-TEAM", - "jbNetworkSecurityGroupName": "[concat('nsg-',variables('jbVirtualMachineName'))]", - "jbNetworkInterfaceName": "[concat( 'nic-', variables('jbVirtualMachineName'))]", - "jbPublicIpAddressName": "[concat( 'ip-', variables('jbVirtualMachineName'))]", - "virtualNetworkName": "[concat(parameters('SharedResourceGroup'), '-vnet')]", - "jbCustomScriptFileName": "Powershell/ARM_Deployment-TEAM_VM_Build_RC4.ps1", - "jbCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('jbCustomScriptFileName'))]", - "managementSubnetName": "TeamJumpServers" - }, - - "resources": [ - { - "copy": { - "name": "nodeCopy", - "count": "[parameters('vmCount')]" - }, - "name": "[concat(variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2019-03-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', concat(variables('jbNetworkInterfaceName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - ], - "properties": { - "hardwareProfile": { - "vmSize": "[variables('virtualMachineSize')]" - }, - "storageProfile": { - "osDisk": { - "name" : "[concat('OsDisk_1_',concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", - "createOption": "fromImage", - "managedDisk": { - "storageAccountType": "StandardSSD_LRS" - } - }, - "imageReference": { - "publisher": "MicrosoftWindowsDesktop", - "offer": "Windows-10", - "sku": "win10-22h2-pro-g2", - "version": "latest" - } - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('jbNetworkInterfaceName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - } - ] - }, - "osProfile": { - "computerName": "[variables('jbVirtualMachineName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": true, - "provisionVmAgent": true - } - }, - "licenseType": "Windows_Client" - }, - "resources": [ - { - "name": "SetupJumpBox", - "apiVersion": "2019-03-01", - "type": "extensions", - "location": "[variables('location')]", - "properties": { - "publisher": "Microsoft.Compute", - "type": "CustomScriptExtension", - "typeHandlerVersion": "1.9", - "autoUpgradeMinorVersion": true, - "settings": { - "timestamp":123456761 - }, - "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('jbCustomScriptFileName'))]", - "storageAccountName": "[parameters('storageAccount')]", - "storageAccountKey": "[Concat(listKeys(resourceId(parameters('SharedResourceGroup'),'Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", - "fileUris": [ - "[variables('jbCustomScriptUri')]" - ] - } - }, - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - ], - "tags": { - "displayName": "SetupJumpBox" - } - } - ] - }, - { - "copy": { - "name": "NICCopy", - "count": "[parameters('vmCount')]" - }, - "name": "[concat(variables('jbNetworkInterfaceName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2019-04-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIpAddresses/', concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", - "[concat('Microsoft.Network/networkSecurityGroups/', concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - ], - "properties": { - "ipConfigurations": [ - { - "name": "[concat('ipconfig',if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "properties": { - "subnet": { - "id": "[resourceId(parameters('SharedResourceGroup'),'Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" - }, - "privateIPAllocationMethod": "Dynamic", - "publicIpAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - } - } - } - ], - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" - } - } - }, - { - "copy": { - "name": "IPCopy", - "count": "[parameters('vmCount')]" - }, - "name": "[concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2019-04-01", - "location": "[variables('location')]", - "properties": { - "publicIPAllocationMethod": "Static" - }, - "sku": { - "name": "Basic" - } - }, - { - "copy": { - "name": "NSGCopy", - "count": "[parameters('vmCount')]" - }, - "name": "[concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2019-06-01", - "location": "[variables('location')]", - "properties": { - "securityRules": [ - { - "name": "RDP", - "properties": { - "priority": 300, - "protocol": "Tcp", - "access": "Allow", - "direction": "Inbound", - "sourceApplicationSecurityGroups": [], - "destinationApplicationSecurityGroups": [], - "sourceAddressPrefix": "*", - "sourcePortRange": "*", - "destinationAddressPrefix": "*", - "destinationPortRange": "3389" - } - } - ] - } - }, - { - "copy": { - "name": "ShutdownCopy", - "count": "[parameters('vmCount')]" - }, - "name": "[concat('shutdown-computevm-', variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", - "type": "Microsoft.DevTestLab/schedules", - "apiVersion": "2017-04-26-preview", - "location": "[variables('location')]", - "dependsOn": [ - "[concat(variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]" - ], - "properties": { - "status": "Enabled", - "taskType": "ComputeVmShutdownTask", - "dailyRecurrence": { - "time": "19:00" - }, - "timeZoneId": "UTC", - "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", - "notificationSettings": { - "status": "Disabled" - } - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.1", + "parameters": { + "vmCount": + { + "type": "int", + "defaultvalue": 2, + "metadata": { + "description": "Select the number of TEAM Virtual Jump boxes to add." + } + }, + "adminUsername": { + "defaultValue": "DemoUser", + "type": "string", + "metadata": { + "description": "Administrator user name for logging into the virtual machine and SQL MI." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "The password must be between 16 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter. Default value is Password.1234567890" + } + }, + "SharedResourceGroup": { + "defaultValue": "SQLHACK-SHARED", + "type": "string", + "metadata": { + "description": "The Shared Resource Group" + } + }, + "SASURIKey": { + "defaultValue": "SQLHACK-SHARED", + "type": "string", + "maxLength": 256, + "metadata": { + "description": "The SASURI for the hack" + } + }, + "StorageAccount": { + "type": "string", + "maxLength": 128, + "metadata": { + "description": "The sa the hack" + } + } + }, + "variables": { + "location": "[resourceGroup().location]", + "virtualMachineSize": "Standard_D2s_v3", + "jbVirtualMachineName": "vm-TEAM", + "jbNetworkSecurityGroupName": "[concat('nsg-',variables('jbVirtualMachineName'))]", + "jbNetworkInterfaceName": "[concat( 'nic-', variables('jbVirtualMachineName'))]", + "jbPublicIpAddressName": "[concat( 'ip-', variables('jbVirtualMachineName'))]", + "virtualNetworkName": "[concat(parameters('SharedResourceGroup'), '-vnet')]", + "jbCustomScriptFileName": "Powershell/ARM_Deployment-TEAM_VM_Build_RC4.ps1", + "jbCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('jbCustomScriptFileName'))]", + "managementSubnetName": "TeamJumpServers" + }, + + "resources": [ + { + "copy": { + "name": "nodeCopy", + "count": "[parameters('vmCount')]" + }, + "name": "[concat(variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2019-03-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', concat(variables('jbNetworkInterfaceName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[variables('virtualMachineSize')]" + }, + "storageProfile": { + "osDisk": { + "name" : "[concat('OsDisk_1_',concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", + "createOption": "fromImage", + "managedDisk": { + "storageAccountType": "StandardSSD_LRS" + } + }, + "imageReference": { + "publisher": "MicrosoftWindowsDesktop", + "offer": "Windows-10", + "sku": "win10-22h2-pro-g2", + "version": "latest" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('jbNetworkInterfaceName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + } + ] + }, + "osProfile": { + "computerName": "[variables('jbVirtualMachineName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "enableAutomaticUpdates": true, + "provisionVmAgent": true + } + }, + "licenseType": "Windows_Client" + }, + "resources": [ + { + "name": "SetupJumpBox", + "apiVersion": "2019-03-01", + "type": "extensions", + "location": "[variables('location')]", + "properties": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "timestamp":123456761 + }, + "protectedSettings": { + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('jbCustomScriptFileName'))]", + "storageAccountName": "[parameters('storageAccount')]", + "storageAccountKey": "[Concat(listKeys(resourceId(parameters('SharedResourceGroup'),'Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", + "fileUris": [ + "[variables('jbCustomScriptUri')]" + ] + } + }, + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + ], + "tags": { + "displayName": "SetupJumpBox" + } + } + ] + }, + { + "copy": { + "name": "NICCopy", + "count": "[parameters('vmCount')]" + }, + "name": "[concat(variables('jbNetworkInterfaceName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2019-04-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIpAddresses/', concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", + "[concat('Microsoft.Network/networkSecurityGroups/', concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "[concat('ipconfig',if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "properties": { + "subnet": { + "id": "[resourceId(parameters('SharedResourceGroup'),'Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" + }, + "privateIPAllocationMethod": "Dynamic", + "publicIpAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]" + } + } + }, + { + "copy": { + "name": "IPCopy", + "count": "[parameters('vmCount')]" + }, + "name": "[concat(variables('jbPublicIpAddressName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2019-04-01", + "location": "[variables('location')]", + "properties": { + "publicIPAllocationMethod": "Static" + }, + "sku": { + "name": "Standard" + } + }, + { + "copy": { + "name": "NSGCopy", + "count": "[parameters('vmCount')]" + }, + "name": "[concat(variables('jbNetworkSecurityGroupName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-06-01", + "location": "[variables('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "priority": 300, + "protocol": "Tcp", + "access": "Allow", + "direction": "Inbound", + "sourceApplicationSecurityGroups": [], + "destinationApplicationSecurityGroups": [], + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*", + "destinationPortRange": "3389" + } + } + ] + } + }, + { + "copy": { + "name": "ShutdownCopy", + "count": "[parameters('vmCount')]" + }, + "name": "[concat('shutdown-computevm-', variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]", + "type": "Microsoft.DevTestLab/schedules", + "apiVersion": "2017-04-26-preview", + "location": "[variables('location')]", + "dependsOn": [ + "[concat(variables('jbVirtualMachineName'), if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1)))]" + ], + "properties": { + "status": "Enabled", + "taskType": "ComputeVmShutdownTask", + "dailyRecurrence": { + "time": "19:00" + }, + "timeZoneId": "UTC", + "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('jbVirtualMachineName'),if (less(copyIndex(1), 10), concat('0', copyIndex(1)), copyIndex(1))))]", + "notificationSettings": { + "status": "Disabled" + } + } + } + ] } \ No newline at end of file From 82a23fb81936d12bb265658be54eb46a29bff975 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Fri, 5 Dec 2025 10:35:29 +0100 Subject: [PATCH 04/11] move to D2s_v5 instances --- ...e - SQL Hackathon - Jump Servers - v2.json | 2 +- ...RM Template - SQL Hackathon - SQL2K12.json | 658 +++++++++--------- ...RM Template - SQL Hackathon - SQL2K16.json | 646 +++++++++-------- 3 files changed, 647 insertions(+), 659 deletions(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json index 155880c..2be360b 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json @@ -48,7 +48,7 @@ }, "variables": { "location": "[resourceGroup().location]", - "virtualMachineSize": "Standard_D2s_v3", + "virtualMachineSize": "Standard_D2s_v5", "jbVirtualMachineName": "vm-TEAM", "jbNetworkSecurityGroupName": "[concat('nsg-',variables('jbVirtualMachineName'))]", "jbNetworkInterfaceName": "[concat( 'nic-', variables('jbVirtualMachineName'))]", diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json index 9f090b2..922f4d5 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json @@ -1,333 +1,327 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.1", - "parameters": { - "adminUsername": { - "defaultValue": "DemoUser", - "type": "string", - "metadata": { - "description": "Administrator user name for logging into the virtual machine and SQL MI." - } - }, - "adminPassword": { - "type": "securestring", - "metadata": { - "description": "The password must be between 15 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter." - } - }, - "dbCount": - { - "type": "int", - "defaultvalue": 3, - "metadata": { - "description": "Select the number of db to add." - } - }, - "storageAccount": { - "type": "string", - "metadata": { - "description": "Storage account with source files for post deployment" - } - }, - "sasTokenBuildContainer": { - "type": "string", - "metadata": { - "description": "sas token" - } - }, - "sasTokenMigrationContainer": { - "type": "string", - "metadata": { - "description": "sas token" - } - } - - }, - "outputs": { - "resourceID": { - "type": "string", - "value": "[variables('sqlVirtualMachineName')]" - }, - "scriptpath": { - "type": "string", - "value": "[variables('sqlCustomScriptUri')]" - } - }, - "variables": { - "location": "[resourceGroup().location]", - "SQLlMachineSize": "Standard_DS3_v2", - "sqlVirtualMachineName": "legacysql2012", - "sqlNetworkSecurityGroupName": "[concat(variables('sqlVirtualMachineName'), '-nsg')]", - "sqlNetworkInterfaceName": "[concat(variables('sqlVirtualMachineName'), '-nic')]", - "sqlPublicIpAddressName": "[concat(variables('sqlVirtualMachineName'), '-ip')]", - "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", - "managementSubnetName": "Management", - "sqlCustomScriptFileName": "Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1", - "sqlCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('sqlCustomScriptFileName'))]", - "dataPath": "F:\\data", - "sqlStorageDisksCount": { - "value": 1 - }, - "sqlStorageWorkloadType": "OLTP", - "sqlStorageDisksConfigurationType": "NEW", - "sqlStorageStartingDeviceId": 2, - "dataDisksLUNs": { - "value": [ - 0 - ] - }, - "logPath": "F:\\log", - "logDisksLUNs": { - "value": [ - 0 - ] - }, - "tempDbPath": "D:\\tempDb", - "dataFileCount": 2, - "dataFileSize":8 , - "dataGrowth":64, - "logFileSize": 8, - "logGrowth": 64, - "SQLSystemDbOnDataDisk": false - - }, - "resources": [ - { - "name": "[variables('sqlNetworkInterfaceName')]", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2019-04-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkSecurityGroups/', variables('sqlNetworkSecurityGroupName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig1", - "properties": { - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" - }, - "privateIPAllocationMethod": "Dynamic" - } - } - ], - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('sqlNetworkSecurityGroupName'))]" - } - } - }, - { - "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", - "type": "Microsoft.Compute/disks", - "apiVersion": "2022-03-02", - "location": "[variables('location')]", - "properties": { - "diskSizeGB": 64, - "creationData": { - "createOption": "empty" - } - }, - "sku": { - "name": "Premium_LRS", - "tier": "Premium" - } - }, - { "name": "[variables('sqlVirtualMachineName')]", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2019-03-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('sqlNetworkInterfaceName'))]" - ], - "properties": { - "hardwareProfile": { - "vmSize": "[variables('SQLlMachineSize')]" - }, - "storageProfile": { - "osDisk": { - "createOption": "FromImage", - "name": "[concat(variables('sqlVirtualMachineName'), '_disk1_OS')]", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - }, - "imageReference": { - "publisher": "MicrosoftSQLServer", - "offer": "SQL2012SP4-WS2012R2", - "sku": "enterprise", - "version": "latest" - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "attach", - "caching": "ReadOnly", - "writeAcceleratorEnabled": false, - "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", - "managedDisk": { - "id": "[resourceId('Microsoft.Compute/disks/', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" - } - } - ] - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('sqlNetworkInterfaceName'))]" - } - ] - }, - "osProfile": { - "computerName": "[variables('sqlVirtualMachineName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": true, - "provisionVmAgent": true - } - }, - "licenseType": "Windows_Server", - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - } - } - }, - { - "name": "[concat('shutdown-computevm-', variables('sqlVirtualMachineName'))]", - "type": "Microsoft.DevTestLab/schedules", - "apiVersion": "2017-04-26-preview", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]" - ], - "properties": { - "status": "Enabled", - "taskType": "ComputeVmShutdownTask", - "dailyRecurrence": { - "time": "19:00" - }, - "timeZoneId": "UTC", - "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", - "notificationSettings": { - "status": "Disabled" - } - } - }, - { - "name": "[variables('sqlVirtualMachineName')]", - "type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines", - "apiVersion": "2021-11-01-preview", - "location": "[variables('location')]", - "properties": { - "virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", - "sqlManagement": "Full", - "SqlServerLicenseType": "AHUB", - "AutoPatchingSettings": { - "Enable": true, - "DayOfWeek":"Sunday", - "MaintenanceWindowStartingHour": "2", - "MaintenanceWindowDuration": "60" - }, - "KeyVaultCredentialSettings": { - "Enable": false, - "CredentialName": "" - }, - "ServerConfigurationsManagementSettings": { - "SQLConnectivityUpdateSettings": { - "ConnectivityType": "Private", - "Port": "1433", - "SQLAuthUpdateUserName": "[parameters('adminUsername')]", - "SQLAuthUpdatePassword": "[parameters('adminPassword')]" - }, - "AdditionalFeaturesServerConfigurations": { - "IsRServicesEnabled": "false" - } - }, - "StorageConfigurationSettings": { - "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]", - "StorageWorkloadType": "[variables('sqlStorageWorkloadType')]", - - "SQLDataSettings": { - "LUNs": [0], - "DefaultFilePath": "[variables('dataPath')]" - }, - "SQLLogSettings": { - "LUNs": [0], - "DefaultFilePath": "[variables('logPath')]" - }, - "SQLTempDbSettings": { - "DefaultFilePath": "[variables('tempDbPath')]", - "DataFileCount": "[variables('dataFileCount')]", - "DataFileSize": "[variables('dataFileSize')]", - "DataGrowth": "[variables('dataGrowth')]", - "LogFileSize": "[variables('logFileSize')]", - "LogGrowth": "[variables('logGrowth')]" - }, - "SQLSystemDbOnDataDisk": "[variables('SQLSystemDbOnDataDisk')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines',variables('sqlVirtualMachineName'))]" - ] - }, - { - "name": "[concat( variables('sqlVirtualMachineName'),'/SetupSqlVm')]", - "apiVersion": "2019-03-01", - "type": "Microsoft.Compute/virtualMachines/extensions", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]", - "[concat('Microsoft.SqlVirtualMachine/SqlVirtualMachines/', variables('sqlVirtualMachineName'))]" - ], - "properties": { - "publisher": "Microsoft.Compute", - "type": "CustomScriptExtension", - "typeHandlerVersion": "1.10", - "autoUpgradeMinorVersion": true, - "settings": { - "timestamp":123456783 - }, - "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasTokenBuildContainer ', parameters('sasTokenBuildContainer'),' -sasTokenMigrationContainer ', parameters('sasTokenMigrationContainer'),' -dbCount ', parameters('dbCount'))]" , - "storageAccountName": "[parameters('storageAccount')]", - "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", - "fileUris": [ - "[variables('sqlCustomScriptUri')]" - ] - } - - }, - "tags": { - "displayName": "SetupSqlVm" - } - }, - { - "name": "[variables('sqlNetworkSecurityGroupName')]", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2019-06-01", - "location": "[variables('location')]", - "properties": { - "securityRules": [ - { - "name": "RDP", - "properties": { - "priority": 300, - "protocol": "Tcp", - "access": "Allow", - "direction": "Inbound", - "sourceApplicationSecurityGroups": [], - "destinationApplicationSecurityGroups": [], - "sourceAddressPrefix": "*", - "sourcePortRange": "*", - "destinationAddressPrefix": "*", - "destinationPortRange": "3389" - } - } - ] - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.1", + "parameters": { + "adminUsername": { + "defaultValue": "DemoUser", + "type": "string", + "metadata": { + "description": "Administrator user name for logging into the virtual machine and SQL MI." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "The password must be between 15 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter." + } + }, + "dbCount": + { + "type": "int", + "defaultvalue": 3, + "metadata": { + "description": "Select the number of db to add." + } + }, + "storageAccount": { + "type": "string", + "metadata": { + "description": "Storage account with source files for post deployment" + } + }, + "sasTokenBuildContainer": { + "type": "string", + "metadata": { + "description": "sas token" + } + }, + "sasTokenMigrationContainer": { + "type": "string", + "metadata": { + "description": "sas token" + } + } + + }, + "outputs": { + "resourceID": { + "type": "string", + "value": "[variables('sqlVirtualMachineName')]" + }, + "scriptpath": { + "type": "string", + "value": "[variables('sqlCustomScriptUri')]" + } + }, + "variables": { + "location": "[resourceGroup().location]", + "SQLlMachineSize": "Standard_D2s_v5", + "sqlVirtualMachineName": "legacysql2012", + "sqlNetworkSecurityGroupName": "[concat(variables('sqlVirtualMachineName'), '-nsg')]", + "sqlNetworkInterfaceName": "[concat(variables('sqlVirtualMachineName'), '-nic')]", + "sqlPublicIpAddressName": "[concat(variables('sqlVirtualMachineName'), '-ip')]", + "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", + "managementSubnetName": "Management", + "sqlCustomScriptFileName": "Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1", + "sqlCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('sqlCustomScriptFileName'))]", + "dataPath": "F:\\data", + "sqlStorageDisksCount": { + "value": 1 + }, + "sqlStorageWorkloadType": "OLTP", + "sqlStorageDisksConfigurationType": "NEW", + "sqlStorageStartingDeviceId": 2, + "dataDisksLUNs": [0], + "logPath": "F:\\log", + "logDisksLUNs": [0], + "tempDbPath": "F:\\tempDb", + "tempDbDisksLUNs": [0], + "dataFileCount": 2, + "dataFileSize": 8, + "dataGrowth": 64, + "logFileSize": 8, + "logGrowth": 64, + "SQLSystemDbOnDataDisk": false + }, + "resources": [ + { + "name": "[variables('sqlNetworkInterfaceName')]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2019-04-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', variables('sqlNetworkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" + }, + "privateIPAllocationMethod": "Dynamic" + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('sqlNetworkSecurityGroupName'))]" + } + } + }, + { + "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", + "type": "Microsoft.Compute/disks", + "apiVersion": "2022-03-02", + "location": "[variables('location')]", + "properties": { + "diskSizeGB": 128, + "creationData": { + "createOption": "empty" + } + }, + "sku": { + "name": "Premium_LRS", + "tier": "Premium" + } + }, + { "name": "[variables('sqlVirtualMachineName')]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2019-03-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('sqlNetworkInterfaceName'))]", + "[resourceId('Microsoft.Compute/disks', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[variables('SQLlMachineSize')]" + }, + "storageProfile": { + "osDisk": { + "createOption": "FromImage", + "name": "[concat(variables('sqlVirtualMachineName'), '_disk1_OS')]", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + "imageReference": { + "publisher": "MicrosoftSQLServer", + "offer": "SQL2012SP4-WS2012R2", + "sku": "enterprise", + "version": "latest" + }, + "dataDisks": [ + { + "lun": 0, + "createOption": "attach", + "caching": "None", + "writeAcceleratorEnabled": false, + "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", + "managedDisk": { + "id": "[resourceId('Microsoft.Compute/disks/', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" + } + } + ] + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('sqlNetworkInterfaceName'))]" + } + ] + }, + "osProfile": { + "computerName": "[variables('sqlVirtualMachineName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "enableAutomaticUpdates": true, + "provisionVmAgent": true + } + }, + "licenseType": "Windows_Server", + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + } + } + }, + { + "name": "[concat('shutdown-computevm-', variables('sqlVirtualMachineName'))]", + "type": "Microsoft.DevTestLab/schedules", + "apiVersion": "2017-04-26-preview", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]" + ], + "properties": { + "status": "Enabled", + "taskType": "ComputeVmShutdownTask", + "dailyRecurrence": { + "time": "19:00" + }, + "timeZoneId": "UTC", + "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", + "notificationSettings": { + "status": "Disabled" + } + } + }, + { + "name": "[variables('sqlVirtualMachineName')]", + "type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines", + "apiVersion": "2021-11-01-preview", + "location": "[variables('location')]", + "properties": { + "virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", + "sqlManagement": "Full", + "SqlServerLicenseType": "AHUB", + "AutoPatchingSettings": { + "Enable": true, + "DayOfWeek":"Sunday", + "MaintenanceWindowStartingHour": "2", + "MaintenanceWindowDuration": "60" + }, + "KeyVaultCredentialSettings": { + "Enable": false, + "CredentialName": "" + }, + "ServerConfigurationsManagementSettings": { + "SQLConnectivityUpdateSettings": { + "ConnectivityType": "Private", + "Port": "1433", + "SQLAuthUpdateUserName": "[parameters('adminUsername')]", + "SQLAuthUpdatePassword": "[parameters('adminPassword')]" + }, + "AdditionalFeaturesServerConfigurations": { + "IsRServicesEnabled": "false" + } + }, + "StorageConfigurationSettings": { + "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]", + "StorageWorkloadType": "[variables('sqlStorageWorkloadType')]", + + "SQLDataSettings": { + "LUNs": "[variables('dataDisksLUNs')]", + "DefaultFilePath": "[variables('dataPath')]" + }, + "SQLLogSettings": { + "LUNs": "[variables('logDisksLUNs')]", + "DefaultFilePath": "[variables('logPath')]" + }, + "SQLTempDbSettings": { + "LUNs": "[variables('tempDbDisksLUNs')]", + "DefaultFilePath": "[variables('tempDbPath')]", + "DataFileCount": "[variables('dataFileCount')]", + "DataFileSize": "[variables('dataFileSize')]", + "DataGrowth": "[variables('dataGrowth')]", + "LogFileSize": "[variables('logFileSize')]", + "LogGrowth": "[variables('logGrowth')]" + }, + "SQLSystemDbOnDataDisk": "[variables('SQLSystemDbOnDataDisk')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines',variables('sqlVirtualMachineName'))]" + ] + }, + { + "name": "[concat( variables('sqlVirtualMachineName'),'/SetupSqlVm')]", + "apiVersion": "2019-03-01", + "type": "Microsoft.Compute/virtualMachines/extensions", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]", + "[concat('Microsoft.SqlVirtualMachine/SqlVirtualMachines/', variables('sqlVirtualMachineName'))]" + ], + "properties": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.10", + "autoUpgradeMinorVersion": true, + "settings": { + "timestamp":123456783 + }, + "protectedSettings": { + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasTokenBuildContainer ', parameters('sasTokenBuildContainer'),' -sasTokenMigrationContainer ', parameters('sasTokenMigrationContainer'),' -dbCount ', parameters('dbCount'))]" , + "storageAccountName": "[parameters('storageAccount')]", + "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", + "fileUris": [ + "[variables('sqlCustomScriptUri')]" + ] + } + + }, + "tags": { + "displayName": "SetupSqlVm" + } + }, + { + "name": "[variables('sqlNetworkSecurityGroupName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-06-01", + "location": "[variables('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "priority": 300, + "protocol": "Tcp", + "access": "Allow", + "direction": "Inbound", + "sourceApplicationSecurityGroups": [], + "destinationApplicationSecurityGroups": [], + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*", + "destinationPortRange": "3389" + } + } + ] + } + } + ] } \ No newline at end of file diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json index 54f362e..469cb90 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json @@ -1,327 +1,321 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.1", - "parameters": { - "adminUsername": { - "defaultValue": "DemoUser", - "type": "string", - "metadata": { - "description": "Administrator user name for logging into the virtual machine and SQL MI." - } - }, - "adminPassword": { - "type": "securestring", - "metadata": { - "description": "The password must be between 15 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter." - } - }, - "storageAccount": { - "type": "string", - "metadata": { - "description": "Storage account with source files for post deployment" - } - }, - "sasToken": { - "type": "string", - "metadata": { - "description": "sas token" - } - } , - "dbCount": - { - "type": "int", - "defaultvalue": 3, - "metadata": { - "description": "Select the number of db to add." - } - } - - }, - "outputs": { - "resourceID": { - "type": "string", - "value": "[variables('sqlVirtualMachineName')]" - }, - "scriptpath": { - "type": "string", - "value": "[variables('sqlCustomScriptUri')]" - } - }, - "variables": { - "location": "[resourceGroup().location]", - "SQLlMachineSize": "Standard_DS3_v2", - "sqlVirtualMachineName": "legacysql2016", - "sqlNetworkSecurityGroupName": "[concat(variables('sqlVirtualMachineName'), '-nsg')]", - "sqlNetworkInterfaceName": "[concat(variables('sqlVirtualMachineName'), '-nic')]", - "sqlPublicIpAddressName": "[concat(variables('sqlVirtualMachineName'), '-ip')]", - "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", - "managementSubnetName": "Management", - "sqlCustomScriptFileName": "Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1", - "sqlCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('sqlCustomScriptFileName'))]", - "dataPath": "F:\\data", - "sqlStorageDisksCount": { - "value": 1 - }, - "sqlStorageWorkloadType": "OLTP", - "sqlStorageDisksConfigurationType": "NEW", - "sqlStorageStartingDeviceId": 2, - "dataDisksLUNs": { - "value": [ - 0 - ] - }, - "logPath": "F:\\log", - "logDisksLUNs": { - "value": [ - 0 - ] - }, - "tempDbPath": "D:\\tempDb", - "dataFileCount": 2, - "dataFileSize":8 , - "dataGrowth":64, - "logFileSize": 8, - "logGrowth": 64, - "SQLSystemDbOnDataDisk": false - - }, - "resources": [ - { - "name": "[variables('sqlNetworkInterfaceName')]", - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2019-04-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkSecurityGroups/', variables('sqlNetworkSecurityGroupName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig1", - "properties": { - "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" - }, - "privateIPAllocationMethod": "Dynamic" - } - } - ], - "networkSecurityGroup": { - "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('sqlNetworkSecurityGroupName'))]" - } - } - }, - { - "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", - "type": "Microsoft.Compute/disks", - "apiVersion": "2022-03-02", - "location": "[variables('location')]", - "properties": { - "diskSizeGB": 64, - "creationData": { - "createOption": "empty" - } - }, - "sku": { - "name": "Premium_LRS", - "tier": "Premium" - } - }, - { "name": "[variables('sqlVirtualMachineName')]", - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2019-03-01", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('sqlNetworkInterfaceName'))]" - ], - "properties": { - "hardwareProfile": { - "vmSize": "[variables('SQLlMachineSize')]" - }, - "storageProfile": { - "osDisk": { - "createOption": "FromImage", - "name": "[concat(variables('sqlVirtualMachineName'), '_disk1_OS')]", - "managedDisk": { - "storageAccountType": "Premium_LRS" - } - }, - "imageReference": { - "publisher": "MicrosoftSQLServer", - "offer": "sql2016sp3-ws2019", - "sku": "enterprise", - "version": "latest" - }, - "dataDisks": [ - { - "lun": 0, - "createOption": "attach", - "caching": "ReadOnly", - "writeAcceleratorEnabled": false, - "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", - "managedDisk": { - "id": "[resourceId('Microsoft.Compute/disks/', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" - } - } - ] - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('sqlNetworkInterfaceName'))]" - } - ] - }, - "osProfile": { - "computerName": "[variables('sqlVirtualMachineName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "windowsConfiguration": { - "enableAutomaticUpdates": true, - "provisionVmAgent": true - } - }, - "licenseType": "Windows_Server", - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - } - } - }, - { - "name": "[concat('shutdown-computevm-', variables('sqlVirtualMachineName'))]", - "type": "Microsoft.DevTestLab/schedules", - "apiVersion": "2017-04-26-preview", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]" - ], - "properties": { - "status": "Enabled", - "taskType": "ComputeVmShutdownTask", - "dailyRecurrence": { - "time": "19:00" - }, - "timeZoneId": "UTC", - "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", - "notificationSettings": { - "status": "Disabled" - } - } - }, - { - "name": "[variables('sqlVirtualMachineName')]", - "type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines", - "apiVersion": "2021-11-01-preview", - "location": "[variables('location')]", - "properties": { - "virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", - "sqlManagement": "Full", - "SqlServerLicenseType": "AHUB", - "AutoPatchingSettings": { - "Enable": true, - "DayOfWeek":"Sunday", - "MaintenanceWindowStartingHour": "2", - "MaintenanceWindowDuration": "60" - }, - "KeyVaultCredentialSettings": { - "Enable": false, - "CredentialName": "" - }, - "ServerConfigurationsManagementSettings": { - "SQLConnectivityUpdateSettings": { - "ConnectivityType": "Private", - "Port": "1433", - "SQLAuthUpdateUserName": "[parameters('adminUsername')]", - "SQLAuthUpdatePassword": "[parameters('adminPassword')]" - }, - "AdditionalFeaturesServerConfigurations": { - "IsRServicesEnabled": "false" - } - }, - "StorageConfigurationSettings": { - "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]", - "StorageWorkloadType": "[variables('sqlStorageWorkloadType')]", - - "SQLDataSettings": { - "LUNs": [0], - "DefaultFilePath": "[variables('dataPath')]" - }, - "SQLLogSettings": { - "LUNs": [0], - "DefaultFilePath": "[variables('logPath')]" - }, - "SQLTempDbSettings": { - "DefaultFilePath": "[variables('tempDbPath')]", - "DataFileCount": "[variables('dataFileCount')]", - "DataFileSize": "[variables('dataFileSize')]", - "DataGrowth": "[variables('dataGrowth')]", - "LogFileSize": "[variables('logFileSize')]", - "LogGrowth": "[variables('logGrowth')]" - }, - "SQLSystemDbOnDataDisk": "[variables('SQLSystemDbOnDataDisk')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines',variables('sqlVirtualMachineName'))]" - ] - }, - { - "name": "[concat( variables('sqlVirtualMachineName'),'/SetupSqlVm')]", - "apiVersion": "2019-03-01", - "type": "Microsoft.Compute/virtualMachines/extensions", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]", - "[concat('Microsoft.SqlVirtualMachine/SqlVirtualMachines/', variables('sqlVirtualMachineName'))]" - ], - "properties": { - "publisher": "Microsoft.Compute", - "type": "CustomScriptExtension", - "typeHandlerVersion": "1.10", - "autoUpgradeMinorVersion": true, - "settings": { - "timestamp":123456783 - }, - "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasToken ', parameters('sasToken'),' -dbCount ', parameters('dbCount'))]" , - "storageAccountName": "[parameters('storageAccount')]", - "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", - "fileUris": [ - "[variables('sqlCustomScriptUri')]" - ] - } - - }, - "tags": { - "displayName": "SetupSqlVm" - } - }, - { - "name": "[variables('sqlNetworkSecurityGroupName')]", - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2019-06-01", - "location": "[variables('location')]", - "properties": { - "securityRules": [ - { - "name": "RDP", - "properties": { - "priority": 300, - "protocol": "Tcp", - "access": "Allow", - "direction": "Inbound", - "sourceApplicationSecurityGroups": [], - "destinationApplicationSecurityGroups": [], - "sourceAddressPrefix": "*", - "sourcePortRange": "*", - "destinationAddressPrefix": "*", - "destinationPortRange": "3389" - } - } - ] - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.1", + "parameters": { + "adminUsername": { + "defaultValue": "DemoUser", + "type": "string", + "metadata": { + "description": "Administrator user name for logging into the virtual machine and SQL MI." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "The password must be between 15 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter." + } + }, + "storageAccount": { + "type": "string", + "metadata": { + "description": "Storage account with source files for post deployment" + } + }, + "sasToken": { + "type": "string", + "metadata": { + "description": "sas token" + } + } , + "dbCount": + { + "type": "int", + "defaultvalue": 3, + "metadata": { + "description": "Select the number of db to add." + } + } + + }, + "outputs": { + "resourceID": { + "type": "string", + "value": "[variables('sqlVirtualMachineName')]" + }, + "scriptpath": { + "type": "string", + "value": "[variables('sqlCustomScriptUri')]" + } + }, + "variables": { + "location": "[resourceGroup().location]", + "SQLlMachineSize": "Standard_D2s_v5", + "sqlVirtualMachineName": "legacysql2016", + "sqlNetworkSecurityGroupName": "[concat(variables('sqlVirtualMachineName'), '-nsg')]", + "sqlNetworkInterfaceName": "[concat(variables('sqlVirtualMachineName'), '-nic')]", + "sqlPublicIpAddressName": "[concat(variables('sqlVirtualMachineName'), '-ip')]", + "virtualNetworkName": "[concat(resourceGroup().name, '-vnet')]", + "managementSubnetName": "Management", + "sqlCustomScriptFileName": "Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1", + "sqlCustomScriptUri": "[concat('https://',parameters('storageAccount'),'.blob.core.windows.net/build/', variables('sqlCustomScriptFileName'))]", + "sqlStorageDisksCount": { + "value": 1 + }, + "sqlStorageWorkloadType": "OLTP", + "sqlStorageDisksConfigurationType": "NEW", + "sqlStorageStartingDeviceId": 2, + "dataPath": "F:\\data", + "dataDisksLUNs": [0], + "logPath": "F:\\log", + "logDisksLUNs": [0], + "tempDbPath": "F:\\tempDb", + "tempDbDisksLUNs": [0], + "dataFileCount": 2, + "dataFileSize": 8, + "dataGrowth": 64, + "logFileSize": 8, + "logGrowth": 64, + "SQLSystemDbOnDataDisk": false + }, + "resources": [ + { + "name": "[variables('sqlNetworkInterfaceName')]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2019-04-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', variables('sqlNetworkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('managementSubnetName'))]" + }, + "privateIPAllocationMethod": "Dynamic" + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('sqlNetworkSecurityGroupName'))]" + } + } + }, + { + "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", + "type": "Microsoft.Compute/disks", + "apiVersion": "2022-03-02", + "location": "[variables('location')]", + "properties": { + "diskSizeGB": 128, + "creationData": { + "createOption": "empty" + } + }, + "sku": { + "name": "Premium_LRS", + "tier": "Premium" + } + }, + { "name": "[variables('sqlVirtualMachineName')]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2019-03-01", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('sqlNetworkInterfaceName'))]", + "[resourceId('Microsoft.Compute/disks', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" + ], + "properties": { + "hardwareProfile": { + "vmSize": "[variables('SQLlMachineSize')]" + }, + "storageProfile": { + "osDisk": { + "createOption": "FromImage", + "name": "[concat(variables('sqlVirtualMachineName'), '_disk1_OS')]", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + "imageReference": { + "publisher": "MicrosoftSQLServer", + "offer": "sql2016sp3-ws2019", + "sku": "enterprise", + "version": "latest" + }, + "dataDisks": [ + { + "lun": 0, + "createOption": "attach", + "caching": "None", + "writeAcceleratorEnabled": false, + "name": "[concat(variables('sqlVirtualMachineName'), '-DataDisk_0')]", + "managedDisk": { + "id": "[resourceId('Microsoft.Compute/disks/', concat(variables('sqlVirtualMachineName'), '-DataDisk_0'))]" + } + } + ] + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('sqlNetworkInterfaceName'))]" + } + ] + }, + "osProfile": { + "computerName": "[variables('sqlVirtualMachineName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "enableAutomaticUpdates": true, + "provisionVmAgent": true + } + }, + "licenseType": "Windows_Server", + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + } + } + }, + { + "name": "[concat('shutdown-computevm-', variables('sqlVirtualMachineName'))]", + "type": "Microsoft.DevTestLab/schedules", + "apiVersion": "2017-04-26-preview", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]" + ], + "properties": { + "status": "Enabled", + "taskType": "ComputeVmShutdownTask", + "dailyRecurrence": { + "time": "19:00" + }, + "timeZoneId": "UTC", + "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", + "notificationSettings": { + "status": "Disabled" + } + } + }, + { + "name": "[variables('sqlVirtualMachineName')]", + "type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines", + "apiVersion": "2021-11-01-preview", + "location": "[variables('location')]", + "properties": { + "virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('sqlVirtualMachineName'))]", + "sqlManagement": "Full", + "SqlServerLicenseType": "AHUB", + "AutoPatchingSettings": { + "Enable": true, + "DayOfWeek":"Sunday", + "MaintenanceWindowStartingHour": "2", + "MaintenanceWindowDuration": "60" + }, + "KeyVaultCredentialSettings": { + "Enable": false, + "CredentialName": "" + }, + "ServerConfigurationsManagementSettings": { + "SQLConnectivityUpdateSettings": { + "ConnectivityType": "Private", + "Port": "1433", + "SQLAuthUpdateUserName": "[parameters('adminUsername')]", + "SQLAuthUpdatePassword": "[parameters('adminPassword')]" + }, + "AdditionalFeaturesServerConfigurations": { + "IsRServicesEnabled": "false" + } + }, + "StorageConfigurationSettings": { + "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]", + "StorageWorkloadType": "[variables('sqlStorageWorkloadType')]", + + "SQLDataSettings": { + "LUNs": "[variables('dataDisksLUNs')]", + "DefaultFilePath": "[variables('dataPath')]" + }, + "SQLLogSettings": { + "LUNs": "[variables('logDisksLUNs')]", + "DefaultFilePath": "[variables('logPath')]" + }, + "SQLTempDbSettings": { + "LUNs": "[variables('tempDbDisksLUNs')]", + "DefaultFilePath": "[variables('tempDbPath')]", + "DataFileCount": "[variables('dataFileCount')]", + "DataFileSize": "[variables('dataFileSize')]", + "DataGrowth": "[variables('dataGrowth')]", + "LogFileSize": "[variables('logFileSize')]", + "LogGrowth": "[variables('logGrowth')]" + }, + "SQLSystemDbOnDataDisk": "[variables('SQLSystemDbOnDataDisk')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines',variables('sqlVirtualMachineName'))]" + ] + }, + { + "name": "[concat( variables('sqlVirtualMachineName'),'/SetupSqlVm')]", + "apiVersion": "2019-03-01", + "type": "Microsoft.Compute/virtualMachines/extensions", + "location": "[variables('location')]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('sqlVirtualMachineName'))]", + "[concat('Microsoft.SqlVirtualMachine/SqlVirtualMachines/', variables('sqlVirtualMachineName'))]" + ], + "properties": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.10", + "autoUpgradeMinorVersion": true, + "settings": { + "timestamp":123456783 + }, + "protectedSettings": { + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasToken ', parameters('sasToken'),' -dbCount ', parameters('dbCount'))]" , + "storageAccountName": "[parameters('storageAccount')]", + "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", + "fileUris": [ + "[variables('sqlCustomScriptUri')]" + ] + } + + }, + "tags": { + "displayName": "SetupSqlVm" + } + }, + { + "name": "[variables('sqlNetworkSecurityGroupName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-06-01", + "location": "[variables('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "priority": 300, + "protocol": "Tcp", + "access": "Allow", + "direction": "Inbound", + "sourceApplicationSecurityGroups": [], + "destinationApplicationSecurityGroups": [], + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*", + "destinationPortRange": "3389" + } + } + ] + } + } + ] } \ No newline at end of file From 5f2d3580b11c0e1bab01ef0e83f258b4f8edd7f8 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Mon, 22 Dec 2025 09:11:25 +0100 Subject: [PATCH 05/11] fix legacy db backup restore --- Build/ARM Deployment - SQL Hackathon v2.ps1 | 736 +++++++++--------- ...RM Template - SQL Hackathon - SQL2K12.json | 2 +- ...RM Template - SQL Hackathon - SQL2K16.json | 8 +- .../ARM_Deployment-SQL_Build_SQL2K12.ps1 | 2 +- .../ARM_Deployment-SQL_Build_SQL2K16.ps1 | 4 +- 5 files changed, 376 insertions(+), 376 deletions(-) diff --git a/Build/ARM Deployment - SQL Hackathon v2.ps1 b/Build/ARM Deployment - SQL Hackathon v2.ps1 index 5dab633..be5a665 100644 --- a/Build/ARM Deployment - SQL Hackathon v2.ps1 +++ b/Build/ARM Deployment - SQL Hackathon v2.ps1 @@ -1,368 +1,368 @@ - -<# -#POWERSHELL ENVIRONMENTALS: -#========================= - -#1. SET PS SCRIPT SECURITY: -#1.1 Set PS execution policy to Unrestricted so script can be run: -Set-ExecutionPolicy -ExecutionPolicy Unrestricted - -#1.1 Confirm Exectution Policy changed to Unrestricted: -Get-ExecutionPolicy - -#2. CONNECT PS SESSION TO TARGET AZURE SUBSCRIPTION: -#2.1 Run this to connect into Azure: -Connect-AzAccount - -#2.2 Run this to get a list of Subscriptions you have access to: -Get-AzSubscription - -#2.3 Replace and placeholders below then run: -Select-AzSubscription -Tenant '' -SubscriptionId '' - -#NOW RUN THE ENTIRE PS SCRIPT COMPLETING REQUESTED PARAMTERS AS PROMPTED. -#> -#Select-AzSubscription -Tenant '72f988bf-86f1-41af-91ab-2d7cd011db47' -SubscriptionId 'ab6dbbb5-ff85-4692-a99c-490f66eed14a' -#Select-AzSubscription -Tenant '4fc9c688-ad9c-4d58-85c7-d141d4989ac2' -SubscriptionId 'cfdd59e1-0a35-4577-a19b-6d6a44bcf2c4' - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "#################################################################################" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "SQL Server Migration Hack Build Script" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "This script will build the enviroment for the SQL Server Hack and Labs" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "#################################################################################" -$CurrentDir = Split-Path $script:MyInvocation.MyCommand.Path -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Checking and Installing Az and SQL modules......................................." -$sourceRootPath ="C:\Sources" -#Set-ExecutionPolicy RemoteSigned -Force -If(-not(Get-InstalledModule Az -ErrorAction silentlycontinue)){ - Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force -AllowClobber -} - - - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Setting Enviroment Variables....................................................." -$subscriptionID = (Get-AzContext).Subscription.id -$subscriptionName = (Get-AzContext).Subscription.Name - -if(-not $subscriptionID) { ` - $subscriptionMessage = "There is no selected Azure subscription. Please use Select-AzSubscription to select a default subscription"; ` - Write-Warning $subscriptionMessage ; return;} ` -else { ` - $subscriptionMessage = ("Actually targeting Azure subscription: {0} - {1}." -f $subscriptionID, $subscriptionName)} -Write-Host -BackgroundColor Black -ForegroundColor Yellow $subscriptionMessage - -if ((read-host "Please ensure this is the correct subscription. Press a to abort, any other key to continue.") -eq "a") {Return;} -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Continuing to build.................................................." - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Register Batch provider " -Register-AzResourceProvider -ProviderNamespace Microsoft.Batch - -################################################################### -# Setup Vaiables -################################################################### -$DefaultValue = 3 -if (($TeamVMCount = Read-Host "Please enter the number of Team VM's required (1-20) (default value: $DefaultValue)") -eq '') {$TeamVMCount = $DefaultValue} -# If ($TeamVMCount -gt 20) -# { -# Write-Warning "Maximum number TEAM VM's is 20. Setting to 5 VM's" -# $TeamVMCount = 5 - -# } - -$DefaultValue = "WestEurope" -if (($Location = Read-Host "Please enter the Location of the Resource Groups. (default value: $DefaultValue)") -eq '') {$Location = $DefaultValue} -If (“NorthEurope”,”WestEurope”,”UKSouth”, "UKWest", "WestUS", "EastUS" -NotContains $Location ) {Write-Warning "Unrecognised location. Setting to Default $DefaultValue" ; $Location = "NorthEurope"} - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "##################### IMPORTANT: MAKE A NOTE OF THE FOLLOWING USERNAME and PASSWORD ########################" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "The username and password specified next, will be used to credentials to SQL, Managed Instance and any VM's" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "############################################################################################################" -$DefaultValue = "DemoUser" -$x = 4 -do - {$x = $x - 1 - if ($x -lt 3){write-host "Not enough characters. Retries remaining: " $x}; - if ($x -le 0) {write-host "Existing build. Please check username and retry..."; Exit}; - if (($adminUsername = Read-Host "Please enter an Admin username (more than 6 characters) (default value: $DefaultValue)") -eq '') {$adminUsername = $DefaultValue} - } -while ($adminUsername.length -le 6) - - -$x = 4 -do - {$x = $x - 1 - if ($x -lt 3){write-host "Not enough characters. Retries remaining: " $x}; - if ($x -le 0) {write-host "Existing build. Please check password and retry..."; Exit}; - $adminPassword = Read-Host "Please enter a 16 character Password. The password must be between 16 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter" -AsSecureString - } -while ($adminPassword.length -le 15) - -################################################################### -# Setup Hack Resource Groups -################################################################### - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "##################### IMPORTANT: MAKE A NOTE OF THE FOLLOWING RESOURCE GROUPS ########################" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "The Resource groups will be used to store all the lab build" -Write-Host -BackgroundColor Black -ForegroundColor Yellow "############################################################################################################" - -$DefaultValue = "SQLHACK-SHARED" -if (($SharedRG = Read-Host "Please enter a Shared resource group name. (default value: $DefaultValue)") -eq '') {$SharedRG = $DefaultValue} - -$notPresent = Get-AzResourceGroup -name $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue -if (!($notPresent)) {New-AzResourceGroup -Name $SharedRG -Location $Location} - -$DefaultValue = "SQLHACK-TEAM_VMs" -if (($TeamRG = Read-Host "Please enter a VM resource group name. (default value: $DefaultValue)") -eq '') {$TeamRG = $DefaultValue} - -$notPresent =Get-AzResourceGroup -name $TeamRG -ErrorVariable notPresent -ErrorAction SilentlyContinue -if (!($notPresent)) {New-AzResourceGroup -Name $TeamRG -Location $Location} - -$CurrentDir = Split-Path $script:MyInvocation.MyCommand.Path - - - -################################################################### -# Setup Network and Storage account -################################################################### -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating Virtual Network................................................." -$templatePath= (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Network - v2.json") -$output = New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateFile $templatePath -Name "NetworkBuild" - - -# Check if Vnet has been created -Get-AzVirtualNetwork -Name "$SharedRG-vnet" -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue -if ($notPresent) {Write-Warning "VNET Failed to build. Please check and retry";return;} - -# save the SQL Managed Instance FQDN -$uniqueRgValue = $output.Outputs['uniqueRgValue'].Value - -################################################################### -# Setup SASURI -################################################################### -#Create Blob Storage Container and SASURI Key. -$StorageAccount = (get-AzStorageAccount -ResourceGroupName $SharedRG).StorageAccountName | Select-object -First 1 -$StorageAccountKeys = Get-AzStorageAccountKey -ResourceGroupName $SharedRG -Name $StorageAccount -$Key0 = $StorageAccountKeys | Select-Object -First 1 -ExpandProperty Value -$Context = New-AzStorageContext -StorageAccountName $StorageAccount -StorageAccountKey $Key0 - -#Create Container auditlogs -If(-not (Get-AzStorageContainer -Context $Context -Name auditlogs -ErrorAction Ignore)){ - $output = New-AzStorageContainer -Context $Context -Name auditlogs -} - -#Create Container migration -If(-not (Get-AzStorageContainer -Context $Context -Name migration -ErrorAction Ignore)){ - $output = New-AzStorageContainer -Context $Context -Name migration -} - -#Create Container Build -If(-not (Get-AzStorageContainer -Context $Context -Name build -ErrorAction Ignore)){ - $output = New-AzStorageContainer -Context $Context -Name build -} - -#Create SASUri for Build Container -$storagePolicyName = "Build-Policy" -$expiryTime = (Get-Date).AddYears(1) - -If(-not (Get-AzStorageContainerStoredAccessPolicy -Context $Context -Name build)){ - New-AzStorageContainerStoredAccessPolicy -Container build -Policy $storagePolicyName -Permission rl -ExpiryTime $expiryTime -Context $Context -StartTime(Get-Date) -} -$SASUriContainerBuild = (New-AzStorageContainerSASToken -Name "build" -Policy $storagePolicyName -Context $Context) -$JsonSASUriContainerBuild = $SASUriContainerBuild | ConvertTo-Json - -$storagePolicyName = "Migration-Policy" -If(-not (Get-AzStorageContainerStoredAccessPolicy -Context $Context -Name migration)){ - New-AzStorageContainerStoredAccessPolicy -Container migration -Policy $storagePolicyName -Permission rwld -ExpiryTime $expiryTime -Context $Context -StartTime(Get-Date) -} -$SASUriMigrationContainer = (New-AzStorageContainerSASToken -Name "migration" -Policy $storagePolicyName -Context $Context -FullUri) -$JsonSASUriContainerMigration = $SASUriMigrationContainer| ConvertTo-Json -################################################################################### -# download and upload source file needed -function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) -{ - while($true) - { - try - { - Invoke-WebRequest $url -OutFile $downloadLocation - Write-Host "Download '$url'completed" - break - } - catch - { - $exceptionMessage = $_.Exception.Message - Write-Host "Failed to download '$url': $exceptionMessage" - if ($retries -gt 0) { - $retries-- - Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" - Start-Sleep -Seconds 10 - - } - else - { - $exception = $_.Exception - throw $exception - } - } - } -} - - -If(!(test-path $sourceRootPath)) -{ - New-Item -ItemType Directory -Force -Path $sourceRootPath -} -else -{ - Remove-Item $sourceRootPath -Force -Recurse - New-Item -ItemType Directory -Force -Path $sourceRootPath - -} -$CopyPath="$sourceRootPath\Downloads" -If(!(test-path $CopyPath)) -{ - New-Item -ItemType Directory -Force -Path $CopyPath -} - -DownloadWithRetry "https://aka.ms/ssmsfullsetup?clcid=0x409" "$CopyPath\SSMS-Setup-ENU.exe" 10 -DownloadWithRetry "https://download.microsoft.com/download/C/6/3/C63D8695-CEF2-43C3-AF0A-4989507E429B/DataMigrationAssistant.msi" "$CopyPath\DataMigrationAssistant.msi" 10 -DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2124518" "$CopyPath\SSDT-Setup-ENU.exe" 10 -DownloadWithRetry "https://go.microsoft.com/fwlink/?LinkId=708343" "$CopyPath\StorageExplore.exe" 10 -DownloadWithRetry "https://download.visualstudio.microsoft.com/download/pr/3f56df9d-6dc0-4897-a49b-ea891f9ad0f4/076e353a29908c70e24ba8b8d0daefb8/windowsdesktop-runtime-3.1.21-win-x64.exe" "$CopyPath\windowsdesktop-runtime-3.1.21-win-x64.exe" 10 -DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2133900" "$CopyPath\sql-assessment-0.6.3.vsix" 10 -DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2099770" "$CopyPath\managed-instance-dashboard-0.4.2.vsix" 10 - - -$SourcePath= (Join-Path $CurrentDir "DB_SSIS_Build\") -$TargetPath = "$sourceRootPath" -Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force -$SourcePath= (Join-Path $CurrentDir "DB_SQL2K12_Build\") -Compress-Archive -Path $SourcePath -DestinationPath "$TargetPath\DB_SQL2K12_Build.zip" -$SourcePath= (Join-Path $CurrentDir "DB_SQL2K16_Build\") -Compress-Archive -Path $SourcePath -DestinationPath "$TargetPath\DB_SQL2K16_Build.zip" - -$SourcePath= (Join-Path $CurrentDir "LABS\") -Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force -Exclude "*.docx" -$SourcePath= (Join-Path $CurrentDir "DB_Perf\") -Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force -$SourcePath= (Join-Path $CurrentDir "Powershell\") -Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force -$SourcePath= (Join-Path $CurrentDir "TSQL_Scripts\") -Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force - -# copy migration container SAS key to file -$TargetPathSASKey= (Join-Path $TargetPath "LABS\01-Data_Migration") -$SASUriMigrationContainer | out-file -FilePath "$TargetPathSASKey\SASKEY.txt" -Force - - - - -$filesToUpload = Get-ChildItem -File -Recurse -Path $sourceRootPath - - - foreach ($x in $filesToUpload) { - $targetPath = ($x.fullname.Substring($sourceRootPath.Length + 1)).Replace("\", "/") - - Write-Verbose "Uploading $("\" + $x.fullname.Substring($sourceRootPath.Length + 1)) to $("build" + " /" + $targetPath)" - Set-AzStorageBlobContent -File $x.fullname -Container "build" -Blob $targetPath -Context $Context -Force - } - - - -################################################################### -# Setup SQL Legacy Servers -################################################################### -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating legacySQL2012 Server................................................." - -$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - SQL2k12.json") -New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -storageAccount $StorageAccount -sasTokenBuildContainer $JsonSASUriContainerBuild -sasTokenMigrationContainer $Key0 -Name "LegacySQL2012" -dbCount $TeamVMCount -AsJob - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating legacySQL2016 Server................................................." - -$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - SQL2K16.json") -New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -storageAccount $StorageAccount -sasToken $JsonSASUriContainerBuild -Name "LegacySQL2K16" -dbCount $TeamVMCount #-AsJob - -Restart-AzVM -ResourceGroupName $SharedRG -Name legacysql2016 -Write-host "legacysql2016 restarted " -$Script = 'Powershell\PrerequisitesSQL2016_MILINK.ps1' -$ScriptPath= (Join-Path $CurrentDir $Script) -Invoke-AzVMRunCommand -ResourceGroupName $SharedRG -Name legacysql2016 -CommandId RunPowerShellScript -ScriptPath $ScriptPath - -################################################################### -# Setup Data Migration Service V2 -################################################################### -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating DMS, Datafactory, Keyvault, storage account shared resources.................................................." -$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Shared - v2.json") -New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -Name "SharedServicesBuild" -AsJob - -# Setup KeyVault -$Random = Get-Random -Maximum 99999 -$Keyvault = "sqlhack-keyvault-$Random" -If(-not (Get-AzKeyVault -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction Ignore)){ -New-AzKeyVault -Name $Keyvault -ResourceGroupName $SharedRG -Location $Location -} -Get-AzKeyVault -Name $Keyvault -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue -if ($notPresent) {Write-Warning "sqlhack-keyvault Failed to build. Please check and retry";return;} - - -################################################################### -# Setup Managed Instance and ADF with SSIS IR -################################################################### -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating sqlhack-mi Managed Instance................................................." -$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Managed Instance- v2.json") -New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -location $location -createNSG 1 -createRT 1 -Name "ManagedInstanceBuild" -AsJob - - -################################################################### -# Setup Team VM's -################################################################### -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating $TeamVMCount Team Server(s).................................................." -$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Jump Servers - v2.json") - -New-AzResourceGroupDeployment -ResourceGroupName $TeamRG -TemplateUri $TemplateUri -Name "TeamVMBuild" -vmCount $TeamVMCount -SharedResourceGroup $SharedRG -SASURIKey $JsonSASUriContainerBuild -StorageAccount $StorageAccount -adminPassword $adminpassword -adminUsername $adminUsername -$AzureVMsRunning = Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} -$AzureVMsRunning | ForEach-Object -ThrottleLimit 22 -Parallel{ - - Restart-AzVM -ResourceGroupName $_.ResourceGroupName -Name $_.Name - Write-host "$($_.Name) restarted " -} -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Waiting for 3 minutes ........................................................." -start-sleep -s 180 -Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} |Format-Table -Property Name, PowerState - -#configure VM's -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Start Vms configuration ........................................................." -$Script = 'Powershell\Configure-TEAM_VMs.ps1' -$ScriptPath= (Join-Path $CurrentDir $Script) -[string]$Installed = "1" # 1 to install tool and labs, 0 for labs only -$VMs = Get-AzVM -ResourceGroupName $TeamRG #-ResourceType Microsoft.Compute/virtualMachines - -$VMs | ForEach-Object -ThrottleLimit 22 -Parallel { - $RG = $_.ResourceGroupName - $VMName= $_.Name - $Message = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- Configuration starting..." - write-host $Message - $out = Invoke-AzVMRunCommand -ResourceGroupName $RG -Name $VMName -CommandId RunPowerShellScript -ScriptPath $using:ScriptPath -Parameter @{StorageAccount = $using:StorageAccount; SASURIKey = $using:JsonSASUriContainerBuild; Installed = $using:Installed} - #Formating the Output with the VM name - if($out.value[1].Message) - { - $status= "failed" - $ForegroundColor="Red" - $message = $out.value[1].Message - } - else { - $status= "successfull" - $ForegroundColor="White" - $message = "" - } - $output = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- status: $status " + $message - Write-host $output - -ForegroundColor $ForegroundColor -} - - -Write-Host -BackgroundColor Black -ForegroundColor Yellow "Enviroment Build in progress. Please check RG deployments for errors." - -Write-Warning "NOTE: THE FOLLOWING POST BUILD TASKS ARE REQUIRED." -Write-Warning "1. DataFactory Build Ok. You will need to start the SSIS integration runtime and enable AHUB" -Write-Warning "2. Restore databases for SSIS + Monitoring labs by running the Launch_SQL_MI_configuration.ps1. Choose a remote TEAM VM. Note: Only run once." -Write-Warning "3. All labs and documaention can be found on TEAMVM's in C:\_SQLHACK_\LABS" - - + +<# +#POWERSHELL ENVIRONMENTALS: +#========================= + +#1. SET PS SCRIPT SECURITY: +#1.1 Set PS execution policy to Unrestricted so script can be run: +Set-ExecutionPolicy -ExecutionPolicy Unrestricted + +#1.1 Confirm Exectution Policy changed to Unrestricted: +Get-ExecutionPolicy + +#2. CONNECT PS SESSION TO TARGET AZURE SUBSCRIPTION: +#2.1 Run this to connect into Azure: +Connect-AzAccount + +#2.2 Run this to get a list of Subscriptions you have access to: +Get-AzSubscription + +#2.3 Replace and placeholders below then run: +Select-AzSubscription -Tenant '' -SubscriptionId '' + +#NOW RUN THE ENTIRE PS SCRIPT COMPLETING REQUESTED PARAMTERS AS PROMPTED. +#> +#Select-AzSubscription -Tenant '72f988bf-86f1-41af-91ab-2d7cd011db47' -SubscriptionId 'ab6dbbb5-ff85-4692-a99c-490f66eed14a' +#Select-AzSubscription -Tenant '4fc9c688-ad9c-4d58-85c7-d141d4989ac2' -SubscriptionId 'cfdd59e1-0a35-4577-a19b-6d6a44bcf2c4' + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "#################################################################################" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "SQL Server Migration Hack Build Script" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "This script will build the enviroment for the SQL Server Hack and Labs" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "#################################################################################" +$CurrentDir = Split-Path $script:MyInvocation.MyCommand.Path +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Checking and Installing Az and SQL modules......................................." +$sourceRootPath ="C:\Sources" +#Set-ExecutionPolicy RemoteSigned -Force +If(-not(Get-InstalledModule Az -ErrorAction silentlycontinue)){ + Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force -AllowClobber +} + + + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Setting Enviroment Variables....................................................." +$subscriptionID = (Get-AzContext).Subscription.id +$subscriptionName = (Get-AzContext).Subscription.Name + +if(-not $subscriptionID) { ` + $subscriptionMessage = "There is no selected Azure subscription. Please use Select-AzSubscription to select a default subscription"; ` + Write-Warning $subscriptionMessage ; return;} ` +else { ` + $subscriptionMessage = ("Actually targeting Azure subscription: {0} - {1}." -f $subscriptionID, $subscriptionName)} +Write-Host -BackgroundColor Black -ForegroundColor Yellow $subscriptionMessage + +if ((read-host "Please ensure this is the correct subscription. Press a to abort, any other key to continue.") -eq "a") {Return;} +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Continuing to build.................................................." + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Register Batch provider " +Register-AzResourceProvider -ProviderNamespace Microsoft.Batch + +################################################################### +# Setup Vaiables +################################################################### +$DefaultValue = 3 +if (($TeamVMCount = Read-Host "Please enter the number of Team VM's required (1-20) (default value: $DefaultValue)") -eq '') {$TeamVMCount = $DefaultValue} +# If ($TeamVMCount -gt 20) +# { +# Write-Warning "Maximum number TEAM VM's is 20. Setting to 5 VM's" +# $TeamVMCount = 5 + +# } + +$DefaultValue = "WestEurope" +if (($Location = Read-Host "Please enter the Location of the Resource Groups. (default value: $DefaultValue)") -eq '') {$Location = $DefaultValue} +If (“NorthEurope”,”WestEurope”,”UKSouth”, "UKWest", "WestUS", "EastUS" -NotContains $Location ) {Write-Warning "Unrecognised location. Setting to Default $DefaultValue" ; $Location = "NorthEurope"} + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "##################### IMPORTANT: MAKE A NOTE OF THE FOLLOWING USERNAME and PASSWORD ########################" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "The username and password specified next, will be used to credentials to SQL, Managed Instance and any VM's" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "############################################################################################################" +$DefaultValue = "DemoUser" +$x = 4 +do + {$x = $x - 1 + if ($x -lt 3){write-host "Not enough characters. Retries remaining: " $x}; + if ($x -le 0) {write-host "Existing build. Please check username and retry..."; Exit}; + if (($adminUsername = Read-Host "Please enter an Admin username (more than 6 characters) (default value: $DefaultValue)") -eq '') {$adminUsername = $DefaultValue} + } +while ($adminUsername.length -le 6) + + +$x = 4 +do + {$x = $x - 1 + if ($x -lt 3){write-host "Not enough characters. Retries remaining: " $x}; + if ($x -le 0) {write-host "Existing build. Please check password and retry..."; Exit}; + $adminPassword = Read-Host "Please enter a 16 character Password. The password must be between 16 and 128 characters in length and must contain at least one number, one non-alphanumeric character, and one upper or lower case letter" -AsSecureString + } +while ($adminPassword.length -le 15) + +################################################################### +# Setup Hack Resource Groups +################################################################### + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "##################### IMPORTANT: MAKE A NOTE OF THE FOLLOWING RESOURCE GROUPS ########################" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "The Resource groups will be used to store all the lab build" +Write-Host -BackgroundColor Black -ForegroundColor Yellow "############################################################################################################" + +$DefaultValue = "SQLHACK-SHARED" +if (($SharedRG = Read-Host "Please enter a Shared resource group name. (default value: $DefaultValue)") -eq '') {$SharedRG = $DefaultValue} + +$notPresent = Get-AzResourceGroup -name $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue +if (!($notPresent)) {New-AzResourceGroup -Name $SharedRG -Location $Location} + +$DefaultValue = "SQLHACK-TEAM_VMs" +if (($TeamRG = Read-Host "Please enter a VM resource group name. (default value: $DefaultValue)") -eq '') {$TeamRG = $DefaultValue} + +$notPresent =Get-AzResourceGroup -name $TeamRG -ErrorVariable notPresent -ErrorAction SilentlyContinue +if (!($notPresent)) {New-AzResourceGroup -Name $TeamRG -Location $Location} + +$CurrentDir = Split-Path $script:MyInvocation.MyCommand.Path + + + +################################################################### +# Setup Network and Storage account +################################################################### +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating Virtual Network................................................." +$templatePath= (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Network - v2.json") +$output = New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateFile $templatePath -Name "NetworkBuild" + + +# Check if Vnet has been created +Get-AzVirtualNetwork -Name "$SharedRG-vnet" -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue +if ($notPresent) {Write-Warning "VNET Failed to build. Please check and retry";return;} + +# save the SQL Managed Instance FQDN +$uniqueRgValue = $output.Outputs['uniqueRgValue'].Value + +################################################################### +# Setup SASURI +################################################################### +#Create Blob Storage Container and SASURI Key. +$StorageAccount = (get-AzStorageAccount -ResourceGroupName $SharedRG).StorageAccountName | Select-object -First 1 +$StorageAccountKeys = Get-AzStorageAccountKey -ResourceGroupName $SharedRG -Name $StorageAccount +$Key0 = $StorageAccountKeys | Select-Object -First 1 -ExpandProperty Value +$Context = New-AzStorageContext -StorageAccountName $StorageAccount -StorageAccountKey $Key0 + +#Create Container auditlogs +If(-not (Get-AzStorageContainer -Context $Context -Name auditlogs -ErrorAction Ignore)){ + $output = New-AzStorageContainer -Context $Context -Name auditlogs +} + +#Create Container migration +If(-not (Get-AzStorageContainer -Context $Context -Name migration -ErrorAction Ignore)){ + $output = New-AzStorageContainer -Context $Context -Name migration +} + +#Create Container Build +If(-not (Get-AzStorageContainer -Context $Context -Name build -ErrorAction Ignore)){ + $output = New-AzStorageContainer -Context $Context -Name build +} + +#Create SASUri for Build Container +$storagePolicyName = "Build-Policy" +$expiryTime = (Get-Date).AddYears(1) + +If(-not (Get-AzStorageContainerStoredAccessPolicy -Context $Context -Name build)){ + New-AzStorageContainerStoredAccessPolicy -Container build -Policy $storagePolicyName -Permission rl -ExpiryTime $expiryTime -Context $Context -StartTime(Get-Date) +} +$SASUriContainerBuild = (New-AzStorageContainerSASToken -Name "build" -Policy $storagePolicyName -Context $Context) +$JsonSASUriContainerBuild = $SASUriContainerBuild | ConvertTo-Json + +$storagePolicyName = "Migration-Policy" +If(-not (Get-AzStorageContainerStoredAccessPolicy -Context $Context -Name migration)){ + New-AzStorageContainerStoredAccessPolicy -Container migration -Policy $storagePolicyName -Permission rwld -ExpiryTime $expiryTime -Context $Context -StartTime(Get-Date) +} +$SASUriMigrationContainer = (New-AzStorageContainerSASToken -Name "migration" -Policy $storagePolicyName -Context $Context -FullUri) +$JsonSASUriContainerMigration = $SASUriMigrationContainer| ConvertTo-Json +################################################################################### +# download and upload source file needed +function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) +{ + while($true) + { + try + { + Invoke-WebRequest $url -OutFile $downloadLocation + Write-Host "Download '$url'completed" + break + } + catch + { + $exceptionMessage = $_.Exception.Message + Write-Host "Failed to download '$url': $exceptionMessage" + if ($retries -gt 0) { + $retries-- + Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" + Start-Sleep -Seconds 10 + + } + else + { + $exception = $_.Exception + throw $exception + } + } + } +} + + +If(!(test-path $sourceRootPath)) +{ + New-Item -ItemType Directory -Force -Path $sourceRootPath +} +else +{ + Remove-Item $sourceRootPath -Force -Recurse + New-Item -ItemType Directory -Force -Path $sourceRootPath + +} +$CopyPath="$sourceRootPath\Downloads" +If(!(test-path $CopyPath)) +{ + New-Item -ItemType Directory -Force -Path $CopyPath +} + +DownloadWithRetry "https://aka.ms/ssmsfullsetup?clcid=0x409" "$CopyPath\SSMS-Setup-ENU.exe" 10 +DownloadWithRetry "https://download.microsoft.com/download/C/6/3/C63D8695-CEF2-43C3-AF0A-4989507E429B/DataMigrationAssistant.msi" "$CopyPath\DataMigrationAssistant.msi" 10 +DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2124518" "$CopyPath\SSDT-Setup-ENU.exe" 10 +DownloadWithRetry "https://go.microsoft.com/fwlink/?LinkId=708343" "$CopyPath\StorageExplore.exe" 10 +DownloadWithRetry "https://download.visualstudio.microsoft.com/download/pr/3f56df9d-6dc0-4897-a49b-ea891f9ad0f4/076e353a29908c70e24ba8b8d0daefb8/windowsdesktop-runtime-3.1.21-win-x64.exe" "$CopyPath\windowsdesktop-runtime-3.1.21-win-x64.exe" 10 +DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2133900" "$CopyPath\sql-assessment-0.6.3.vsix" 10 +DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2099770" "$CopyPath\managed-instance-dashboard-0.4.2.vsix" 10 + + +$SourcePath= (Join-Path $CurrentDir "DB_SSIS_Build\") +$TargetPath = "$sourceRootPath" +Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force +$SourcePath= (Join-Path $CurrentDir "DB_SQL2K12_Build\") +Compress-Archive -Path $SourcePath -DestinationPath "$TargetPath\DB_SQL2K12_Build.zip" +$SourcePath= (Join-Path $CurrentDir "DB_SQL2K16_Build\") +Compress-Archive -Path $SourcePath -DestinationPath "$TargetPath\DB_SQL2K16_Build.zip" + +$SourcePath= (Join-Path $CurrentDir "LABS\") +Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force -Exclude "*.docx" +$SourcePath= (Join-Path $CurrentDir "DB_Perf\") +Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force +$SourcePath= (Join-Path $CurrentDir "Powershell\") +Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force +$SourcePath= (Join-Path $CurrentDir "TSQL_Scripts\") +Copy-Item -Path $SourcePath -Destination $TargetPath -Recurse -Force + +# copy migration container SAS key to file +$TargetPathSASKey= (Join-Path $TargetPath "LABS\01-Data_Migration") +$SASUriMigrationContainer | out-file -FilePath "$TargetPathSASKey\SASKEY.txt" -Force + + + + +$filesToUpload = Get-ChildItem -File -Recurse -Path $sourceRootPath + + + foreach ($x in $filesToUpload) { + $targetPath = ($x.fullname.Substring($sourceRootPath.Length + 1)).Replace("\", "/") + + Write-Verbose "Uploading $("\" + $x.fullname.Substring($sourceRootPath.Length + 1)) to $("build" + " /" + $targetPath)" + Set-AzStorageBlobContent -File $x.fullname -Container "build" -Blob $targetPath -Context $Context -Force + } + + + +################################################################### +# Setup SQL Legacy Servers +################################################################### +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating legacySQL2012 Server................................................." + +$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - SQL2k12.json") +New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -storageAccount $StorageAccount -sasTokenBuildContainer $SASUriContainerBuild -sasTokenMigrationContainer $Key0 -Name "LegacySQL2012" -dbCount $TeamVMCount -AsJob + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating legacySQL2016 Server................................................." + +$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - SQL2K16.json") +New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -storageAccount $StorageAccount -sasTokenBuildContainer $SASUriContainerBuild -Name "LegacySQL2K16" -dbCount $TeamVMCount #-AsJob + +Restart-AzVM -ResourceGroupName $SharedRG -Name legacysql2016 +Write-host "legacysql2016 restarted " +$Script = 'Powershell\PrerequisitesSQL2016_MILINK.ps1' +$ScriptPath= (Join-Path $CurrentDir $Script) +Invoke-AzVMRunCommand -ResourceGroupName $SharedRG -Name legacysql2016 -CommandId RunPowerShellScript -ScriptPath $ScriptPath + +################################################################### +# Setup Data Migration Service V2 +################################################################### +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating DMS, Datafactory, Keyvault, storage account shared resources.................................................." +$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Shared - v2.json") +New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -Name "SharedServicesBuild" -AsJob + +# Setup KeyVault +$Random = Get-Random -Maximum 99999 +$Keyvault = "sqlhack-keyvault-$Random" +If(-not (Get-AzKeyVault -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction Ignore)){ +New-AzKeyVault -Name $Keyvault -ResourceGroupName $SharedRG -Location $Location +} +Get-AzKeyVault -Name $Keyvault -ResourceGroupName $SharedRG -ErrorVariable notPresent -ErrorAction SilentlyContinue +if ($notPresent) {Write-Warning "sqlhack-keyvault Failed to build. Please check and retry";return;} + + +################################################################### +# Setup Managed Instance and ADF with SSIS IR +################################################################### +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating sqlhack-mi Managed Instance................................................." +$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Managed Instance- v2.json") +New-AzResourceGroupDeployment -ResourceGroupName $SharedRG -TemplateUri $TemplateUri -adminPassword $adminpassword -adminUsername $adminUsername -location $location -createNSG 1 -createRT 1 -Name "ManagedInstanceBuild" -AsJob + + +################################################################### +# Setup Team VM's +################################################################### +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Creating $TeamVMCount Team Server(s).................................................." +$TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackathon - Jump Servers - v2.json") + +New-AzResourceGroupDeployment -ResourceGroupName $TeamRG -TemplateUri $TemplateUri -Name "TeamVMBuild" -vmCount $TeamVMCount -SharedResourceGroup $SharedRG -SASURIKey $JsonSASUriContainerBuild -StorageAccount $StorageAccount -adminPassword $adminpassword -adminUsername $adminUsername +$AzureVMsRunning = Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} +$AzureVMsRunning | ForEach-Object -ThrottleLimit 22 -Parallel{ + + Restart-AzVM -ResourceGroupName $_.ResourceGroupName -Name $_.Name + Write-host "$($_.Name) restarted " +} +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Waiting for 3 minutes ........................................................." +start-sleep -s 180 +Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} |Format-Table -Property Name, PowerState + +#configure VM's +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Start Vms configuration ........................................................." +$Script = 'Powershell\Configure-TEAM_VMs.ps1' +$ScriptPath= (Join-Path $CurrentDir $Script) +[string]$Installed = "1" # 1 to install tool and labs, 0 for labs only +$VMs = Get-AzVM -ResourceGroupName $TeamRG #-ResourceType Microsoft.Compute/virtualMachines + +$VMs | ForEach-Object -ThrottleLimit 22 -Parallel { + $RG = $_.ResourceGroupName + $VMName= $_.Name + $Message = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- Configuration starting..." + write-host $Message + $out = Invoke-AzVMRunCommand -ResourceGroupName $RG -Name $VMName -CommandId RunPowerShellScript -ScriptPath $using:ScriptPath -Parameter @{StorageAccount = $using:StorageAccount; SASURIKey = $using:JsonSASUriContainerBuild; Installed = $using:Installed} + #Formating the Output with the VM name + if($out.value[1].Message) + { + $status= "failed" + $ForegroundColor="Red" + $message = $out.value[1].Message + } + else { + $status= "successfull" + $ForegroundColor="White" + $message = "" + } + $output = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- status: $status " + $message + Write-host $output - -ForegroundColor $ForegroundColor +} + + +Write-Host -BackgroundColor Black -ForegroundColor Yellow "Enviroment Build in progress. Please check RG deployments for errors." + +Write-Warning "NOTE: THE FOLLOWING POST BUILD TASKS ARE REQUIRED." +Write-Warning "1. DataFactory Build Ok. You will need to start the SSIS integration runtime and enable AHUB" +Write-Warning "2. Restore databases for SSIS + Monitoring labs by running the Launch_SQL_MI_configuration.ps1. Choose a remote TEAM VM. Note: Only run once." +Write-Warning "3. All labs and documaention can be found on TEAMVM's in C:\_SQLHACK_\LABS" + + diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json index 922f4d5..26d062b 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json @@ -285,7 +285,7 @@ "timestamp":123456783 }, "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasTokenBuildContainer ', parameters('sasTokenBuildContainer'),' -sasTokenMigrationContainer ', parameters('sasTokenMigrationContainer'),' -dbCount ', parameters('dbCount'))]" , + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername \"', parameters('adminUsername'), '\" -AdminPassword \"', parameters('adminPassword'), '\" -storageAccountName \"', parameters('storageAccount'), '\" -sasTokenBuildContainer \"', parameters('sasTokenBuildContainer'), '\" -sasTokenMigrationContainer \"', parameters('sasTokenMigrationContainer'), '\" -dbCount ', parameters('dbCount'))]", "storageAccountName": "[parameters('storageAccount')]", "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", "fileUris": [ diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json index 469cb90..535ebff 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json @@ -21,12 +21,12 @@ "description": "Storage account with source files for post deployment" } }, - "sasToken": { + "sasTokenBuildContainer": { "type": "string", "metadata": { - "description": "sas token" + "description": "sas token for the build storage container" } - } , + }, "dbCount": { "type": "int", @@ -279,7 +279,7 @@ "timestamp":123456783 }, "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername ', parameters('adminUsername'),' -AdminPassword ', parameters('adminPassword'),' -storageAccountName ',parameters('storageAccount'),' -sasToken ', parameters('sasToken'),' -dbCount ', parameters('dbCount'))]" , + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername \"', parameters('adminUsername'), '\" -AdminPassword \"', parameters('adminPassword'), '\" -storageAccountName \"', parameters('storageAccount'), '\" -sasTokenBuildContainer \"', parameters('sasTokenBuildContainer'), -dbCount ', parameters('dbCount'))]", "storageAccountName": "[parameters('storageAccount')]", "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", "fileUris": [ diff --git a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1 b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1 index 754ba27..378defb 100644 --- a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1 +++ b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K12.ps1 @@ -94,7 +94,7 @@ function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $ret } } -$SourcefilePath = "https://$storageAccountName.blob.core.windows.net/build/DB_SQL2K12_Build.zip$sasTokenBuildContainer" +$SourcefilePath = "https://$storageAccountName.blob.core.windows.net/build/DB_SQL2K12_Build.zip?$sasTokenBuildContainer" DownloadWithRetry $SourcefilePath "$InstallPath\DB_SQL2K12_Build.zip" 10 diff --git a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 index 0bddb2e..1844d2c 100644 --- a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 +++ b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 @@ -2,7 +2,7 @@ [string]$AdminUsername, [string]$AdminPassword, [string]$storageAccountName, - [string]$sasToken, + [string]$sasTokenBuildContainer, [int]$dbCount ) @@ -110,7 +110,7 @@ function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $ret } } -$SourcefilePath = "https://$storageAccountName.blob.core.windows.net/build/DB_SQL2K16_Build.zip$sasToken" +$SourcefilePath = "https://$storageAccountName.blob.core.windows.net/build/DB_SQL2K16_Build.zip?$sasTokenBuildContainer" DownloadWithRetry $SourcefilePath "$InstallPath\DB_SQL2K16_Build.zip" 10 From 7d5e2bf87061e4a1fc06d1dee059b91229367ae9 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Mon, 22 Dec 2025 09:12:37 +0100 Subject: [PATCH 06/11] add azure data studio to win11 vms --- Build/ARM Deployment - SQL Hackathon v2.ps1 | 1 + Build/Powershell/Configure-TEAM_VMs.ps1 | 132 ++++++++++---------- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/Build/ARM Deployment - SQL Hackathon v2.ps1 b/Build/ARM Deployment - SQL Hackathon v2.ps1 index be5a665..53988b7 100644 --- a/Build/ARM Deployment - SQL Hackathon v2.ps1 +++ b/Build/ARM Deployment - SQL Hackathon v2.ps1 @@ -229,6 +229,7 @@ DownloadWithRetry "https://go.microsoft.com/fwlink/?LinkId=708343" "$CopyPath\St DownloadWithRetry "https://download.visualstudio.microsoft.com/download/pr/3f56df9d-6dc0-4897-a49b-ea891f9ad0f4/076e353a29908c70e24ba8b8d0daefb8/windowsdesktop-runtime-3.1.21-win-x64.exe" "$CopyPath\windowsdesktop-runtime-3.1.21-win-x64.exe" 10 DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2133900" "$CopyPath\sql-assessment-0.6.3.vsix" 10 DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2099770" "$CopyPath\managed-instance-dashboard-0.4.2.vsix" 10 +DownloadWithRetry "https://go.microsoft.com/fwlink/?linkid=2324716" "$CopyPath\AzureDataStudio-Setup-1.52.0.exe" 10 $SourcePath= (Join-Path $CurrentDir "DB_SSIS_Build\") diff --git a/Build/Powershell/Configure-TEAM_VMs.ps1 b/Build/Powershell/Configure-TEAM_VMs.ps1 index a6df103..d7cec4d 100644 --- a/Build/Powershell/Configure-TEAM_VMs.ps1 +++ b/Build/Powershell/Configure-TEAM_VMs.ps1 @@ -1,65 +1,67 @@ -param ( - [string]$SASURIKey, - [string]$StorageAccount, - [string]$Installed = "0" -) -$ErrorActionPreference = "Stop" -$InstallPath = 'C:\Install' -$LabsPath = 'C:\_SQLHACK_' -$FullLabsPath = 'C:\_SQLHACK_\LABS' -$Labs4Path = 'C:\_SQLHACK_\LABS\04-SSIS_Migration' - -################################################################## -#Create Folders for Labs and Installs -################################################################## -If(!(test-path $LabsPath)) -{ - md -Path $LabsPath -} -If((test-path $FullLabsPath)) -{ - Remove-Item $FullLabsPath -Force -Recurse -} -If(!(test-path $InstallPath)) -{ - md -Path $InstallPath -} -# md -Path $InstallPath -$Key = $SASURIKey | ConvertFrom-Json - -$StorageContext = New-AzStorageContext -StorageAccountName $StorageAccount -SasToken $Key -Get-AzStorageBlob -Context $StorageContext.Context -Container "build" -Prefix "LABS" | Get-AzStorageBlobContent -Force -Destination $LabsPath |out-null -Get-AzStorageBlob -Context $StorageContext.Context -Container "build" -Prefix "Downloads" | Get-AzStorageBlobContent -Force -Destination $InstallPath |out-null - - -######################################################################### -#Install Applications -######################################################################### -if($Installed -eq "1") -{ - # Install SSDT - Start-Process -file 'C:\Install\Downloads\SSDT-Setup-ENU.exe' -arg '/layout c:\Install\vs_install_bits /quiet /log C:\Install\SSDTLayout_install.txt' -wait - start-sleep 10 - Start-Process -file 'C:\Install\vs_install_bits\SSDT-Setup-enu.exe' -arg '/INSTALLVSSQL /install INSTALLALL /norestart /passive /log C:\Install\SSDT_install.txt' -wait - - # Install Data Mirgation Assistant - Start-Process -file 'C:\Install\Downloads\DataMigrationAssistant.msi' -arg '/qn /l*v C:\Install\dma_install.txt' -passthru - - # Install Storage Explorer - Start-Process -file 'C:\Install\Downloads\StorageExplore.exe' -arg '/VERYSILENT /ALLUSERS /norestart /LOG C:\Install\StorageExplore_install.txt' - - # Install SQL Server Management Studio - #$pathArgs = {C:\Install\SSMS-Setup.exe /S /v/qn} - #Invoke-Command -ScriptBlock $pathArgs - Start-Process -file 'C:\Install\Downloads\SSMS-Setup-ENU.exe' -arg '/passive /install /norestart /quiet /log C:\Install\SSMS_install.txt' -wait - - # install .netcore 3.1 for DMA sizing console - Start-Process -file 'C:\Install\Downloads\windowsdesktop-runtime-3.1.21-win-x64.exe' -arg '/install /quiet /norestart /log C:\Install\DotNet31x86-Install.log' -wait - # install ADS extensions - #Start-Process -file 'azuredatastudio' -arg '--install-extension "C:\Install\Downloads\sql-migration-1.0.4.vsix" --force' -wait - #Start-Process -file 'azuredatastudio' -arg '--install-extension "C:\Install\Downloads\managed-instance-dashboard-0.4.2.vsix" --force' -wait - -} -$message="Configuration Successfull" -Write-host $message -$message | out-file -FilePath "$InstallPath\SetupCompleted.txt" -Force +param ( + [string]$SASURIKey, + [string]$StorageAccount, + [string]$Installed = "0" +) +$ErrorActionPreference = "Stop" +$InstallPath = 'C:\Install' +$LabsPath = 'C:\_SQLHACK_' +$FullLabsPath = 'C:\_SQLHACK_\LABS' +$Labs4Path = 'C:\_SQLHACK_\LABS\04-SSIS_Migration' + +################################################################## +#Create Folders for Labs and Installs +################################################################## +If(!(test-path $LabsPath)) +{ + md -Path $LabsPath +} +If((test-path $FullLabsPath)) +{ + Remove-Item $FullLabsPath -Force -Recurse +} +If(!(test-path $InstallPath)) +{ + md -Path $InstallPath +} +# md -Path $InstallPath +$Key = $SASURIKey | ConvertFrom-Json + +$StorageContext = New-AzStorageContext -StorageAccountName $StorageAccount -SasToken $Key +Get-AzStorageBlob -Context $StorageContext.Context -Container "build" -Prefix "LABS" | Get-AzStorageBlobContent -Force -Destination $LabsPath |out-null +Get-AzStorageBlob -Context $StorageContext.Context -Container "build" -Prefix "Downloads" | Get-AzStorageBlobContent -Force -Destination $InstallPath |out-null + + +######################################################################### +#Install Applications +######################################################################### +if($Installed -eq "1") +{ + # Install SSDT + Start-Process -file 'C:\Install\Downloads\SSDT-Setup-ENU.exe' -arg '/layout c:\Install\vs_install_bits /quiet /log C:\Install\SSDTLayout_install.txt' -wait + start-sleep 10 + Start-Process -file 'C:\Install\vs_install_bits\SSDT-Setup-enu.exe' -arg '/INSTALLVSSQL /install INSTALLALL /norestart /passive /log C:\Install\SSDT_install.txt' -wait + + # Install Data Mirgation Assistant + Start-Process -file 'C:\Install\Downloads\DataMigrationAssistant.msi' -arg '/qn /l*v C:\Install\dma_install.txt' -passthru + + # Install Storage Explorer + Start-Process -file 'C:\Install\Downloads\StorageExplore.exe' -arg '/VERYSILENT /ALLUSERS /norestart /LOG C:\Install\StorageExplore_install.txt' + + # Install SQL Server Management Studio + #$pathArgs = {C:\Install\SSMS-Setup.exe /S /v/qn} + #Invoke-Command -ScriptBlock $pathArgs + Start-Process -file 'C:\Install\Downloads\SSMS-Setup-ENU.exe' -arg '/passive /install /norestart /quiet /log C:\Install\SSMS_install.txt' -wait + + # install .netcore 3.1 for DMA sizing console + Start-Process -file 'C:\Install\Downloads\windowsdesktop-runtime-3.1.21-win-x64.exe' -arg '/install /quiet /norestart /log C:\Install\DotNet31x86-Install.log' -wait + # install ADS extensions + #Start-Process -file 'azuredatastudio' -arg '--install-extension "C:\Install\Downloads\sql-migration-1.0.4.vsix" --force' -wait + #Start-Process -file 'azuredatastudio' -arg '--install-extension "C:\Install\Downloads\managed-instance-dashboard-0.4.2.vsix" --force' -wait + + # Install Azure Data Studio + Start-Process -File 'C:\Install\Downloads\AzureDataStudio-Setup-1.52.0.exe' -Arg '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /MERGETASKS=!runcode' -Wait +} +$message="Configuration Successfull" +Write-host $message +$message | out-file -FilePath "$InstallPath\SetupCompleted.txt" -Force From 28c800e78104d122b25c58363a9345342d5457bb Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Mon, 22 Dec 2025 09:12:56 +0100 Subject: [PATCH 07/11] move jumpservers to win11 --- .../ARM Template - SQL Hackathon - Jump Servers - v2.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json index 2be360b..56f3f57 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Jump Servers - v2.json @@ -86,8 +86,8 @@ }, "imageReference": { "publisher": "MicrosoftWindowsDesktop", - "offer": "Windows-10", - "sku": "win10-22h2-pro-g2", + "offer": "Windows-11", + "sku": "win11-25h2-pro", "version": "latest" } }, From 7aadacf5452864126e18fb9cc2159a9956e96759 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Mon, 22 Dec 2025 09:13:43 +0100 Subject: [PATCH 08/11] enable public network access for storage account --- .../ARM Template - SQL Hackathon - Network - v2.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json index ed2d7f3..9164e53 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - Network - v2.json @@ -30,7 +30,7 @@ "resources": [ { "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2019-04-01", + "apiVersion": "2022-09-01", "name": "[variables('storageAccountName')]", "location": "[variables('location')]", "sku": { @@ -41,7 +41,11 @@ "tags": { "SecurityControl": "Ignore" }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + ], "properties": { + "publicNetworkAccess": "Enabled", "networkAcls": { "bypass": "AzureServices", "virtualNetworkRules": [], From 2762390032467e582f9d05f0c99ee1a49e485415 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Mon, 22 Dec 2025 09:13:50 +0100 Subject: [PATCH 09/11] spelling --- Build/ARM Deployment - SQL Hackathon v2.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build/ARM Deployment - SQL Hackathon v2.ps1 b/Build/ARM Deployment - SQL Hackathon v2.ps1 index 53988b7..6a0590a 100644 --- a/Build/ARM Deployment - SQL Hackathon v2.ps1 +++ b/Build/ARM Deployment - SQL Hackathon v2.ps1 @@ -364,6 +364,6 @@ Write-Host -BackgroundColor Black -ForegroundColor Yellow "Enviroment Build in p Write-Warning "NOTE: THE FOLLOWING POST BUILD TASKS ARE REQUIRED." Write-Warning "1. DataFactory Build Ok. You will need to start the SSIS integration runtime and enable AHUB" Write-Warning "2. Restore databases for SSIS + Monitoring labs by running the Launch_SQL_MI_configuration.ps1. Choose a remote TEAM VM. Note: Only run once." -Write-Warning "3. All labs and documaention can be found on TEAMVM's in C:\_SQLHACK_\LABS" +Write-Warning "3. All labs and documention can be found on TEAMVM's in C:\_SQLHACK_\LABS" From b1eb5966299b1ea702d08fe710ecc9542bcd2102 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Tue, 23 Dec 2025 12:23:10 +0100 Subject: [PATCH 10/11] minor fixes in template and restore script --- .../ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json | 2 +- .../ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json | 4 ++-- Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json index 26d062b..49255a6 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K12.json @@ -18,7 +18,7 @@ "dbCount": { "type": "int", - "defaultvalue": 3, + "defaultValue": 3, "metadata": { "description": "Select the number of db to add." } diff --git a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json index 535ebff..6af89a8 100644 --- a/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json +++ b/Build/ARM Templates/ARM Template - SQL Hackathon - SQL2K16.json @@ -30,7 +30,7 @@ "dbCount": { "type": "int", - "defaultvalue": 3, + "defaultValue": 3, "metadata": { "description": "Select the number of db to add." } @@ -279,7 +279,7 @@ "timestamp":123456783 }, "protectedSettings": { - "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername \"', parameters('adminUsername'), '\" -AdminPassword \"', parameters('adminPassword'), '\" -storageAccountName \"', parameters('storageAccount'), '\" -sasTokenBuildContainer \"', parameters('sasTokenBuildContainer'), -dbCount ', parameters('dbCount'))]", + "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File ', variables('sqlCustomScriptFileName'), ' -AdminUsername \"', parameters('adminUsername'), '\" -AdminPassword \"', parameters('adminPassword'), '\" -storageAccountName \"', parameters('storageAccount'), '\" -sasTokenBuildContainer \"', parameters('sasTokenBuildContainer'), '\" -dbCount ', parameters('dbCount'))]", "storageAccountName": "[parameters('storageAccount')]", "storageAccountKey": "[Concat(listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccount')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]", "fileUris": [ diff --git a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 index 1844d2c..d9504bb 100644 --- a/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 +++ b/Build/Powershell/ARM_Deployment-SQL_Build_SQL2K16.ps1 @@ -70,8 +70,8 @@ function IfNotExistsCreateFolder([string] $folderPath) } #Set Veriables -$InstallPath = 'D:\Install' -$BackupPath = 'D:\Backups' +$InstallPath = 'C:\Install' +$BackupPath = 'C:\Backups' $DataPath = 'F:\Data' #Create Folders for Labs and Installs From 8c9371a5010a7ffdf6bf873a449e7c78d16fbb47 Mon Sep 17 00:00:00 2001 From: Adrian Bossert Date: Tue, 23 Dec 2025 12:23:43 +0100 Subject: [PATCH 11/11] make TeamVM setup powershell5 compatible --- Build/ARM Deployment - SQL Hackathon v2.ps1 | 109 +++++++++++++++----- 1 file changed, 84 insertions(+), 25 deletions(-) diff --git a/Build/ARM Deployment - SQL Hackathon v2.ps1 b/Build/ARM Deployment - SQL Hackathon v2.ps1 index 6a0590a..ee3e4bf 100644 --- a/Build/ARM Deployment - SQL Hackathon v2.ps1 +++ b/Build/ARM Deployment - SQL Hackathon v2.ps1 @@ -37,7 +37,20 @@ If(-not(Get-InstalledModule Az -ErrorAction silentlycontinue)){ Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force -AllowClobber } +# Ensure ThreadJob module is available for PS 5.1 compatibility +if (-not (Get-Command Start-ThreadJob -ErrorAction SilentlyContinue)) { + try { + Install-Module ThreadJob -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop + } catch { + Write-Warning ("ThreadJob install failed: {0}" -f $_.Exception.Message) + } + try { + Import-Module ThreadJob -ErrorAction Stop + } catch { + Write-Warning ("ThreadJob import failed: {0}" -f $_.Exception.Message) + } +} Write-Host -BackgroundColor Black -ForegroundColor Yellow "Setting Enviroment Variables....................................................." $subscriptionID = (Get-AzContext).Subscription.id @@ -320,11 +333,27 @@ $TemplateUri = (Join-Path $CurrentDir "ARM Templates\ARM Template - SQL Hackatho New-AzResourceGroupDeployment -ResourceGroupName $TeamRG -TemplateUri $TemplateUri -Name "TeamVMBuild" -vmCount $TeamVMCount -SharedResourceGroup $SharedRG -SASURIKey $JsonSASUriContainerBuild -StorageAccount $StorageAccount -adminPassword $adminpassword -adminUsername $adminUsername $AzureVMsRunning = Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} -$AzureVMsRunning | ForEach-Object -ThrottleLimit 22 -Parallel{ - Restart-AzVM -ResourceGroupName $_.ResourceGroupName -Name $_.Name - Write-host "$($_.Name) restarted " +# Manual throttling to 22 concurrent thread jobs +$throttle = 22 +$jobs = @() +foreach ($vm in $AzureVMsRunning) { + $rg = $vm.ResourceGroupName + $name = $vm.Name + while (($jobs | Where-Object State -eq 'Running').Count -ge $throttle) { + Start-Sleep -Milliseconds 300 + } + $job = Start-ThreadJob -Name "Restart-$name" -ScriptBlock { + param($rg, $name) + Restart-AzVM -ResourceGroupName $rg -Name $name + "$name restarted" + } -ArgumentList $rg, $name + $jobs += $job } +Wait-Job -Job $jobs | Out-Null +Receive-Job -Job $jobs | ForEach-Object { Write-Host $_ } +Remove-Job -Job $jobs + Write-Host -BackgroundColor Black -ForegroundColor Yellow "Waiting for 3 minutes ........................................................." start-sleep -s 180 Get-AzVM -ResourceGroupName $TeamRG -status | Where-Object {$_.PowerState -eq "VM running"} |Format-Table -Property Name, PowerState @@ -336,34 +365,64 @@ $ScriptPath= (Join-Path $CurrentDir $Script) [string]$Installed = "1" # 1 to install tool and labs, 0 for labs only $VMs = Get-AzVM -ResourceGroupName $TeamRG #-ResourceType Microsoft.Compute/virtualMachines -$VMs | ForEach-Object -ThrottleLimit 22 -Parallel { - $RG = $_.ResourceGroupName - $VMName= $_.Name - $Message = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- Configuration starting..." - write-host $Message - $out = Invoke-AzVMRunCommand -ResourceGroupName $RG -Name $VMName -CommandId RunPowerShellScript -ScriptPath $using:ScriptPath -Parameter @{StorageAccount = $using:StorageAccount; SASURIKey = $using:JsonSASUriContainerBuild; Installed = $using:Installed} - #Formating the Output with the VM name - if($out.value[1].Message) - { - $status= "failed" - $ForegroundColor="Red" - $message = $out.value[1].Message +$jobs = @() +foreach ($vm in $VMs) { + $RG = $vm.ResourceGroupName + $VMName = $vm.Name + $Message = "$(Get-Date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- Configuration starting..." + Write-Host $Message + + $jobs = $jobs | Where-Object { $_.State -eq 'Running' } + while ($jobs.Count -ge $throttle) { + Start-Sleep -Milliseconds 300 + $jobs = $jobs | Where-Object { $_.State -eq 'Running' } } - else { - $status= "successfull" - $ForegroundColor="White" - $message = "" - } - $output = "$(get-date -Format 'dd/MM/yyyy hh:mm:ss'): $VMName -- status: $status " + $message - Write-host $output - -ForegroundColor $ForegroundColor + + $job = Start-ThreadJob -Name "Config-$VMName" -ScriptBlock { + param($rg, $vmName, $scriptPath, $storageAccount, $sasJson, $installed) + try { + $out = Invoke-AzVMRunCommand ` + -ResourceGroupName $rg ` + -Name $vmName ` + -CommandId RunPowerShellScript ` + -ScriptPath $scriptPath ` + -Parameter @{ + StorageAccount = $storageAccount + SASURIKey = $sasJson + Installed = $installed + } + + if ($out -and $out.Value -and $out.Value.Count -gt 1 -and $out.Value[1].Message) { + $status = "failed" + $ForegroundColor = "Red" + $message = $out.Value[1].Message + } else { + $status = "successfull" + $ForegroundColor = "White" + $message = "" + } + } catch { + $status = "failed" + $ForegroundColor = "Red" + $message = $_.Exception.Message + } + + if (-not $message) { $message = "" } + $output = "$(Get-Date -Format 'dd/MM/yyyy hh:mm:ss'): $vmName -- status: $status " + $message + [pscustomobject]@{ Line = $output; Color = $ForegroundColor } + } -ArgumentList $RG, $VMName, $ScriptPath, $StorageAccount, $JsonSASUriContainerBuild, $Installed + + $jobs += $job } +Wait-Job -Job $jobs | Out-Null +Receive-Job -Job $jobs | ForEach-Object { Write-Host $_.Line -ForegroundColor $_.Color } +Remove-Job -Job $jobs + Write-Host -BackgroundColor Black -ForegroundColor Yellow "Enviroment Build in progress. Please check RG deployments for errors." Write-Warning "NOTE: THE FOLLOWING POST BUILD TASKS ARE REQUIRED." Write-Warning "1. DataFactory Build Ok. You will need to start the SSIS integration runtime and enable AHUB" Write-Warning "2. Restore databases for SSIS + Monitoring labs by running the Launch_SQL_MI_configuration.ps1. Choose a remote TEAM VM. Note: Only run once." -Write-Warning "3. All labs and documention can be found on TEAMVM's in C:\_SQLHACK_\LABS" - - +Write-Warning "3. All labs and documention can be found on TEAMVM's in C:\_SQLHACK_\LABS" \ No newline at end of file