├── Get-AzureRmVMHealth.ps1 ├── LICENSE ├── README.md ├── Register-Images.ps1 ├── ResizeCS.ps1 ├── SECURITY.md └── TestDeployments ├── Test1.ps1 ├── Test10.ps1 ├── Test2.ps1 ├── Test3.ps1 ├── Test4-withEP.ps1 ├── Test4.ps1 ├── Test5.ps1 ├── Test6.ps1 ├── Test7.ps1 ├── Test8.ps1 ├── Test9.ps1 └── TestCases.txt /Get-AzureRmVMHealth.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string]$resourceGroupName, 3 | [string]$name, 4 | [string]$path, 5 | [switch]$openJsonFile = $true 6 | ) 7 | 8 | function Get-JsonFromSerialLog ($serialLogFilePath) 9 | { 10 | $serialLogFileName = split-path -Path $serialLogFilePath -Leaf 11 | $jsonFileName = "$($serialLogFileName.SubString(0,$serialLogFileName.Length-4)).json" 12 | $jsonFilePath = "$env:TEMP\$jsonFileName" 13 | $serialLog = get-content -Path $serialLogFilePath 14 | for ($i = ($serialLog.count); $i -ne 0; $i--) { 15 | if ($serialLog[$i] -match 'Microsoft Azure VM Health Report - End') 16 | { 17 | $jsonString = $serialLog[$i-1] 18 | try 19 | { 20 | $json = $jsonString | ConvertFrom-Json -ErrorAction SilentlyContinue 21 | } 22 | catch 23 | { 24 | write-verbose "ConvertFrom-Json failed, will try next entry" 25 | $i-- 26 | } 27 | if ($json) {break} 28 | } 29 | } 30 | 31 | if ($json){$json | ConvertTo-Json -Depth 99 | out-file $jsonFilePath} 32 | if (test-path $jsonFilePath) 33 | { 34 | get-content $jsonFilePath 35 | "VM Health JSON: $jsonFilePath" 36 | if ($openJsonFile) 37 | { 38 | invoke-item $jsonFilePath 39 | } 40 | } 41 | else 42 | { 43 | write-host "No VM Health Report entries found." 44 | } 45 | } 46 | 47 | if ($resourceGroupName -and $name) 48 | { 49 | $vm = get-azurermvm -ResourceGroupName $resourceGroupName -Name $name -ErrorAction Stop 50 | $vmstatus = $vm | get-azurermvm -status -ErrorAction Stop 51 | 52 | if ($vm.DiagnosticsProfile.Bootdiagnostics.Enabled) 53 | { 54 | if ($vmstatus.bootdiagnostics.ConsoleScreenshotBlobUri) 55 | { 56 | $consoleScreenshotBlobUri = $vmstatus.bootdiagnostics.ConsoleScreenshotBlobUri 57 | } 58 | else 59 | { 60 | "ConsoleScreenshotBlobUri property not populated" 61 | exit 62 | } 63 | } 64 | else 65 | { 66 | "Bootdiagnostics: $($vm.DiagnosticsProfile.Bootdiagnostics.Enabled)" 67 | exit 68 | } 69 | 70 | $storageAccountName = $consoleScreenshotBlobUri.split('/')[2].split('.')[0] 71 | $storageContainer = $consoleScreenshotBlobUri.split('/')[3] 72 | #TODO If boot diag storage account can reside in a different RG than the VM's RG, need a different way to get the RG of the boot diag storage account 73 | $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey (Get-AzureRmStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName)[0].Value 74 | $blobs = get-azurestorageblob -Container $storageContainer -Context $storageContext 75 | $log = $blobs | where {$_.Name.EndsWith('.serialconsole.log')} | select -first 1 76 | $log | Get-AzureStorageBlobContent -Destination $env:TEMP -Force | Out-Null 77 | $logFilePath = "$env:TEMP\$($log.Name)" 78 | Get-JsonFromSerialLog $logFilePath 79 | "serial log: $logFilePath" 80 | } 81 | elseif ($path) 82 | { 83 | if (test-path $path) 84 | { 85 | Get-JsonFromSerialLog $path 86 | } 87 | else 88 | { 89 | Write-Error "File not found: $path" 90 | exit 91 | } 92 | } 93 | else 94 | { 95 | write-error "Use -resourceGroupName and -name to download the log, or -path to parse output from log already downloaded." 96 | exit 97 | } 98 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Microsoft Azure 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Resize Cloud Service 2 | 3 | This script is designed to assist in resizing VMs which cannot be resized through standard commands. Azure Service Management (ASM) VMs, which are also called classic VMs, can be resized to a limited set of sizes based on the physical hardware supporting the VM. To change the VM size to a size not supported by the current hosting hardware requires the VM deployment to be deleted and then recreated. This script performs the action to delete and recreate the VM deployment. 4 | 5 | If there are multiple VMs in a Cloud Service, this script will resize all VMs in the selected deployment. 6 | 7 | This script is designed to only be used when the VM cannot be resized through the standard resize action. If it is possible to change the VM size using the standard resize options, then please use the standard resize command available through the Azure portal, Azure PowerShell or Azure command line interface (Azure CLI). Furthermore, this script requires the caller to specify flags to allow actions which will cause changes in the configuration of the VM deployment. 8 | 9 | ## Parameters 10 | Parameter | Type | Description 11 | :----- | :------: | ------ 12 | CloudService | String | Name of Cloud Service to be resized 13 | NewSize | String | New VM size for all VMs in the Cloud Service 14 | OutputFile | String | Output file to contain all details of the execution 15 | AllowServiceVipChange | Switch | Allow VIP (Internet IP address for cloud service) to change through the resize operation. To maintain the VIP the cloud service must be using a reserved IP address. 16 | AllowVMPublicIPChange | Switch | Allow the public IP address of a VM to change. Public IP addresses cannot use a static IP address for classic VMs so this switch must be set if the deployment contains any VMs that have a public IP address configured on it. 17 | AllowVNetIPChange | Switch | Allow the VNet IP address of VMs to change. This must be set if any VM does not have a static VNet IP address configured on it. 18 | AllowRemovalOfAffinityGroup | Switch | Allow the cloud service to be deleted and created if it is initially configured to use an affinity group. The affinity group must be removed to enable the VM deployment to be moved to new physical hardware that supports the requested VM size. 19 | 20 | 21 | ## Notable error messages 22 | Error message | Explanation 23 | :----- | :------ 24 | VMs in the cloud service (Service Name) can be resized to (New Size) through standard resize operations. |This script will not resize a VM that can be resized through the standard resize operations. Please use the standard operations to resize the VM. 25 | The size (New Size) is not a valid VM size in the current region. |Some sizes are not available in all regions. Please select a different VM size. 26 | This script does not support cloud services with custom DNS configuration. | This is a limitation of the initial script. Community support for this action is welcome. 27 | This script does not support cloud services with Reverse FQDN configured. | This is a limitation of the initial script. Community support for this action is welcome. 28 | The VM: (VM Name) has more data disks than are supported on the selected VM size. | Different VM sizes support a different number of data disks (typically two data disks per vCPU). The selected VM size does not support enough data disks for one or more of the VMs in the current deployment 29 | One of the original VMs is using premium storage, and the selected size is not a DS or GS size. | If any VM is using premium storage, then the new VM size must also support premium storage. 30 | The VM: (VM Name) is currently in a Provisioning state. Please wait for provisioning to complete before attempting to resize the VM. | VMs in the provisioning state should not be shutdown. Therefore, the script will block any attempt to resize a VM that is in the provisioning state. 31 | This script does not support changing the size of VMs that have multiple NICs. | This is a limitation of the initial script. Community support for this action is welcome. 32 | This script does not support changing the size of VMs use network security groups. | This is a limitation of the initial script. Community support for this action is welcome. 33 | -------------------------------------------------------------------------------- /Register-Images.ps1: -------------------------------------------------------------------------------- 1 | Param([string]$sourceURI = $(Read-Host -prompt "Specify the full URL to the source blob"), 2 | [string]$storageId = $(Read-Host -prompt "Specify the full storage account ARM-ID"), 3 | [string]$location = $(Read-Host -prompt "Specify the source location"), 4 | [string]$imageName = $(Read-Host -prompt "Specify the image name")) 5 | 6 | 7 | $RGName="Images" 8 | $location = $location.Replace(' ','') 9 | $snapName=$imageName+$location+"-snap" 10 | $imageNameRegional=$imageName+$location 11 | 12 | $subscriptions=Get-AzureRmSubscription 13 | 14 | foreach ($sub in $subscriptions){ 15 | 16 | Set-AzureRmContext -Subscription $sub.Name 17 | $ctx = Get-AzureRmContext 18 | 19 | Start-Job {param ($ctx,$sub,$location,$sourceURI,$storageId,$RGName,$snapName,$imageNameRegional) 20 | 21 | # 22 | # Create a snapshot from the remote blob 23 | # 24 | write-host "Creating Snapshot" 25 | $snapshotConfig = New-AzureRmSnapshotConfig -AccountType StandardLRS ` 26 | -OsType Windows ` 27 | -Location $location ` 28 | -CreateOption Import ` 29 | -SourceUri $sourceURI ` 30 | -StorageAccountId $storageId 31 | 32 | $snap = New-AzureRmSnapshot -AzureRmContext $ctx ` 33 | -ResourceGroupName $RGName ` 34 | -SnapshotName $snapName ` 35 | -Snapshot $snapshotConfig 36 | 37 | # 38 | # Create an image from the snapshot 39 | # 40 | write-host "Creating Image from Snapshot" 41 | $imageConfig = New-AzureRmImageConfig -Location $location 42 | 43 | Set-AzureRmImageOsDisk -Image $imageConfig ` 44 | -OsType Windows ` 45 | -OsState Generalized ` 46 | -SnapshotId $snap.Id 47 | 48 | New-AzureRmImage -AzureRmContext $ctx ` 49 | -ResourceGroupName $RGName ` 50 | -ImageName $imageNameRegional ` 51 | -Image $imageConfig 52 | 53 | # 54 | # Cleanup snapshot 55 | # 56 | write-host "Deleting Snapshot" 57 | Remove-AzureRmSnapshot -AzureRmContext $ctx -ResourceGroupName $RGName -SnapshotName $snapName -force 58 | 59 | } -ArgumentList $ctx,$sub,$location,$sourceURI,$storageId,$RGName,$snapName,$imageNameRegional 60 | } 61 | -------------------------------------------------------------------------------- /ResizeCS.ps1: -------------------------------------------------------------------------------- 1 | ## 2 | # 3 | # 4 | # ResizeCS - Script to delete and resize all VMs in a cloud service to an new size. 5 | # 6 | # Note: This script will resize all VMs in the cloud service to the same size. After 7 | # executing this script individual VMs can be resized via a reboot to alternate sizes 8 | # that are supported by the specific hardware cluster where the cloud service was 9 | # redeployed. 10 | # 11 | ### 12 | 13 | [CmdletBinding()] 14 | Param( 15 | [string]$CloudService = $(Read-Host -prompt "Specify the the Cloud Service that contains VMs to be resized"), 16 | [string]$NewSize = $(Read-Host -prompt "Specify the size to make all VMs in the cloud service"), 17 | [string]$OutputFile = $(Read-Host -prompt "Specify a file to store the output of the operations"), 18 | [switch]$AllowServiceVipChange, 19 | [switch]$AllowVMPublicIPChange, 20 | [switch]$AllowVNetIPChange, 21 | [switch]$AllowRemovalOfAffinityGroup 22 | ) 23 | 24 | 25 | $ErrorActionPreference = "Stop" 26 | 27 | # 28 | #region Verify VM Size 29 | # 30 | 31 | $validSizes = Get-AzureRoleSize 32 | $isNewSizeValid = $false 33 | foreach ($validSize in $validSizes ){ 34 | if ($validSize.InstanceSize.ToLower() -eq $NewSize) { 35 | $isNewSizeValid = $true 36 | $newsizeDiskCount = $validSize.MaxDataDiskCount 37 | } 38 | } 39 | 40 | if (-Not($isNewSizeValid)) { 41 | write-host 42 | write-host "ERROR: The size" $NewSize "is not a valid VM size" 43 | write-host 44 | return 45 | } 46 | 47 | #endregion 48 | 49 | # 50 | #region Check to see if reboot can be used to resize 51 | # 52 | # 53 | # Verify that specified VM size is not already supported via a reboot 54 | # 55 | # Note: This requires a bit of a work-around due to the fact that VM sizes available 56 | # in an existing deployment are only returned when querying all cloud servcies, 57 | # and not returned when a specficific cloud service is queried 58 | # 59 | $allCloudServices = Get-AzureService 60 | $foundCloudService = $false 61 | $canRebootToResize = $false 62 | 63 | if ($allCloudServices.Count -eq "0"){ 64 | write-host 65 | write-host "ERROR: No cloud services were found in the default subscription." 66 | write-host 67 | return 68 | } 69 | 70 | foreach ($service in $allCloudServices){ 71 | if ($service.ServiceName.ToLower() -eq $CloudService.ToLower()){ 72 | $foundCloudService = $true 73 | 74 | foreach ($vmsize in $service.VirtualMachineRoleSizes) { 75 | if($vmsize.ToLower() -eq $NewSize.ToLower()){ 76 | $canRebootToResize = $true 77 | } 78 | } 79 | } 80 | } 81 | 82 | if (-Not ($foundCloudService)) { 83 | write-host 84 | write-host "ERROR: Cloud Service" $CloudService "was not found." 85 | write-host 86 | return 87 | } 88 | 89 | if ($canRebootToResize){ 90 | write-host 91 | write-host "ERROR: VMs in the cloud service" $CloudService "can be resized to" $NewSize "through standard resize operations." 92 | write-host 93 | return 94 | } 95 | 96 | #endregion 97 | 98 | 99 | # 100 | # Get CS and Deployment details 101 | # 102 | write-host 103 | Write-Host "INFO: Reading Cloud Service Details" 104 | $service = Get-AzureService -ServiceName $CloudService 105 | "Service Details:" | Out-File $OutputFile 106 | $service | Out-File -Append $OutputFile 107 | 108 | $deployment = Get-AzureDeployment -ServiceName $CloudService 109 | "Deployment Details" | Out-File -Append $OutputFile 110 | $deployment | Out-File -Append $OutputFile 111 | 112 | $VNet = Get-AzureDeployment -ServiceName $CloudService | Select Vnetname 113 | $VNet | Out-File -Append $OutputFile 114 | 115 | #region Ensure the existing CloudService is not in an AffinityGroup 116 | # 117 | 118 | $isAffinityGroup = $false 119 | if ($service.AffinityGroup -ne $null){ 120 | $isAffinityGroup = $true 121 | $AffinityGroup = Get-AzureAffinityGroup -Name $service.AffinityGroup 122 | $location = $AffinityGroup.Location 123 | 124 | 125 | if ($AllowRemovalOfAffinityGroup) { 126 | write-host 127 | write-host "WARNING: Continuing with cloud service in an Affinity Group. This will result in the CloudService being recreated without an Affinity Group." | Out-File $OutputFile 128 | } else { 129 | write-host 130 | write-host "ERROR: The selected cloud service is deployed to an affinity group. Please specify '-AllowRemovalOfAffinityGroup' to resize and allow the VMs to be removed from the Affinity Group." 131 | write-host 132 | return 133 | } 134 | 135 | } else { 136 | $location = $service.Location 137 | } 138 | #endregion 139 | 140 | 141 | #region Verify new size is available in the existing region 142 | # 143 | $locationDetails = Get-AzureLocation | where {$_.DisplayName.ToString() -eq $location} 144 | 145 | $validSizesForRegion = $locationDetails.VirtualMachineRoleSizes 146 | 147 | $isNewSizeValid = $false 148 | foreach ($validSize in $validSizesForRegion ){ 149 | if ($validSize.ToLower() -eq $NewSize) { 150 | $isNewSizeValid = $true 151 | } 152 | } 153 | 154 | if (-Not($isNewSizeValid)) { 155 | write-host 156 | write-host "ERROR: The size" $NewSize "is not a valid VM size in the current region:" $location 157 | write-host 158 | return 159 | } 160 | 161 | #endregion 162 | 163 | #region check for reserved VIP 164 | # 165 | 166 | # 167 | # Verify VIP is reserved or allow IP changes is set 168 | # 169 | write-host "INFO: Checking for reserved IP address on VIP" 170 | 171 | $reservedIPName = $deployment.VirtualIPs[0].ReservedIPName 172 | 173 | if ($reservedIPName) { 174 | "Reserved VIP Details:" | Out-File -Append $OutputFile 175 | Get-AzureReservedIP -ReservedIPName $reservedIPName | Out-File -Append $OutputFile 176 | } else { 177 | if ($AllowServiceVipChange) { 178 | write-host 179 | write-host "WARNING: Continuing with unreserved VIP. IP address of VIP will change after resize." 180 | "WARNING: Continuing with unreserved VIP. IP address of VIP will change after resize." | Out-File $OutputFile 181 | } else { 182 | write-host 183 | write-host "ERROR: The selected cloud service does not have a reserved VIP. Please specify '-AllowServiceVipChange' to resize and allow the IP address to change." 184 | write-host 185 | return 186 | } 187 | 188 | } 189 | 190 | #endregion 191 | 192 | #region check for custom DNS and reverse FQDN 193 | 194 | # 195 | # TODO: Add support for Cloud Service with custom DNS configuration 196 | # 197 | if ($deployment.DnsSettings) { 198 | write-host 199 | write-host "ERROR: This script does not support cloud services with custom DNS configuration" 200 | write-host 201 | return 202 | } 203 | 204 | 205 | # 206 | # TODO: Add support for Cloud Service with Reverse DNS Configuration 207 | # 208 | if ($service.ReverseDnsFqdn) { 209 | write-host 210 | write-host "ERROR: This script does not support cloud services with Reverse FQDN configured" 211 | write-host 212 | return 213 | } 214 | 215 | #endregion 216 | 217 | 218 | # 219 | # Get the ILB if one is in use 220 | # 221 | $internalLB = Get-AzureInternalLoadBalancer -ServiceName $CloudService 222 | if ($internalLB) { 223 | Write-host "INFO: Getting ILB Configuration" 224 | "Internal LB:" | Out-File -Append $OutputFile 225 | $internalLB | Out-File -Append $OutputFile 226 | } 227 | 228 | 229 | 230 | # 231 | # Gather the details for each VM 232 | # 233 | 234 | write-host "INFO: Reading VM details" 235 | $vms = Get-AzureVM -ServiceName $CloudService 236 | 237 | $ipForwardingStatuses = @() 238 | 239 | foreach ($vm in $vms){ 240 | 241 | write-host "INFO: Getting Details for VM:" $vm.name 242 | $vm | Out-File -Append $OutputFile 243 | 244 | $SubNet = Get-AzureSubnet -VM $vm 245 | "Subnet:" | Out-File -Append $OutputFile 246 | $SubNet | Out-File -Append $OutputFile 247 | 248 | $Endpoints = Get-AzureEndpoint -VM $vm 249 | "Endpoints:" | Out-File -Append $OutputFile 250 | $Endpoints | Out-File -Append $OutputFile 251 | 252 | $OSDisk = $vm.vm.OSVirtualHardDisk 253 | "OS Disk:" | Out-File -Append $OutputFile 254 | $OSDisk | Out-File -Append $OutputFile 255 | 256 | $DataDisks = $vm.vm.DataVirtualHardDisks 257 | "Data Disks:" | Out-File -Append $OutputFile 258 | $DataDisks | Out-File -Append $OutputFile 259 | 260 | 261 | $vmExtensions = Get-AzureVMExtension -VM $vm 262 | "VM Extensions:" | Out-File -Append $OutputFile 263 | $vmExtensions | Out-File -Append $OutputFile 264 | 265 | # 266 | # Verify the new size will support the number of data disks 267 | # 268 | if ($DataDisks.count -gt $newsizeDiskCount) { 269 | write-host 270 | write-host "ERROR: The VM:" $vm.name "has more data disks than are supported on the selected VM size." 271 | write-host 272 | return 273 | } 274 | 275 | #region Check for Premium Storage Compatability 276 | # 277 | # Verify that we are not trying to use a non-premium VM with premium storage 278 | # 279 | $usingPremiumStorage = $false 280 | if ($OSDisk.IOType -eq "Provisioned") { 281 | $usingPremiumStorage = $true 282 | } 283 | foreach ($disk in $DataDisks) { 284 | if ($disk.IOType -eq "Provisioned") { 285 | $usingPremiumStorage = $true 286 | } 287 | } 288 | 289 | if ($usingPremiumStorage) { 290 | if (($NewSize -like "Standard_DS*") -or ($NewSize -like "Standard_GS*")){ 291 | # Size is good 292 | } else { 293 | write-host 294 | write-host "Error: One of the original VMs is using premium storage, and the selected size is not a DS or GS size." 295 | write-host 296 | return 297 | } 298 | } 299 | 300 | #endregion 301 | 302 | # 303 | #region Warn on any IP address changes 304 | # 305 | # Check for Public IP addresses and warn that they will change 306 | # 307 | if ($vm.PublicIpAddress ) { 308 | if ($AllowVMPublicIPChange){ 309 | write-host "WARNING: Public IP address for VM:" $vm.Name "will change after resize." 310 | } else { 311 | write-host 312 | write-host "ERROR: The VM:" $vm.Name "has a public IP address which will change. Please specify '-AllowVMPublicIPChange' to resize and allow the IP address to change." 313 | write-host 314 | return 315 | } 316 | } 317 | 318 | # Check for static VNet IP addresses and warn that VNet address will change if not static 319 | $StaticIP = Get-AzureStaticVNetIP -VM $vm.vm 320 | 321 | if ($StaticIP) { 322 | "Static IP address:" | Out-File -Append $OutputFile 323 | $StaticIP | Out-File -Append $OutputFile 324 | } else { 325 | if ($AllowVNetIPChange) { 326 | write-host "WARNING: VNet IP address for VM:" $vm.Name "may change after resize." 327 | } else { 328 | write-host 329 | write-host "ERROR: The VM:" $vm.name "is not configured for a static VNet IP address. Please specify '-AllowVNetIPChange' to resize allowing the VNet IP address of the VM to change." 330 | write-host 331 | return 332 | } 333 | } 334 | 335 | #endregion 336 | 337 | # Get the status for IP Forwarding 338 | $ipForwardingStatus = Get-AzureIPForwarding -VM $vm -ServiceName $CloudService 339 | "IP Forwarding Status:" | Out-File -Append $OutputFile 340 | $ipForwardingStatus| Out-File -Append $OutputFile 341 | 342 | $ipForwardingStatuses += $ipForwardingStatus 343 | 344 | # 345 | #region Block running if any VM is in a provisioning state 346 | # 347 | if ($vm.InstanceStatus -like "*Provisioning*"){ 348 | write-host 349 | write-host "ERROR: The VM:" $vm.Name "is currently in a Provisioning state. Please wait for provisioning to complete before attempting to resize the VM." 350 | write-host 351 | return 352 | } 353 | #endregion 354 | 355 | 356 | # 357 | #region Warn if any VM is in a stopped or stopped-deallocated state 358 | # 359 | if ($vm.InstanceStatus -like "*Stop*"){ 360 | write-host "WARNING: The following VM is currently stopped and will be restarted at the end of this script:" $vm.Name 361 | } 362 | #endregion 363 | 364 | # 365 | #region Block if using multiple NICs or NSGs 366 | # 367 | # 368 | # TODO: Extend script to support VMs with multiple NICs 369 | # 370 | # 371 | $multiNic = Get-AzureNetworkInterfaceConfig -VM $vm 372 | if ($multiNic) { 373 | write-host 374 | write-host "ERROR: This script does not support changing the size of VMs that have multiple NICs." 375 | write-host 376 | return 377 | } 378 | 379 | # 380 | # TODO: Extend script to support VMs with network security groups 381 | # 382 | # 383 | $nsg = Get-AzureNetworkSecurityGroupAssociation -VM $vm -ServiceName $vm.ServiceName -ErrorAction SilentlyContinue 384 | if ($nsg) { 385 | write-host 386 | write-host "ERROR: This script does not support changing the size of VMs use network security groups." 387 | write-host 388 | return 389 | } 390 | 391 | #endregion 392 | 393 | } 394 | 395 | 396 | # 397 | # Pause to get user confirmation before deleting cloud service 398 | # 399 | write-host 400 | write-host "Please review details. Click Enter to continue or CTRL+C to exit script" 401 | write-host 402 | 403 | pause 404 | write-host 405 | 406 | # 407 | # Delete deployment saving all disks 408 | # 409 | Write-Host "Deleting the deployment" 410 | Remove-AzureDeployment -ServiceName $CloudService -Slot Production -Force 411 | 412 | try { 413 | 414 | #region Wait for disks to detach 415 | # 416 | # Wait for disks to detach 417 | # 418 | foreach ($vm in $vms) { 419 | 420 | # Check OS Disk 421 | $OSDisk = $vm.vm.OSVirtualHardDisk 422 | $disk = Get-AzureDisk -DiskName $OSDisk.DiskName 423 | while ($disk.AttachedTo -ne $null) { 424 | Write-Host "Waiting for disks to detach. VM:" $vm.Name "Disk:" $disk.DiskName 425 | Sleep -Seconds 20 426 | $disk = Get-AzureDisk -DiskName $OSDisk.DiskName 427 | } 428 | 429 | # Check Data Disks 430 | foreach ($datadisk in $vm.vm.DataVirtualHardDisks) { 431 | $disk = Get-AzureDisk -DiskName $datadisk.DiskName 432 | while ($disk.AttachedTo -ne $null) { 433 | Write-Host "Waiting for disks to detach. VM:" $vm.Name "Disk:" $disk 434 | Sleep -Seconds 20 435 | $disk = Get-AzureDisk -DiskName $datadisk.DiskName 436 | } 437 | } 438 | } 439 | 440 | #endregion 441 | 442 | # 443 | # Ensure CurrentStorageAccount is set for the subscription in the right location 444 | # 445 | $currentSub = Get-AzureSubscription -Current 446 | $parser = $OSDisk.MediaLink.Host.Split(".") 447 | $StorageAccount = $parser[0] 448 | Set-AzureSubscription -SubscriptionName $currentSub.SubscriptionName -CurrentStorageAccountName $StorageAccount 449 | 450 | 451 | # 452 | # Delete and Recreate the Cloud Service if it was in an affinity group 453 | # 454 | if ($isAffinityGroup){ 455 | Remove-AzureService -ServiceName $service.ServiceName -Force 456 | New-AzureService -ServiceName $service.ServiceName -Location $location 457 | } 458 | 459 | # 460 | # Deploy each VM 461 | # 462 | for ($i=0; $i -lt $vms.count; $i++) { 463 | $vm = $vms[$i] 464 | write-host "Building VM Config:" $vm.Name 465 | 466 | $NewVM = New-AzureVMConfig -Name $vm.Name ` 467 | -InstanceSize $NewSize ` 468 | -DiskName $vm.vm.OSVirtualHardDisk.DiskName ` 469 | -HostCaching $vm.vm.OSVirtualHardDisk.HostCaching 470 | 471 | 472 | if ($vm.AvailabilitySetName) { 473 | Set-AzureAvailabilitySet -AvailabilitySetName $vm.AvailabilitySetName -VM $NewVM 474 | } 475 | 476 | foreach ($disk in $vm.vm.DataVirtualHardDisks) { 477 | Add-AzureDataDisk -import -DiskName $disk.DiskName -LUN $disk.LUN -HostCaching $disk.HostCaching -VM $NewVM 478 | } 479 | 480 | $Endpoints = Get-AzureEndpoint -VM $vm 481 | foreach ($endpoint in $Endpoints) { 482 | if ($endpoint.LBSetName -ne $null ){ 483 | if ($endpoint.InternalLoadBalancerName -ne $null) 484 | { 485 | Add-AzureEndpoint -LBSetName $endpoint.LBSetName -Name $endpoint.Name -Protocol $endpoint.Protocol -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port -ProbePort $endpoint.ProbePort -ProbeProtocol $endpoint.ProbeProtocol -ProbeIntervalInSeconds $endpoint.ProbeIntervalInSeconds -ProbeTimeoutInSeconds $endpoint.ProbeTimeoutInSeconds -DirectServerReturn $endpoint.EnableDirectServerReturn -InternalLoadBalancerName $endpoint.InternalLoadBalancerName -VM $NewVM 486 | } else { 487 | Add-AzureEndpoint -LBSetName $endpoint.LBSetName -Name $endpoint.Name -Protocol $endpoint.Protocol -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port -ProbePort $endpoint.ProbePort -ProbeProtocol $endpoint.ProbeProtocol -ProbeIntervalInSeconds $endpoint.ProbeIntervalInSeconds -ProbeTimeoutInSeconds $endpoint.ProbeTimeoutInSeconds -DirectServerReturn $endpoint.EnableDirectServerReturn -VM $NewVM 488 | } 489 | } else { 490 | Add-AzureEndpoint -Name $endpoint.Name -Protocol $endpoint.Protocol -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port -VM $NewVM 491 | } 492 | } 493 | 494 | $SubNet = Get-AzureSubnet -VM $vm 495 | if ($SubNet -ne $null){ 496 | Set-AzureSubnet -SubnetNames $SubNet -VM $NewVM 497 | } 498 | 499 | $StaticIP = Get-AzureStaticVNetIP -VM $vm.vm 500 | if ($StaticIP -ne $null){ 501 | Set-AzureStaticVNetIP -IPAddress $StaticIP.IPAddress -VM $NewVM 502 | } 503 | 504 | $vmExtensions = Get-AzureVMExtension -VM $vm 505 | foreach ($extension in $vmExtensions) { 506 | if (($extension.Version -ne $null) -and ($extension.Version -ne "")){ 507 | if (($extension.ReferenceName -ne $null) -and ($extension.ReferenceName -ne "")) { 508 | if (($extension.PublicConfiguration -ne $null) -and ($extension.PublicConfiguration -ne "")) { 509 | #All non-NULL 510 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 511 | -Version $extension.Version -ReferenceName $extension.ReferenceName ` 512 | -PublicConfiguration $extension.PublicConfiguration 513 | } else { 514 | #Only Public Config NULL 515 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 516 | -Version $extension.Version -ReferenceName $extension.ReferenceName 517 | } 518 | } else { 519 | if ($extension.PublicConfiguration -ne $null){ 520 | #Only ReferenceName NULL 521 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 522 | -Version $extension.Version ` 523 | -PublicConfiguration $extension.PublicConfiguration 524 | } else { 525 | #Reference Name and Public Configuration NULL 526 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 527 | -Version $extension.Version 528 | } 529 | } 530 | 531 | }else { 532 | if ($extension.ReferenceName -ne $null) { 533 | if ($extension.PublicConfiguration -ne $null){ 534 | #Only Version is NULL 535 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 536 | -ReferenceName $extension.ReferenceName ` 537 | -PublicConfiguration $extension.PublicConfiguration 538 | } else { 539 | #Version and PublicConfig NULL 540 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 541 | -ReferenceName $extension.ReferenceName 542 | } 543 | } else { 544 | if ($extension.PublicConfiguration -ne $null){ 545 | #Version and ReferenceName NULL 546 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 547 | -PublicConfiguration $extension.PublicConfiguration 548 | } else { 549 | #All NULL 550 | Set-AzureVMExtension -VM $NewVM -ExtensionName $extension.ExtensionName -Publisher $extension.Publisher` 551 | } 552 | } 553 | } 554 | } 555 | 556 | $newVMCommand = "New-AzureVM -ServiceName " + $CloudService + " -VMs `$NewVM" 557 | 558 | # 559 | # Configure settings that only apply to the first VM 560 | # 561 | if ($i -eq "0") { 562 | if ($internalLB) { 563 | if ($internalLB.IPAddress) { 564 | $internalLBConfig = New-AzureInternalLoadBalancerConfig -InternalLoadBalancerName $internalLB.InternalLoadBalancerName ` 565 | -SubnetName $internalLB.SubnetName ` 566 | -StaticVNetIPAddress $internalLB.IPAddress 567 | } else { 568 | $internalLBConfig = New-AzureInternalLoadBalancerConfig -InternalLoadBalancerName $internalLB.InternalLoadBalancerName ` 569 | -SubnetName $internalLB.SubnetName 570 | } 571 | $newVMCommand += " -InternalLoadBalancerConfig `$internalLBConfig" 572 | 573 | } 574 | 575 | if ($deployment.VNetName) { 576 | $newVMCommand += " -VNetName `$deployment.VNetName" 577 | } 578 | 579 | if ($reservedIPName) { 580 | $newVMCommand += " -ReservedIPName `$reservedIPName" 581 | } 582 | } 583 | 584 | Invoke-Expression -Command $newVMCommand 585 | } 586 | 587 | 588 | 589 | } catch { 590 | write-host "An error occurred while adding the VMs back to the cloud service. Please review out output at " $OutputFile " to retry the steps manually." 591 | 592 | Write-host "Error at script line" $error[0].InvocationInfo.ScriptLineNumber ":" $error[0].InvocationInfo.Line 593 | 594 | write-host "Error Details:" 595 | $_ 596 | } 597 | 598 | 599 | # END 600 | 601 | 602 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /TestDeployments/Test1.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | $cloudServiceName = "resize-test1" 9 | $vmName = "resize-vm1" 10 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 11 | $location = "West US" 12 | $vmsize = "Small" 13 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test1/" 14 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 15 | 16 | 17 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL 18 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 19 | 20 | New-AzureVM -ServiceName $cloudServiceName -Location $location -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test10.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | # 9 | # Multiple VMs in a stopped-deallocated and stopped state 10 | # 11 | $cloudServiceName = "resize-test10" 12 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 13 | $location = "North Central US" 14 | $vmsize = "Small" 15 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test10/" 16 | 17 | 18 | $vmName = "resize-vm10-1" 19 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 20 | 21 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL 22 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 23 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -location $location 24 | 25 | -------------------------------------------------------------------------------- /TestDeployments/Test2.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Note: VNet must be created before running this script 3 | # 4 | 5 | [CmdletBinding()] 6 | Param( 7 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 8 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 9 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 10 | ) 11 | 12 | $cloudServiceName = "resize-test2" 13 | $availabilitySet = "AS1" 14 | $VNet = "resize2-VNet" 15 | $subnet = "subnet-1" 16 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 17 | $location = "West US" 18 | $vmsize = "Small" 19 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test2/" 20 | 21 | 22 | $vmName = "resize-vm1" 23 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 24 | 25 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 26 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 27 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 28 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location 29 | 30 | 31 | $vmName = "resize-vm2" 32 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 33 | 34 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 35 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 36 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 37 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test3.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Note: VNet must be created before running this script 3 | # 4 | 5 | [CmdletBinding()] 6 | Param( 7 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 8 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 9 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 10 | ) 11 | 12 | # 13 | # Multiple VMs w/ Reserved VIP and Static DataCenter IP 14 | # 15 | $cloudServiceName = "resize-test3" 16 | $reservedIP = "resize-test3-reserved1" 17 | $availabilitySet = "AS1" 18 | $VNet = "resize3-VNet" 19 | $subnet = "subnet-1" 20 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 21 | $location = "West US" 22 | $vmsize = "Small" 23 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test3/" 24 | 25 | $vmName = "resize-vm1" 26 | $ipaddress = "10.0.0.51" 27 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 28 | 29 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 30 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 31 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 32 | Set-AzureStaticVNetIP -IPAddress $ipaddress -VM $vmconfig 33 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location -ReservedIPName $reservedIP 34 | 35 | 36 | $vmName = "resize-vm2" 37 | $ipaddress = "10.0.0.52" 38 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 39 | 40 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 41 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 42 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 43 | Set-AzureStaticVNetIP -IPAddress $ipaddress -VM $vmconfig 44 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test4-withEP.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Note: VNet must be created before running this script 3 | # 4 | 5 | [CmdletBinding()] 6 | Param( 7 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 8 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 9 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 10 | ) 11 | 12 | # 13 | # Multiple VMs in AS with ILB 14 | # 15 | $cloudServiceName = "resize-test4ep" 16 | $availabilitySet = "AS1" 17 | $VNet = "resize-VNet4" 18 | $subnet = "subnet-1" 19 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 20 | $location = "West US" 21 | $vmsize = "Small" 22 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test4ep/" 23 | 24 | 25 | $ilbName = "myILBep" 26 | $ilbConfig = New-AzureInternalLoadBalancerConfig -InternalLoadBalancerName $ilbName -SubnetName $subnet 27 | $lbSetName = "myLBSet" 28 | 29 | $vmName = "resize-vm4ep-1" 30 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 31 | 32 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 33 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 34 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 35 | Add-AzureEndpoint -LBSetName $lbSetName -Name "testEP" -Protocol "TCP" -LocalPort 80 -PublicPort 80 -DefaultProbe -InternalLoadBalancerName $ilbName -VM $vmconfig 36 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location -InternalLoadBalancerConfig $ilbConfig 37 | 38 | 39 | $vmName = "resize-vm4ep-2" 40 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 41 | 42 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 43 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 44 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 45 | Add-AzureEndpoint -LBSetName $lbSetName -Name "testEP" -Protocol "TCP" -LocalPort 80 -PublicPort 80 -DefaultProbe -InternalLoadBalancerName $ilbName -VM $vmconfig 46 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test4.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Note: VNet must be created before running this script 3 | # 4 | 5 | [CmdletBinding()] 6 | Param( 7 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 8 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 9 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 10 | ) 11 | 12 | # 13 | # Multiple VMs in AS with ILB 14 | # 15 | $cloudServiceName = "resize-test4" 16 | $availabilitySet = "AS1" 17 | $VNet = "resize-VNet4" 18 | $subnet = "subnet-1" 19 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 20 | $location = "West US" 21 | $vmsize = "Small" 22 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test4/" 23 | 24 | 25 | $ilbName = "myILB" 26 | 27 | $ilbConfig = New-AzureInternalLoadBalancerConfig -InternalLoadBalancerName $ilbName -SubnetName $subnet 28 | 29 | $vmName = "resize-vm4-1" 30 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 31 | 32 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 33 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 34 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 35 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location -InternalLoadBalancerConfig $ilbConfig 36 | 37 | 38 | $vmName = "resize-vm4-2" 39 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 40 | 41 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 42 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 43 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 44 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test5.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | # 9 | # Multiple VMs with multiple data disks 10 | # 11 | $cloudServiceName = "resize-test5" 12 | $availabilitySet = "AS1" 13 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 14 | $location = "West US" 15 | $vmsize = "ExtraLarge" 16 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test5/" 17 | $numberOfDataDisks = "3" 18 | 19 | 20 | $vmName = "resize-vm5-1" 21 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 22 | $datadiskBase = $storageContainer + $cloudServiceName + "-" + $vmName + "-data-" 23 | 24 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 25 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 26 | for ($i=0; $i -lt $numberOfDataDisks;$i++) { 27 | $dataDiskURL = $datadiskBase + $i 28 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 200 -LUN $i -MediaLocation $dataDiskURL -DiskLabel $i -VM $vmconfig 29 | } 30 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location 31 | 32 | 33 | $vmName = "resize-vm5-2" 34 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 35 | $datadiskBase = $storageContainer + $cloudServiceName + "-" + $vmName + "-data-" 36 | 37 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 38 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 39 | for ($i=0; $i -lt $numberOfDataDisks;$i++) { 40 | $dataDiskURL = $datadiskBase + $i 41 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 200 -LUN $i -MediaLocation $dataDiskURL -DiskLabel $i -VM $vmconfig 42 | } 43 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test6.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # Note: VNet must be created before running this script 3 | # 4 | 5 | [CmdletBinding()] 6 | Param( 7 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 8 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 9 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 10 | ) 11 | 12 | # 13 | # Two VMs in two subnets 14 | # 15 | $cloudServiceName = "resize-test6" 16 | $availabilitySet = "AS1" 17 | $VNet = "resize6-VNet" 18 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 19 | $location = "West US" 20 | $vmsize = "Small" 21 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test6/" 22 | 23 | 24 | $vmName = "resize-vm6-1" 25 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 26 | $subnet = "subnet-1" 27 | 28 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 29 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 30 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 31 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location 32 | 33 | 34 | $vmName = "resize-vm6-2" 35 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 36 | $subnet = "subnet-2" 37 | 38 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 39 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 40 | Set-AzureSubnet -SubnetNames $subnet -VM $vmconfig 41 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test7.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | # 9 | # Premium Storage VM 10 | # 11 | $cloudServiceName = "resize-test7" 12 | $availabilitySet = "AS1" 13 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 14 | $location = "West US" 15 | $vmsize = "Standard_DS1" 16 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test7/" 17 | $numberOfDataDisks = "2" 18 | 19 | 20 | $vmName = "resize-vm7-1" 21 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 22 | $datadiskBase = $storageContainer + $cloudServiceName + "-" + $vmName + "-data-" 23 | 24 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 25 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 26 | for ($i=0; $i -lt $numberOfDataDisks;$i++) { 27 | $dataDiskURL = $datadiskBase + $i 28 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 200 -LUN $i -MediaLocation $dataDiskURL -DiskLabel $i -VM $vmconfig 29 | } 30 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -Location $location 31 | 32 | 33 | $vmName = "resize-vm7-2" 34 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 35 | $datadiskBase = $storageContainer + $cloudServiceName + "-" + $vmName + "-data-" 36 | 37 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 38 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 39 | for ($i=0; $i -lt $numberOfDataDisks;$i++) { 40 | $dataDiskURL = $datadiskBase + $i 41 | Add-AzureDataDisk -CreateNew -DiskSizeInGB 200 -LUN $i -MediaLocation $dataDiskURL -DiskLabel $i -VM $vmconfig 42 | } 43 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -------------------------------------------------------------------------------- /TestDeployments/Test8.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | # 9 | # Multiple VMs in a stopped-deallocated and stopped state 10 | # 11 | $cloudServiceName = "resize-test8" 12 | $availabilitySet = "AS1" 13 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 14 | $location = "West US" 15 | $vmsize = "Small" 16 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test8/" 17 | 18 | 19 | 20 | $vmName = "resize-vm8-1" 21 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 22 | 23 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 24 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 25 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -Location $location 26 | 27 | 28 | $vmName = "resize-vm8-2" 29 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 30 | 31 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL -AvailabilitySetName $availabilitySet 32 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 33 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig 34 | 35 | 36 | # 37 | # Stop VMs after they have came to ReadyRole state 38 | # 39 | $vmName = "resize-vm8-1" 40 | 41 | $vm = Get-AzureVM -ServiceName $cloudServiceName -Name $vmName 42 | while ($vm.InstanceStatus -notlike "ReadyRole") { 43 | write-host "Waiting for" $vmName "to become ReadyRole. Current Status:" $vm.InstanceStatus 44 | sleep -Seconds 20 45 | $vm = Get-AzureVM -ServiceName $cloudServiceName -Name $vmName 46 | } 47 | Stop-AzureVM -Name $vmName -ServiceName $cloudServiceName -StayProvisioned 48 | 49 | 50 | $vmName = "resize-vm8-2" 51 | 52 | $vm = Get-AzureVM -ServiceName $cloudServiceName -Name $vmName 53 | while ($vm.InstanceStatus -notlike "ReadyRole") { 54 | write-host "Waiting for" $vmName "to become ReadyRole. Current Status:" $vm.InstanceStatus 55 | sleep -Seconds 20 56 | $vm = Get-AzureVM -ServiceName $cloudServiceName -Name $vmName 57 | } 58 | Stop-AzureVM -Name $vmName -ServiceName $cloudServiceName -------------------------------------------------------------------------------- /TestDeployments/Test9.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$storageAccountName = $(Read-Host -prompt "Specify storage account name"), 4 | [string]$adminUser = $(Read-Host -prompt "Specify admin user name"), 5 | [string]$adminPassword = $(Read-Host -prompt "Specify admin password") 6 | ) 7 | 8 | # 9 | # Multiple VMs in a stopped-deallocated and stopped state 10 | # 11 | $cloudServiceName = "resize-test9" 12 | $image = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-20151120-en.us-127GB.vhd" 13 | $location = "West US" 14 | $vmsize = "Small" 15 | $storageContainer = "http://" + $storageAccountName + ".blob.core.windows.net/test9/" 16 | 17 | $affinityGroupName = "ResizeTest9AG" 18 | 19 | New-AzureAffinityGroup -Name $affinityGroupName -Location $location 20 | 21 | $vmName = "resize-vm9-1" 22 | $osDiskURL = $storageContainer + $cloudServiceName + "-" + $vmName 23 | 24 | $vmconfig = New-AzureVMConfig -Name $vmName -InstanceSize $vmsize -ImageName $image -MediaLocation $osDiskURL 25 | Add-AzureProvisioningConfig -VM $vmConfig -Windows -AdminUsername $adminUser -Password $adminPassword 26 | New-AzureVM -ServiceName $cloudServiceName -VMs $vmconfig -VNetName $VNet -AffinityGroup $affinityGroupName 27 | 28 | -------------------------------------------------------------------------------- /TestDeployments/TestCases.txt: -------------------------------------------------------------------------------- 1 | resize-test1 2 | Single VM 3 | No VNet 4 | 5 | Command: .\ResizeCS.ps1 -CloudService resize-test1 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 6 | 7 | 8 | resize-test2 9 | Two VMs in AS 10 | Member of VNet (resize2-VNet) 11 | 12 | Command: .\ResizeCS.ps1 -CloudService resize-test2 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 13 | 14 | 15 | resize-test3 16 | Multiple VMs w/ Reserved VIP and Static DataCenter IP 17 | VNet (resize3-VNet) 18 | 19 | Command: .\ResizeCS.ps1 -CloudService resize-test3 -NewSize A10 -OutputFile \temp\test.txt 20 | 21 | 22 | resize-test4 23 | Multiple VMs in AS with ILB (Not assigned to endpoints) 24 | VNet (resize4-VNet) 25 | 26 | Command: .\ResizeCS.ps1 -CloudService resize-test4 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 27 | 28 | 29 | resize-test4EP 30 | Multiple VMs in AS with ILB (With Endpoints Assigned) 31 | VNet (resize4-VNet) 32 | 33 | Command: .\ResizeCS.ps1 -CloudService resize-test4ep -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 34 | 35 | 36 | resize-test5 37 | Multiple VMs with multiple data disks 38 | No VNet 39 | 40 | Command: .\ResizeCS.ps1 -CloudService resize-test5 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 41 | 42 | 43 | Resize-test6 44 | Two VMs in two subnets 45 | VNet (resize6-VNet) 46 | 47 | Command: .\ResizeCS.ps1 -CloudService resize-test6 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 48 | 49 | Resize-test7 50 | Premium Storage VM 51 | 52 | Command: .\ResizeCS.ps1 -CloudService resize-test7 -NewSize Standard_GS2 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 53 | 54 | Resize-test8 55 | Verify warning on stopped and stopped-deallocated VMs 56 | No VNet 57 | 58 | Command: .\ResizeCS.ps1 -CloudService resize-test8 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 59 | 60 | Resize-test9 61 | Cloud Service in affinity group 62 | 63 | Command: .\ResizeCS.ps1 -CloudService resize-test9 -NewSize A10 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange -AllowRemovalOfAffinityGroup 64 | 65 | Resize-test10 66 | NEGATIVE TEST: Ensure a size not valid in a region is returned as an error. 67 | No VNet 68 | 69 | Command: .\ResizeCS.ps1 -CloudService resize-test10 -NewSize Standard_DS2 -OutputFile \temp\test.txt -AllowServiceVipChange -AllowVNetIPChange 70 | 71 | Resize-test11 72 | Two VMs with Public IP address 73 | No VNet 74 | 75 | Status: Needs to be created --------------------------------------------------------------------------------