From b6fbae34070410856ebe5052d3ce3c259f772d35 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Fri, 15 Sep 2017 16:44:56 -0700 Subject: [PATCH 01/11] subnet (broken) --- .../AzureRM.Compute.Experiments.Tests.ps1 | 2 +- .../AzureRM.Compute.Experiments.psm1 | 76 +++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index 2bc2c51f4506..ce43ca3b59e5 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -19,7 +19,7 @@ New-AzVm -Name MyVM -Credential $vmCredential -WhatIf # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential -$vm = New-AzVm -Name MyVM -Credential $vmCredential +$vm = New-AzVm -Name MyVMA -Credential $vmCredential $vm diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index b373bf4f4eac..c3668a77a0cc 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -10,6 +10,7 @@ function New-AzVm { [Parameter()][string] $Location, [Parameter()][string] $VirtualNetworkName, + [Parameter()][string] $SubnetName, [Parameter()][string] $PublicIpAddressName, [Parameter()][string] $SecurityGroupName, @@ -22,13 +23,14 @@ function New-AzVm { $rgi = [ResourceGroup]::new($ResourceGroupName); $vni = [VirtualNetwork]::new($VirtualNetworkName); + $subnet = [Subnet]::new($SubnetName, $vni); $piai = [PublicIpAddress]::new($PublicIpAddressName); $sgi = [SecurityGroup]::new($SecurityGroupName); # we don't allow to reuse NetworkInterface so $name is $null. $nii = [NetworkInterface]::new( $null, - $vni, + $subnet, $piai, $sgi); @@ -142,8 +144,11 @@ class AzureObject { if ($this.Name) { return $this.GetInfo(); } else { + Write-Host "{" + Write-Host $this $result = $this.Create($p); $this.Name = $p.Name; + Write-Host "}" return $result; } } @@ -179,9 +184,10 @@ class VirtualNetwork: Resource1 { } [object] Create([CreateParams] $p) { + <# $subnetConfig = New-AzureRmVirtualNetworkSubnetConfig ` - -Name "Subnet" ` - -AddressPrefix "192.168.1.0/24" + -Name "Subnet" ` + -AddressPrefix "192.168.1.0/24" return New-AzureRmVirtualNetwork ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` @@ -189,6 +195,13 @@ class VirtualNetwork: Resource1 { -AddressPrefix "192.168.0.0/16" ` -Subnet $subnetConfig ` -WarningAction SilentlyContinue + #> + return New-AzureRmVirtualNetwork ` + -ResourceGroupName $p.ResourceGroupName ` + -Location $p.Location ` + -Name $p.Name ` + -AddressPrefix "192.168.0.0/16" ` + -WarningAction SilentlyContinue; } } @@ -215,7 +228,7 @@ class SecurityGroup: Resource1 { } [object] GetInfo() { - return Get-AzureRMSecurityGroup -Name $this.Name; + return Get-AzureRMSecurityGroup -Name $this.Name } [object] Create([CreateParams] $p) { @@ -229,7 +242,6 @@ class SecurityGroup: Resource1 { -SourceAddressPrefix "*" ` -DestinationPortRange 3389 ` -DestinationAddressPrefix "*" - return New-AzureRmNetworkSecurityGroup ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` @@ -239,18 +251,49 @@ class SecurityGroup: Resource1 { } } -class NetworkInterface: AzureObject { +class Subnet: AzureObject { [VirtualNetwork] $VirtualNetwork; + + Subnet([string] $name, [VirtualNetwork] $virtualNetwork): + base($name, @($virtualNetwork)) { + $this.VirtualNetwork = $virtualNetwork; + } + + [object] GetInfo() { + Write-Host "sn.GetInfo {" + $virutalNetworkInfo = $this.VirtualNetwork.GetInfo(); + Write-Host "}" + return $virutalNetworkInfo | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name; + } + + [object] Create([CreateParams] $p) { + Write-Host "sn.Create {" + $virtualNetworkInfo = $this.VirtualNetwork.GetOrCreate($p); + Set-AzureRmVirtualNetworkSubnetConfig ` + -VirtualNetwork $virtualNetworkInfo ` + -Name $p.Name ` + -AddressPrefix "192.168.1.0/24"; + Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo + $result = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name + Write-Host $virtualNetworkInfo + Write-Host $result + Write-Host "} sn.Create" + return $result; + } +} + +class NetworkInterface: AzureObject { + [Subnet] $Subnet; [PublicIpAddress] $PublicIpAddress; [SecurityGroup] $SecurityGroup; NetworkInterface( [string] $name, - [VirtualNetwork] $virtualNetwork, + [Subnet] $subnet, [PublicIpAddress] $publicIpAddress, [SecurityGroup] $securityGroup - ): base($name, @($virtualNetwork, $publicIpAddress, $securityGroup)) { - $this.VirtualNetwork = $virtualNetwork; + ): base($name, @($subnet, $publicIpAddress, $securityGroup)) { + $this.Subnet = $subnet; $this.PublicIpAddress = $publicIpAddress; $this.SecurityGroup = $securityGroup; } @@ -260,16 +303,19 @@ class NetworkInterface: AzureObject { } [object] Create([CreateParams] $p) { - $xpublicIpAddress = $this.PublicIpAddress.GetOrCreate($p); - $xvirtualNetwork = $this.VirtualNetwork.GetOrCreate($p); - $xsecurityGroup = $this.SecurityGroup.GetOrCreate($p); + $publicIpAddressInfo = $this.PublicIpAddress.GetOrCreate($p); + $subnetInfo = $this.Subnet.GetOrCreate($p); + Write-Host "sn: {" + Write-Host $subnetInfo + Write-Host "} sn" + $securityGroupInfo = $this.SecurityGroup.GetOrCreate($p); return New-AzureRmNetworkInterface ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` - -PublicIpAddressId $xpublicIpAddress.Id ` - -SubnetId $xvirtualNetwork.Subnets[0].Id ` - -NetworkSecurityGroupId $xsecurityGroup.Id ` + -PublicIpAddressId $publicIpAddressInfo.Id ` + -SubnetId $subnetInfo.Id ` + -NetworkSecurityGroupId $securityGroupInfo.Id ` -WarningAction SilentlyContinue } } From 72f2658a47cf5d07b4ea01af39b98b97902231e6 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 15:40:02 -0700 Subject: [PATCH 02/11] Additional parameters --- .../AzureRM.Compute.Experiments.Tests.ps1 | 1 + .../AzureRM.Compute.Experiments.psm1 | 104 +++++++++--------- 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index ce43ca3b59e5..e6bd109e76a9 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -20,6 +20,7 @@ New-AzVm -Name MyVM -Credential $vmCredential -WhatIf # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential $vm = New-AzVm -Name MyVMA -Credential $vmCredential +# $vm = New-AzVm -Name MyVMA $vm diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index cbb2595e3ca4..aba20cffc7a6 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -5,27 +5,35 @@ function New-AzVm { [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory=$true, Position=0)][string] $Name = "VM", + [Parameter(Mandatory=$true)][PSCredential] $Credential, [Parameter()][string] $ResourceGroupName, [Parameter()][string] $Location, [Parameter()][string] $VirtualNetworkName, + [Parameter()][string] $AddressPrefix = "192.168.0.0/16", + [Parameter()][string] $SubnetName, + [Parameter()][string] $SubnetAddressPrefix = "192.168.1.0/24", + [Parameter()][string] $PublicIpAddressName, + [Parameter()][string] $DomainNameLabel = $Name, + [Parameter()][string] $AllocationMethod = "Static", + [Parameter()][string] $SecurityGroupName, + [Parameter()][int[]] $OpenPorts = @(3389, 5985), - [Parameter()][PSCredential] $Credential, - [Parameter()][string] $ImageName = "Win2012R2Datacenter", + [Parameter()][string] $ImageName = "Win2016Datacenter", [Parameter()][string] $Size = "Standard_DS1_v2" ) PROCESS { $rgi = [ResourceGroup]::new($ResourceGroupName); - $vni = [VirtualNetwork]::new($VirtualNetworkName); - $subnet = [Subnet]::new($SubnetName, $vni); - $piai = [PublicIpAddress]::new($PublicIpAddressName); - $sgi = [SecurityGroup]::new($SecurityGroupName); + $vni = [VirtualNetwork]::new($VirtualNetworkName, $AddressPrefix); + $subnet = [Subnet]::new($SubnetName, $vni, $SubnetAddressPrefix); + $piai = [PublicIpAddress]::new($PublicIpAddressName, $DomainNameLabel, $AllocationMethod); + $sgi = [SecurityGroup]::new($SecurityGroupName, $OpenPorts); # we don't allow to reuse NetworkInterface so $name is $null. $nii = [NetworkInterface]::new( @@ -144,11 +152,8 @@ class AzureObject { if ($this.Name) { return $this.GetInfo(); } else { - Write-Host "{" - Write-Host $this $result = $this.Create($p); $this.Name = $p.Name; - Write-Host "}" return $result; } } @@ -176,7 +181,10 @@ class Resource1: AzureObject { } class VirtualNetwork: Resource1 { - VirtualNetwork([string] $name): base($name) { + [string] $AddressPrefix; + + VirtualNetwork([string] $name, [string] $addressPrefix): base($name) { + $this.AddressPrefix = $addressPrefix; } [object] GetInfo() { @@ -184,29 +192,26 @@ class VirtualNetwork: Resource1 { } [object] Create([CreateParams] $p) { - <# - $subnetConfig = New-AzureRmVirtualNetworkSubnetConfig ` - -Name "Subnet" ` - -AddressPrefix "192.168.1.0/24" - return New-AzureRmVirtualNetwork ` - -ResourceGroupName $p.ResourceGroupName ` - -Location $p.Location ` - -Name $p.Name ` - -AddressPrefix "192.168.0.0/16" ` - -Subnet $subnetConfig ` - -WarningAction SilentlyContinue - #> return New-AzureRmVirtualNetwork ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` - -AddressPrefix "192.168.0.0/16" ` + -AddressPrefix $this.AddressPrefix ` -WarningAction SilentlyContinue; } } class PublicIpAddress: Resource1 { - PublicIpAddress([string] $name): base($name) { + [string] $DomainNameLabel; + [string] $AllocationMethod; + + PublicIpAddress( + [string] $name, + [string] $domainNameLabel, + [string] $allocationMethod + ): base($name) { + $this.DomainNameLabel = $domainNameLabel; + $this.AllocationMethod = $allocationMethod; } [object] GetInfo() { @@ -218,13 +223,17 @@ class PublicIpAddress: Resource1 { -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` + -DomainNameLabel $this.DnsLabel ` -AllocationMethod Static ` -WarningAction SilentlyContinue } } class SecurityGroup: Resource1 { - SecurityGroup([string] $name): base($name) { + [int[]] $OpenPorts; + + SecurityGroup([string] $name, [int[]] $OpenPorts): base($name) { + $this.OpenPorts = $OpenPorts; } [object] GetInfo() { @@ -232,52 +241,52 @@ class SecurityGroup: Resource1 { } [object] Create([CreateParams] $p) { - $securityRuleConfig = New-AzureRmNetworkSecurityRuleConfig ` - -Name $p.Name ` - -Protocol "Tcp" ` - -Priority 1000 ` - -Access "Allow" ` - -Direction "Inbound" ` - -SourcePortRange "*" ` - -SourceAddressPrefix "*" ` - -DestinationPortRange 3389 ` - -DestinationAddressPrefix "*" + $rules = New-Object "System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSSecurityRule]"; + foreach ($port in $this.OpenPorts) { + $name = $p.Name + $port; + $securityRuleConfig = New-AzureRmNetworkSecurityRuleConfig ` + -Name $name ` + -Protocol "Tcp" ` + -Priority 1000 ` + -Access "Allow" ` + -Direction "Inbound" ` + -SourcePortRange "*" ` + -SourceAddressPrefix "*" ` + -DestinationPortRange $port ` + -DestinationAddressPrefix "*"; + } return New-AzureRmNetworkSecurityGroup ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` - -SecurityRules $securityRuleConfig ` + -SecurityRules $rules ` -WarningAction SilentlyContinue } } class Subnet: AzureObject { [VirtualNetwork] $VirtualNetwork; + [string] $SubnetAddressPrefix; - Subnet([string] $name, [VirtualNetwork] $virtualNetwork): + Subnet([string] $name, [VirtualNetwork] $virtualNetwork, [string] $subnetAddressPrefix): base($name, @($virtualNetwork)) { $this.VirtualNetwork = $virtualNetwork; + $this.SubnetAddressPrefix = $subnetAddressPrefix; } [object] GetInfo() { - Write-Host "sn.GetInfo {" $virutalNetworkInfo = $this.VirtualNetwork.GetInfo(); - Write-Host "}" return $virutalNetworkInfo | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name; } [object] Create([CreateParams] $p) { - Write-Host "sn.Create {" $virtualNetworkInfo = $this.VirtualNetwork.GetOrCreate($p); - Set-AzureRmVirtualNetworkSubnetConfig ` + Add-AzureRmVirtualNetworkSubnetConfig ` -VirtualNetwork $virtualNetworkInfo ` -Name $p.Name ` - -AddressPrefix "192.168.1.0/24"; - Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo + -AddressPrefix $this.SubnetAddressPrefix; + $virtualNetworkInfo = Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo $result = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name - Write-Host $virtualNetworkInfo - Write-Host $result - Write-Host "} sn.Create" return $result; } } @@ -305,9 +314,6 @@ class NetworkInterface: AzureObject { [object] Create([CreateParams] $p) { $publicIpAddressInfo = $this.PublicIpAddress.GetOrCreate($p); $subnetInfo = $this.Subnet.GetOrCreate($p); - Write-Host "sn: {" - Write-Host $subnetInfo - Write-Host "} sn" $securityGroupInfo = $this.SecurityGroup.GetOrCreate($p); return New-AzureRmNetworkInterface ` -ResourceGroupName $p.ResourceGroupName ` From c1b34214add051bb8f0f51ec7984a6706431a944 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 15:55:37 -0700 Subject: [PATCH 03/11] 1.0.8 --- .../Compute.Experiments/AzureRM.Compute.Experiments.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 index 907daf9ff596..3aae249c69a8 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 @@ -12,7 +12,7 @@ RootModule = ".\AzureRM.Compute.Experiments.psm1" # Version number of this module. -ModuleVersion = '1.0.7' +ModuleVersion = '1.0.8' # Supported PSEditions # CompatiblePSEditions = @() From 14697b785518f0c3b9735f9b101926c5cbbbe26f Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 16:26:07 -0700 Subject: [PATCH 04/11] install *.3.2 modules. --- .../AzureRM.Compute.Experiments.Tests.ps1 | 8 ++++---- .../Compute.Experiments/AzureRM.Compute.Experiments.psd1 | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index e6bd109e76a9..d8cf750281b1 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -1,7 +1,7 @@ -Import-Module .\..\..\src\Package\Debug\ResourceManager\AzureResourceManager\AzureRM.Profile\AzureRM.Profile.psd1 -Import-Module .\..\..\src\Package\Debug\ResourceManager\AzureResourceManager\AzureRM.Resources\AzureRM.Resources.psd1 -Import-Module .\..\..\src\Package\Debug\ResourceManager\AzureResourceManager\AzureRM.Network\AzureRM.Network.psd1 -Import-Module .\..\..\src\Package\Debug\ResourceManager\AzureResourceManager\AzureRM.Compute\AzureRM.Compute.psd1 +Import-Module AzureRM.Profile -MinimumVersion 3.3.2 +Import-Module AzureRM.Resources -MinimumVersion 4.3.2 +Import-Module AzureRM.Network -MinimumVersion 4.3.2 +Import-Module AzureRM.Compute -MinimumVersion 3.3.2 Import-Module .\..\..\experiments\Compute.Experiments\AzureRM.Compute.Experiments.psd1 # Login diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 index 3aae249c69a8..d230098b9f83 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 @@ -12,7 +12,7 @@ RootModule = ".\AzureRM.Compute.Experiments.psm1" # Version number of this module. -ModuleVersion = '1.0.8' +ModuleVersion = '1.0.9' # Supported PSEditions # CompatiblePSEditions = @() @@ -52,9 +52,9 @@ PowerShellVersion = '5.0' # Modules that must be imported into the global environment prior to importing this module RequiredModules = @( - @{ ModuleName = "AzureRM.Resources"; ModuleVersion = "4.3.1"; }, - @{ ModuleName = "AzureRM.Network"; ModuleVersion = "4.3.1"; }, - @{ ModuleName = "AzureRM.Compute"; ModuleVersion = "3.3.1"; } + @{ ModuleName = "AzureRM.Resources"; ModuleVersion = "4.3.2"; }, + @{ ModuleName = "AzureRM.Network"; ModuleVersion = "4.3.2"; }, + @{ ModuleName = "AzureRM.Compute"; ModuleVersion = "3.3.2"; } ) # Assemblies that must be loaded prior to importing this module From d0ec67150559c8f15c8c7fe915211c7fe6a1c6e2 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 16:29:19 -0700 Subject: [PATCH 05/11] add rules. --- experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index aba20cffc7a6..a06444f28840 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -254,6 +254,7 @@ class SecurityGroup: Resource1 { -SourceAddressPrefix "*" ` -DestinationPortRange $port ` -DestinationAddressPrefix "*"; + $rules.Add($securityRuleConfig); } return New-AzureRmNetworkSecurityGroup ` -ResourceGroupName $p.ResourceGroupName ` From c4d8261a110dc5eb596a6f443b90ce19b7f8422e Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 17:30:48 -0700 Subject: [PATCH 06/11] AsJob preparation --- .../AzureRM.Compute.Experiments.psm1 | 84 ++++++++++++------- 1 file changed, 55 insertions(+), 29 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index a06444f28840..bb4b7298452e 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -24,7 +24,9 @@ function New-AzVm { [Parameter()][int[]] $OpenPorts = @(3389, 5985), [Parameter()][string] $ImageName = "Win2016Datacenter", - [Parameter()][string] $Size = "Standard_DS1_v2" + [Parameter()][string] $Size = "Standard_DS1_v2", + + [Parameter()][switch] $AsJob ) PROCESS { @@ -66,17 +68,27 @@ function New-AzVm { $createParams = [CreateParams]::new($Name, $locationi.Value, $Name); if ($PSCmdlet.ShouldProcess($Name, "Creating a virtual machine")) { - $resourceGroup = $rgi.GetOrCreate($createParams); - $vmResponse = $vmi.Create($createParams); - - return [PSAzureVm]::new( - $resourceGroup.ResourceId, - $Name - ); + return New-AzVmInternal -ResourceGroup $rgi -VirtualMachine $vmi -CreateParams $createParams -ErrorAction Stop; } } } +function New-AzVmInternal { + param ( + [ResourceGroup] $ResourceGroup, + [VirtualMachine] $VirtualMachine, + [CreateParams] $createParams + ) + + $rg = $ResourceGroup.GetOrCreate($createParams); + $vmResponse = $VirtualMachine.Create($createParams); + + return [PSAzureVm]::new( + $rg.ResourceId, + $VirtualMachine.Name + ); +} + class PSAzureVm { [string] $ResourceGroupId; [string] $Name; @@ -171,7 +183,8 @@ class ResourceGroup: AzureObject { return New-AzureRmResourceGroup ` -Name $p.Name ` -Location $p.Location ` - -WarningAction SilentlyContinue; + -WarningAction SilentlyContinue ` + -ErrorAction Stop; } } @@ -184,11 +197,11 @@ class VirtualNetwork: Resource1 { [string] $AddressPrefix; VirtualNetwork([string] $name, [string] $addressPrefix): base($name) { - $this.AddressPrefix = $addressPrefix; + $this.AddressPrefix = $addressPrefix } [object] GetInfo() { - return Get-AzureRmVirtualNetwork -Name $this.Name; + return Get-AzureRmVirtualNetwork -Name $this.Name } [object] Create([CreateParams] $p) { @@ -197,7 +210,8 @@ class VirtualNetwork: Resource1 { -Location $p.Location ` -Name $p.Name ` -AddressPrefix $this.AddressPrefix ` - -WarningAction SilentlyContinue; + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } @@ -223,9 +237,10 @@ class PublicIpAddress: Resource1 { -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` - -DomainNameLabel $this.DnsLabel ` - -AllocationMethod Static ` - -WarningAction SilentlyContinue + -DomainNameLabel $this.DomainNameLabel.ToLower() ` + -AllocationMethod $this.AllocationMethod ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } @@ -241,27 +256,31 @@ class SecurityGroup: Resource1 { } [object] Create([CreateParams] $p) { - $rules = New-Object "System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSSecurityRule]"; + $rules = New-Object "System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSSecurityRule]" + $priority = 1000 foreach ($port in $this.OpenPorts) { - $name = $p.Name + $port; + $name = $p.Name + $port $securityRuleConfig = New-AzureRmNetworkSecurityRuleConfig ` -Name $name ` -Protocol "Tcp" ` - -Priority 1000 ` + -Priority $priority ` -Access "Allow" ` -Direction "Inbound" ` -SourcePortRange "*" ` -SourceAddressPrefix "*" ` -DestinationPortRange $port ` - -DestinationAddressPrefix "*"; - $rules.Add($securityRuleConfig); + -DestinationAddressPrefix "*" ` + -ErrorAction Stop + $rules.Add($securityRuleConfig) + ++$priority } return New-AzureRmNetworkSecurityGroup ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -Name $p.Name ` -SecurityRules $rules ` - -WarningAction SilentlyContinue + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } @@ -286,7 +305,7 @@ class Subnet: AzureObject { -VirtualNetwork $virtualNetworkInfo ` -Name $p.Name ` -AddressPrefix $this.SubnetAddressPrefix; - $virtualNetworkInfo = Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo + $virtualNetworkInfo = Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo -ErrorAction Stop $result = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name return $result; } @@ -323,7 +342,8 @@ class NetworkInterface: AzureObject { -PublicIpAddressId $publicIpAddressInfo.Id ` -SubnetId $subnetInfo.Id ` -NetworkSecurityGroupId $securityGroupInfo.Id ` - -WarningAction SilentlyContinue + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } @@ -367,20 +387,22 @@ class VirtualMachine: AzureObject { throw "Unknown image: " + $this.ImageName; } - $vmConfig = New-AzureRmVMConfig -VMName $p.Name -VMSize $this.Size; - $vmComputerName = $p.Name; + $vmConfig = New-AzureRmVMConfig -VMName $p.Name -VMSize $this.Size -ErrorAction Stop + $vmComputerName = $p.Name switch ($vmImage.Type) { "Windows" { $vmConfig = $vmConfig | Set-AzureRmVMOperatingSystem ` -Windows ` -ComputerName $vmComputerName ` - -Credential $this.Credential; + -Credential $this.Credential ` + -ErrorAction Stop } "Linux" { $vmConfig = $vmConfig | Set-AzureRmVMOperatingSystem ` -Linux ` -ComputerName $vmComputerName ` - -Credential $this.Credential; + -Credential $this.Credential ` + -ErrorAction Stop } } @@ -391,13 +413,17 @@ class VirtualMachine: AzureObject { -Offer $vmImageImage.offer ` -Skus $vmImageImage.sku ` -Version $vmImageImage.version ` - | Add-AzureRmVMNetworkInterface -Id $networkInterfaceInstance.Id + -ErrorAction Stop ` + | Add-AzureRmVMNetworkInterface ` + -Id $networkInterfaceInstance.Id ` + -ErrorAction Stop return New-AzureRmVm ` -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -VM $vmConfig ` - -WarningAction SilentlyContinue + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } From 35ba3866f86dee248e6d01417088f2ca2183642e Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Mon, 18 Sep 2017 18:46:48 -0700 Subject: [PATCH 07/11] as job --- .../AzureRM.Compute.Experiments.Tests.ps1 | 16 ++++++++++++---- .../AzureRM.Compute.Experiments.psm1 | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index d8cf750281b1..f338589d8b20 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -1,7 +1,7 @@ -Import-Module AzureRM.Profile -MinimumVersion 3.3.2 -Import-Module AzureRM.Resources -MinimumVersion 4.3.2 -Import-Module AzureRM.Network -MinimumVersion 4.3.2 -Import-Module AzureRM.Compute -MinimumVersion 3.3.2 +# Import-Module AzureRM.Profile -MinimumVersion 3.3.2 +# Import-Module AzureRM.Resources -MinimumVersion 4.3.2 +# Import-Module AzureRM.Network -MinimumVersion 4.3.2 +# Import-Module AzureRM.Compute -MinimumVersion 3.3.2 Import-Module .\..\..\experiments\Compute.Experiments\AzureRM.Compute.Experiments.psd1 # Login @@ -17,6 +17,14 @@ $vmCredential = New-Object System.Management.Automation.PSCredential ($vmCompute New-AzVm -Name MyVM -Credential $vmCredential -WhatIf +$job = New-AzVm -Name MyVMA -Credential $vmCredential -AsJob + +$vm = Receive-Job $job + +$vm + +exit + # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential $vm = New-AzVm -Name MyVMA -Credential $vmCredential diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index bb4b7298452e..f84eaeb0d654 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -68,11 +68,26 @@ function New-AzVm { $createParams = [CreateParams]::new($Name, $locationi.Value, $Name); if ($PSCmdlet.ShouldProcess($Name, "Creating a virtual machine")) { - return New-AzVmInternal -ResourceGroup $rgi -VirtualMachine $vmi -CreateParams $createParams -ErrorAction Stop; + if ($AsJob) { + $script = { + param($rgi, $vmi, $createParams) + New-AzVmInternal ` + -ResourceGroup $rgi ` + -VirtualMachine $vmi ` + -CreateParams $createParams ` + -ErrorAction Stop + } + return Start-Job -ScriptBlock $script -ArgumentList @($rgi, $vmi, $createParams) + } else { + return New-AzVmInternal ` + -ResourceGroup $rgi ` + -VirtualMachine $vmi ` + -CreateParams $createParams ` + -ErrorAction Stop + } } } } - function New-AzVmInternal { param ( [ResourceGroup] $ResourceGroup, From a034a9b9c0541dfb744e218dfc3cd63ab1458aa1 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Tue, 19 Sep 2017 15:20:22 -0700 Subject: [PATCH 08/11] AsJob --- .../AzureRM.Compute.Experiments.Tests.ps1 | 31 ++-- .../AzureRM.Compute.Experiments.psd1 | 4 +- .../AzureRM.Compute.Experiments.psm1 | 147 ++++++++++-------- .../Compute.Experiments/publish-dev.ps1 | 12 +- 4 files changed, 105 insertions(+), 89 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index f338589d8b20..1ec2b6658862 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -1,8 +1,9 @@ -# Import-Module AzureRM.Profile -MinimumVersion 3.3.2 -# Import-Module AzureRM.Resources -MinimumVersion 4.3.2 -# Import-Module AzureRM.Network -MinimumVersion 4.3.2 -# Import-Module AzureRM.Compute -MinimumVersion 3.3.2 -Import-Module .\..\..\experiments\Compute.Experiments\AzureRM.Compute.Experiments.psd1 +# $build = "..\build\" +# $out = $build + "AzureRM.Compute.Experiments\" +# Copy-Item .\AzureRM.Compute.Experiments.psd1 $out +# Copy-Item .\AzureRM.Compute.Experiments.psm1 $out + +$env:PSModulePath = $env:PSModulePath + ";" + $build # Login $credentials = Get-Content -Path "C:\Users\sergey\Desktop\php-test.json" | ConvertFrom-Json @@ -17,20 +18,26 @@ $vmCredential = New-Object System.Management.Automation.PSCredential ($vmCompute New-AzVm -Name MyVM -Credential $vmCredential -WhatIf -$job = New-AzVm -Name MyVMA -Credential $vmCredential -AsJob - -$vm = Receive-Job $job - -$vm +# $job = New-AzVm -Name MyVMA -Credential $vmCredential -AsJob +# Receive-Job $job -exit +# exit # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential -$vm = New-AzVm -Name MyVMA -Credential $vmCredential +# $vm = New-AzVm -Name MyVMA -Credential $vmCredential # $vm = New-AzVm -Name MyVMA $vm +Write-Host "" + +$job = New-AzVm -Name MyVMA2 -Credential $vmCredential -AsJob +$vm = Receive-Job $job + +$vm + +Write-Host "" + # clean-up Remove-AzureRmResourceGroup -ResourceId $vm.ResourceGroupId \ No newline at end of file diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 index d230098b9f83..7ccb5ab38523 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 @@ -12,7 +12,7 @@ RootModule = ".\AzureRM.Compute.Experiments.psm1" # Version number of this module. -ModuleVersion = '1.0.9' +ModuleVersion = '1.0.19' # Supported PSEditions # CompatiblePSEditions = @() @@ -73,7 +73,7 @@ RequiredModules = @( # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'New-AzVm' +FunctionsToExport = 'New-AzVm', 'New-AzVmInternal' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. # CmdletsToExport = diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index f84eaeb0d654..d0e63b5648c1 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -26,23 +26,31 @@ function New-AzVm { [Parameter()][string] $ImageName = "Win2016Datacenter", [Parameter()][string] $Size = "Standard_DS1_v2", + [Parameter()][object] $AzureRmContext, [Parameter()][switch] $AsJob ) PROCESS { - $rgi = [ResourceGroup]::new($ResourceGroupName); + # TODO: make sure it's logged in. + $context = if ($AzureRmContext) { + Get-AzureRmContext -AzureRmContext $AzureRmContext + } else { + Get-AzureRmContext + } + + $rgi = [ResourceGroup]::new($ResourceGroupName) - $vni = [VirtualNetwork]::new($VirtualNetworkName, $AddressPrefix); - $subnet = [Subnet]::new($SubnetName, $vni, $SubnetAddressPrefix); - $piai = [PublicIpAddress]::new($PublicIpAddressName, $DomainNameLabel, $AllocationMethod); - $sgi = [SecurityGroup]::new($SecurityGroupName, $OpenPorts); + $vni = [VirtualNetwork]::new($VirtualNetworkName, $AddressPrefix) + $subnet = [Subnet]::new($SubnetName, $vni, $SubnetAddressPrefix) + $piai = [PublicIpAddress]::new($PublicIpAddressName, $DomainNameLabel, $AllocationMethod) + $sgi = [SecurityGroup]::new($SecurityGroupName, $OpenPorts) # we don't allow to reuse NetworkInterface so $name is $null. $nii = [NetworkInterface]::new( $null, $subnet, $piai, - $sgi); + $sgi) # the purpouse of the New-AzVm cmdlet is to create (not get) a VM so $name is $null. $vmi = [VirtualMachine]::new( @@ -57,7 +65,7 @@ function New-AzVm { # infer a location $locationi = [Location]::new(); if (-not $Location) { - $vmi.UpdateLocation($locationi); + $vmi.UpdateLocation($locationi, $context); if (-not $locationi.Value) { $locationi.Value = "eastus"; } @@ -65,44 +73,34 @@ function New-AzVm { $locationi.Value = $Location; } - $createParams = [CreateParams]::new($Name, $locationi.Value, $Name); + $createParams = [CreateParams]::new($Name, $locationi.Value, $Name, $context); if ($PSCmdlet.ShouldProcess($Name, "Creating a virtual machine")) { + if ($AsJob) { + $boundParams = $PSCmdlet.MyInvocation.BoundParameters + $arguments = @{ 'AzureRmContext' = $context } + foreach ($argName in $boundParams.Keys) { + if ($argName -ne 'AsJob' -and $argName -ne 'AzureRmContext') { + $arguments[$argName] = $boundParams[$argName] + } + } $script = { - param($rgi, $vmi, $createParams) - New-AzVmInternal ` - -ResourceGroup $rgi ` - -VirtualMachine $vmi ` - -CreateParams $createParams ` - -ErrorAction Stop + [hashtable] $params = $args[0] + New-AzVm @params } - return Start-Job -ScriptBlock $script -ArgumentList @($rgi, $vmi, $createParams) + return Start-Job $script -ArgumentList $arguments } else { - return New-AzVmInternal ` - -ResourceGroup $rgi ` - -VirtualMachine $vmi ` - -CreateParams $createParams ` - -ErrorAction Stop + $rg = $rgi.GetOrCreate($createParams); + $vmResponse = $vmi.Create($createParams); + return [PSAzureVm]::new( + $rg.ResourceId, + $VirtualMachine.Name + ); } } } } -function New-AzVmInternal { - param ( - [ResourceGroup] $ResourceGroup, - [VirtualMachine] $VirtualMachine, - [CreateParams] $createParams - ) - - $rg = $ResourceGroup.GetOrCreate($createParams); - $vmResponse = $VirtualMachine.Create($createParams); - - return [PSAzureVm]::new( - $rg.ResourceId, - $VirtualMachine.Name - ); -} class PSAzureVm { [string] $ResourceGroupId; @@ -128,11 +126,18 @@ class CreateParams { [string] $Name; [string] $Location; [string] $ResourceGroupName; + [object] $Context; - CreateParams([string] $name, [string] $location, [string] $resourceGroupName) { - $this.Name = $name; - $this.Location = $location; - $this.ResourceGroupName = $resourceGroupName; + CreateParams( + [string] $name, + [string] $location, + [string] $resourceGroupName, + [object] $context) + { + $this.Name = $name + $this.Location = $location + $this.ResourceGroupName = $resourceGroupName + $this.Context = $context } } @@ -154,7 +159,7 @@ class AzureObject { } # This function should be called only when $this.Name is not $null. - [object] GetInfo() { + [object] GetInfo([object] $context) { return $null; } @@ -162,14 +167,14 @@ class AzureObject { return $null; } - [void] UpdateLocation([Location] $location) { + [void] UpdateLocation([Location] $location, [object] $context) { if ($this.Priority -gt $location.Priority) { if ($this.Name) { - $location.Value = $this.GetInfo().Location; + $location.Value = $this.GetInfo($context).Location; $location.Priority = $this.Priority; } else { foreach ($child in $this.Children) { - $child.UpdateLocation($location); + $child.UpdateLocation($location, $context); } } } @@ -177,7 +182,7 @@ class AzureObject { [object] GetOrCreate([CreateParams] $p) { if ($this.Name) { - return $this.GetInfo(); + return $this.GetInfo($p.Context); } else { $result = $this.Create($p); $this.Name = $p.Name; @@ -190,14 +195,15 @@ class ResourceGroup: AzureObject { ResourceGroup([string] $name): base($name, @()) { } - [object] GetInfo() { - return Get-AzureRmResourceGroup -Name $this.Name; + [object] GetInfo([object] $context) { + return Get-AzureRmResourceGroup -Name $this.Name -AzureRmContext $context; } [object] Create([CreateParams] $p) { return New-AzureRmResourceGroup ` -Name $p.Name ` -Location $p.Location ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop; } @@ -215,8 +221,8 @@ class VirtualNetwork: Resource1 { $this.AddressPrefix = $addressPrefix } - [object] GetInfo() { - return Get-AzureRmVirtualNetwork -Name $this.Name + [object] GetInfo([object] $context) { + return Get-AzureRmVirtualNetwork -Name $this.Name -AzureRmContext $context } [object] Create([CreateParams] $p) { @@ -225,6 +231,7 @@ class VirtualNetwork: Resource1 { -Location $p.Location ` -Name $p.Name ` -AddressPrefix $this.AddressPrefix ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop } @@ -243,8 +250,8 @@ class PublicIpAddress: Resource1 { $this.AllocationMethod = $allocationMethod; } - [object] GetInfo() { - return Get-AzureRMPublicIpAddress -Name $this.Name; + [object] GetInfo([object] $context) { + return Get-AzureRMPublicIpAddress -Name $this.Name -AzureRmContext $context; } [object] Create([CreateParams] $p) { @@ -254,6 +261,7 @@ class PublicIpAddress: Resource1 { -Name $p.Name ` -DomainNameLabel $this.DomainNameLabel.ToLower() ` -AllocationMethod $this.AllocationMethod ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop } @@ -266,8 +274,8 @@ class SecurityGroup: Resource1 { $this.OpenPorts = $OpenPorts; } - [object] GetInfo() { - return Get-AzureRMSecurityGroup -Name $this.Name + [object] GetInfo([object] $context) { + return Get-AzureRMSecurityGroup -Name $this.Name -AzureRmContext $context } [object] Create([CreateParams] $p) { @@ -294,6 +302,7 @@ class SecurityGroup: Resource1 { -Location $p.Location ` -Name $p.Name ` -SecurityRules $rules ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop } @@ -305,13 +314,13 @@ class Subnet: AzureObject { Subnet([string] $name, [VirtualNetwork] $virtualNetwork, [string] $subnetAddressPrefix): base($name, @($virtualNetwork)) { - $this.VirtualNetwork = $virtualNetwork; - $this.SubnetAddressPrefix = $subnetAddressPrefix; + $this.VirtualNetwork = $virtualNetwork + $this.SubnetAddressPrefix = $subnetAddressPrefix } - [object] GetInfo() { - $virutalNetworkInfo = $this.VirtualNetwork.GetInfo(); - return $virutalNetworkInfo | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name; + [object] GetInfo([object] $context) { + $virutalNetworkInfo = $this.VirtualNetwork.GetInfo($context) + return $virutalNetworkInfo | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name } [object] Create([CreateParams] $p) { @@ -320,9 +329,11 @@ class Subnet: AzureObject { -VirtualNetwork $virtualNetworkInfo ` -Name $p.Name ` -AddressPrefix $this.SubnetAddressPrefix; - $virtualNetworkInfo = Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetworkInfo -ErrorAction Stop - $result = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name - return $result; + $virtualNetworkInfo = Set-AzureRmVirtualNetwork ` + -VirtualNetwork $virtualNetworkInfo ` + -AzureRmContext $p.Context ` + -ErrorAction Stop + return Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name } } @@ -342,8 +353,8 @@ class NetworkInterface: AzureObject { $this.SecurityGroup = $securityGroup; } - [object] GetInfo() { - return Get-AzureRMNetworkInterface -Name $this.Name; + [object] GetInfo([object] $context) { + return Get-AzureRMNetworkInterface -Name $this.Name -AzureRmContext $context; } [object] Create([CreateParams] $p) { @@ -357,6 +368,7 @@ class NetworkInterface: AzureObject { -PublicIpAddressId $publicIpAddressInfo.Id ` -SubnetId $subnetInfo.Id ` -NetworkSecurityGroupId $securityGroupInfo.Id ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop } @@ -386,17 +398,13 @@ class VirtualMachine: AzureObject { $this.Size = $size; } - [object] GetInfo() { - return Get-AzureRMVirtualMachine -Name $this.Name; + [object] GetInfo([object] $context) { + return Get-AzureRMVirtualMachine -Name $this.Name -AzureRmContext $context; } [object] Create([CreateParams] $p) { $networkInterfaceInstance = $this.NetworkInterface.GetOrCreate($p); - if (-not $this.Credential) { - $this.Credential = Get-Credential; - } - $vmImage = $this.Images | Where-Object { $_.Name -eq $this.ImageName } | Select-Object -First 1; if (-not $vmImage) { throw "Unknown image: " + $this.ImageName; @@ -437,6 +445,7 @@ class VirtualMachine: AzureObject { -ResourceGroupName $p.ResourceGroupName ` -Location $p.Location ` -VM $vmConfig ` + -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` -ErrorAction Stop } @@ -539,4 +548,4 @@ $images = $staticImages.psobject.Properties | ForEach-Object { } } -Export-ModuleMember -Function New-AzVm \ No newline at end of file +Export-ModuleMember -Function New-AzVm diff --git a/experiments/Compute.Experiments/publish-dev.ps1 b/experiments/Compute.Experiments/publish-dev.ps1 index ac1402c1fe90..06a866960e94 100644 --- a/experiments/Compute.Experiments/publish-dev.ps1 +++ b/experiments/Compute.Experiments/publish-dev.ps1 @@ -6,10 +6,10 @@ mkdir $out Copy-Item .\AzureRM.Compute.Experiments.psd1 $out Copy-Item .\AzureRM.Compute.Experiments.psm1 $out New-ExternalHelp -Path .\docs\ -OutputPath $out -foreach ($d in $dep) { - Install-Module $d -Repository $repository -} +# foreach ($d in $dep) { +# Install-Module $d -Repository $repository +# } Publish-Module -Path $out -Repository $repository -NuGetApiKey somekey -foreach ($d in $dep) { - Uninstall-Module $d -} +# foreach ($d in $dep) { +# Uninstall-Module $d +# } From 040ac7c53a38bcdd63bb696b76cf4c87b50af7bc Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Tue, 19 Sep 2017 16:31:19 -0700 Subject: [PATCH 09/11] New help. --- .../help/AzureRM.Compute.Experiments.md | 16 ++ .../Compute.Experiments/help/New-AzVm.md | 181 +++++++++++++++++- 2 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 experiments/Compute.Experiments/help/AzureRM.Compute.Experiments.md diff --git a/experiments/Compute.Experiments/help/AzureRM.Compute.Experiments.md b/experiments/Compute.Experiments/help/AzureRM.Compute.Experiments.md new file mode 100644 index 000000000000..7cf6d49ac3ef --- /dev/null +++ b/experiments/Compute.Experiments/help/AzureRM.Compute.Experiments.md @@ -0,0 +1,16 @@ +--- +Module Name: AzureRM.Compute.Experiments +Module Guid: {{ Update Module Guid }} +Download Help Link: {{ Update Download Link }} +Help Version: {{ Update Help Version }} +Locale: {{ Update Locale }} +--- + +# AzureRM.Compute.Experiments Module +## Description +{{Manually Enter Description Here}} + +## AzureRM.Compute.Experiments Cmdlets +### [New-AzVm](New-AzVm.md) +Creates a virtual machine and all required resources. + diff --git a/experiments/Compute.Experiments/help/New-AzVm.md b/experiments/Compute.Experiments/help/New-AzVm.md index 8f75bd817378..fb3dca5e579b 100644 --- a/experiments/Compute.Experiments/help/New-AzVm.md +++ b/experiments/Compute.Experiments/help/New-AzVm.md @@ -13,9 +13,11 @@ Creates a virtual machine and all required resources. ## SYNTAX ``` -New-AzVm [-Name] [[-Credential] ] [[-ImageName] ] - [[-ResourceGroupName] ] [[-Location] ] [[-VirtualNetworkName] ] - [[-PublicIpAddressName] ] [[-SecurityGroupName] ] +New-AzVm [-Name] [-Credential] [[-ResourceGroupName] ] [[-Location] ] + [[-VirtualNetworkName] ] [-AddressPrefix ] [-SubnetName ] + [-SubnetAddressPrefix ] [[-PublicIpAddressName] ] [-DomainNameLabel ] + [-AllocationMethod ] [[-SecurityGroupName] ] [-OpenPorts ] [[-ImageName] ] + [-Size ] [-AzureRmContext ] [-AsJob] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION @@ -32,7 +34,68 @@ Creates a virtual machine with name `MyCoolVM`. ## PARAMETERS +### -AddressPrefix +Specifies a range of IP addresses for a virtual network. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AllocationMethod +Specifies the method with which to allocate the public IP address. The acceptable values for this parameter are: Static or Dynamic. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AsJob +Specifies the cmdlet executes as a job. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -AzureRmContext +Azure context. + +```yaml +Type: Object +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Credential + Specifies the user name and password for the virtual machine as a PSCredential object. ```yaml @@ -40,13 +103,29 @@ Type: PSCredential Parameter Sets: (All) Aliases: -Required: False +Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` +### -DomainNameLabel + +Specifies the relative DNS name for a public IP address. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -ImageName A name of virtual machine image. @@ -92,6 +171,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -OpenPorts +Ports. + +```yaml +Type: Int32[] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -PublicIpAddressName Specifies a name of PublicIPAddress object to assign to a network interface. @@ -137,6 +231,51 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Size +Specifies the size for the virtual machine. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SubnetAddressPrefix +Specifies a range of IP addresses for a subnet configuration. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SubnetName +Specifies the name of the subnet configuration to create. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -VirtualNetworkName Specifies a Virtual Network name. @@ -152,11 +291,43 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Confirm +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). + ## INPUTS ### None - ## OUTPUTS ### System.Object From fa7f2f6e7e7a76110133d84ed32258eb70386a59 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Tue, 19 Sep 2017 16:34:20 -0700 Subject: [PATCH 10/11] remove export of "New-AzVmInternal --- .../Compute.Experiments/AzureRM.Compute.Experiments.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 index 7b5ba6f27ecf..10881a43238b 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 @@ -73,7 +73,7 @@ RequiredModules = @( # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'New-AzVm', 'New-AzVmInternal' +FunctionsToExport = 'New-AzVm' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. # CmdletsToExport = From f3103c8311be3a6b23fc77366c4caf4a7c144d86 Mon Sep 17 00:00:00 2001 From: Sergey Shandar Date: Wed, 20 Sep 2017 16:08:51 -0700 Subject: [PATCH 11/11] idempotent creation of resources --- .../AzureRM.Compute.Experiments.Tests.ps1 | 25 +- .../AzureRM.Compute.Experiments.psm1 | 253 +++++++++++------- 2 files changed, 174 insertions(+), 104 deletions(-) diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index 1ec2b6658862..7129be2d677d 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 @@ -1,9 +1,9 @@ -# $build = "..\build\" -# $out = $build + "AzureRM.Compute.Experiments\" -# Copy-Item .\AzureRM.Compute.Experiments.psd1 $out -# Copy-Item .\AzureRM.Compute.Experiments.psm1 $out +$build = Resolve-Path "..\build\" +$out = Join-Path $build "AzureRM.Compute.Experiments\" +Copy-Item .\AzureRM.Compute.Experiments.psd1 $out +Copy-Item .\AzureRM.Compute.Experiments.psm1 $out -$env:PSModulePath = $env:PSModulePath + ";" + $build +$env:PSModulePath = $env:PSModulePath + ";" + $build.ToString() # Login $credentials = Get-Content -Path "C:\Users\sergey\Desktop\php-test.json" | ConvertFrom-Json @@ -25,19 +25,16 @@ New-AzVm -Name MyVM -Credential $vmCredential -WhatIf # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential -# $vm = New-AzVm -Name MyVMA -Credential $vmCredential +$vm = New-AzVm -Name MyVMA1 -Credential $vmCredential -ResourceGroupName Crocodile # $vm = New-AzVm -Name MyVMA $vm -Write-Host "" - -$job = New-AzVm -Name MyVMA2 -Credential $vmCredential -AsJob -$vm = Receive-Job $job - -$vm - -Write-Host "" +# Write-Host "" +# $job = New-AzVm -Name MyVMA3 -Credential $vmCredential -AsJob +# $vm = Receive-Job $job -Wait +# $vm +# Write-Host "" # clean-up Remove-AzureRmResourceGroup -ResourceId $vm.ResourceGroupId \ No newline at end of file diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index d0e63b5648c1..b82bfef37acf 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -40,14 +40,15 @@ function New-AzVm { $rgi = [ResourceGroup]::new($ResourceGroupName) - $vni = [VirtualNetwork]::new($VirtualNetworkName, $AddressPrefix) + $vni = [VirtualNetwork]::new($VirtualNetworkName, $rgi, $AddressPrefix) $subnet = [Subnet]::new($SubnetName, $vni, $SubnetAddressPrefix) - $piai = [PublicIpAddress]::new($PublicIpAddressName, $DomainNameLabel, $AllocationMethod) - $sgi = [SecurityGroup]::new($SecurityGroupName, $OpenPorts) + $piai = [PublicIpAddress]::new($PublicIpAddressName, $rgi, $DomainNameLabel, $AllocationMethod) + $sgi = [SecurityGroup]::new($SecurityGroupName, $rgi, $OpenPorts) # we don't allow to reuse NetworkInterface so $name is $null. $nii = [NetworkInterface]::new( $null, + $rgi, $subnet, $piai, $sgi) @@ -55,28 +56,27 @@ function New-AzVm { # the purpouse of the New-AzVm cmdlet is to create (not get) a VM so $name is $null. $vmi = [VirtualMachine]::new( $null, - $nii, $rgi, + $nii, $Credential, $ImageName, $images, - $Size); + $Size) # infer a location - $locationi = [Location]::new(); + $locationi = [Location]::new() if (-not $Location) { - $vmi.UpdateLocation($locationi, $context); + $vmi.UpdateLocation($locationi, $context) if (-not $locationi.Value) { - $locationi.Value = "eastus"; + $locationi.Value = "eastus" } } else { - $locationi.Value = $Location; + $locationi.Value = $Location } - $createParams = [CreateParams]::new($Name, $locationi.Value, $Name, $context); + $createParams = [CreateParams]::new($Name, $locationi.Value, $context) if ($PSCmdlet.ShouldProcess($Name, "Creating a virtual machine")) { - if ($AsJob) { $boundParams = $PSCmdlet.MyInvocation.BoundParameters $arguments = @{ 'AzureRmContext' = $context } @@ -91,12 +91,13 @@ function New-AzVm { } return Start-Job $script -ArgumentList $arguments } else { - $rg = $rgi.GetOrCreate($createParams); - $vmResponse = $vmi.Create($createParams); + # Force to create Resource Group before anything else. + $rg = $rgi.GetOrCreate($createParams) + $vmResponse = $vmi.Create($createParams) return [PSAzureVm]::new( $rg.ResourceId, $VirtualMachine.Name - ); + ) } } } @@ -107,8 +108,8 @@ class PSAzureVm { [string] $Name; PSAzureVm([string] $resourceGroupId, [string] $name) { - $this.ResourceGroupId = $resourceGroupId; - $this.Name = $name; + $this.ResourceGroupId = $resourceGroupId + $this.Name = $name } } @@ -117,26 +118,23 @@ class Location { [string] $Value; Location() { - $this.Priority = 0; - $this.Value = $null; + $this.Priority = 0 + $this.Value = $null } } class CreateParams { [string] $Name; [string] $Location; - [string] $ResourceGroupName; [object] $Context; CreateParams( [string] $name, [string] $location, - [string] $resourceGroupName, [object] $context) { $this.Name = $name $this.Location = $location - $this.ResourceGroupName = $resourceGroupName $this.Context = $context } } @@ -145,49 +143,71 @@ class AzureObject { [string] $Name; [AzureObject[]] $Children; [int] $Priority; + [object] $info = $null; AzureObject([string] $name, [AzureObject[]] $children) { - $this.Name = $name; - $this.Children = $children; - $this.Priority = 0; + $this.Name = $name + $this.Children = $children + $this.Priority = 0 foreach ($child in $this.Children) { if ($this.Priority -lt $child.Priority) { - $this.Priority = $child.Priority; + $this.Priority = $child.Priority } } - $this.Priority++; + $this.Priority++ } - # This function should be called only when $this.Name is not $null. - [object] GetInfo([object] $context) { - return $null; + [object] GetInfoOrThrow([object] $context) { + return $null } [object] Create([CreateParams] $p) { - return $null; + return $null + } + + # This function should be called only when $this.Name is not $null. + [object] GetInfo([object] $context) { + if (!$this.Info) { + try { + $this.Info = $this.GetInfoOrThrow($context) + } catch { + # ignore all errors + } + } + return $this.Info; } [void] UpdateLocation([Location] $location, [object] $context) { if ($this.Priority -gt $location.Priority) { if ($this.Name) { - $location.Value = $this.GetInfo($context).Location; - $location.Priority = $this.Priority; - } else { - foreach ($child in $this.Children) { - $child.UpdateLocation($location, $context); + $i = $this.GetInfo($context) + if ($i) { + $location.Value = $i.Location + $location.Priority = $this.Priority + return; } } + foreach ($child in $this.Children) { + $child.UpdateLocation($location, $context) + } } } [object] GetOrCreate([CreateParams] $p) { + $i = $this.GetInfo($p.Context) + if ($i) { + return $i + } if ($this.Name) { - return $this.GetInfo($p.Context); - } else { - $result = $this.Create($p); - $this.Name = $p.Name; - return $result; + $p = [CreateParams]::new( + $this.Name, + $p.Location, + $p.Context + ) } + $this.Info = $this.Create($p) + $this.Name = $p.Name + return $this.Info } } @@ -195,8 +215,11 @@ class ResourceGroup: AzureObject { ResourceGroup([string] $name): base($name, @()) { } - [object] GetInfo([object] $context) { - return Get-AzureRmResourceGroup -Name $this.Name -AzureRmContext $context; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRmResourceGroup ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { @@ -205,29 +228,54 @@ class ResourceGroup: AzureObject { -Location $p.Location ` -AzureRmContext $p.Context ` -WarningAction SilentlyContinue ` - -ErrorAction Stop; + -ErrorAction Stop } } class Resource1: AzureObject { - Resource1([string] $name): base($name, @([ResourceGroup]::new($null))) { + [ResourceGroup] $ResourceGroup; + + Resource1( + [string] $name, + [ResourceGroup] $resourceGroup, + [AzureObject[]] $children + ): base($name, @($children)) { + $this.ResourceGroup = $resourceGroup + } + + Resource1( + [string] $name, + [ResourceGroup] $resourceGroup + ): base($name, @($resourceGroup)) { + $this.ResourceGroup = $resourceGroup + } + + [string] GetResourceGroupName([CreateParams] $p) { + return $this.ResourceGroup.GetOrCreate($p).ResourceGroupName; } } class VirtualNetwork: Resource1 { [string] $AddressPrefix; - VirtualNetwork([string] $name, [string] $addressPrefix): base($name) { + VirtualNetwork( + [string] $name, + [ResourceGroup] $resourceGroup, + [string] $addressPrefix + ): base($name, $resourceGroup) { $this.AddressPrefix = $addressPrefix } - [object] GetInfo([object] $context) { - return Get-AzureRmVirtualNetwork -Name $this.Name -AzureRmContext $context + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRmVirtualNetwork ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { return New-AzureRmVirtualNetwork ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` -AddressPrefix $this.AddressPrefix ` @@ -243,20 +291,24 @@ class PublicIpAddress: Resource1 { PublicIpAddress( [string] $name, + [ResourceGroup] $resourceGroup, [string] $domainNameLabel, [string] $allocationMethod - ): base($name) { - $this.DomainNameLabel = $domainNameLabel; - $this.AllocationMethod = $allocationMethod; + ): base($name, $resourceGroup) { + $this.DomainNameLabel = $domainNameLabel + $this.AllocationMethod = $allocationMethod } - [object] GetInfo([object] $context) { - return Get-AzureRMPublicIpAddress -Name $this.Name -AzureRmContext $context; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMPublicIpAddress ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { return New-AzureRmPublicIpAddress ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` -DomainNameLabel $this.DomainNameLabel.ToLower() ` @@ -270,16 +322,24 @@ class PublicIpAddress: Resource1 { class SecurityGroup: Resource1 { [int[]] $OpenPorts; - SecurityGroup([string] $name, [int[]] $OpenPorts): base($name) { - $this.OpenPorts = $OpenPorts; + SecurityGroup( + [string] $name, + [ResourceGroup] $resourceGroup, + [int[]] $OpenPorts + ): base($name, $resourceGroup) { + $this.OpenPorts = $OpenPorts } - [object] GetInfo([object] $context) { - return Get-AzureRMSecurityGroup -Name $this.Name -AzureRmContext $context + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMSecurityGroup ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { - $rules = New-Object "System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSSecurityRule]" + $rules = New-Object ` + "System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSSecurityRule]" $priority = 1000 foreach ($port in $this.OpenPorts) { $name = $p.Name + $port @@ -298,7 +358,7 @@ class SecurityGroup: Resource1 { ++$priority } return New-AzureRmNetworkSecurityGroup ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` -SecurityRules $rules ` @@ -318,51 +378,61 @@ class Subnet: AzureObject { $this.SubnetAddressPrefix = $subnetAddressPrefix } - [object] GetInfo([object] $context) { + [object] GetInfoOrThrow([object] $context) { $virutalNetworkInfo = $this.VirtualNetwork.GetInfo($context) - return $virutalNetworkInfo | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name + if (!$virutalNetworkInfo) { + return $null + } + return $virutalNetworkInfo ` + | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name -ErrorAction Stop } [object] Create([CreateParams] $p) { - $virtualNetworkInfo = $this.VirtualNetwork.GetOrCreate($p); + $virtualNetworkInfo = $this.VirtualNetwork.GetOrCreate($p) Add-AzureRmVirtualNetworkSubnetConfig ` -VirtualNetwork $virtualNetworkInfo ` -Name $p.Name ` - -AddressPrefix $this.SubnetAddressPrefix; + -AddressPrefix $this.SubnetAddressPrefix $virtualNetworkInfo = Set-AzureRmVirtualNetwork ` -VirtualNetwork $virtualNetworkInfo ` -AzureRmContext $p.Context ` -ErrorAction Stop - return Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $virtualNetworkInfo -Name $p.Name + return Get-AzureRmVirtualNetworkSubnetConfig ` + -VirtualNetwork $virtualNetworkInfo ` + -Name $p.Name } } -class NetworkInterface: AzureObject { +class NetworkInterface: Resource1 { [Subnet] $Subnet; [PublicIpAddress] $PublicIpAddress; [SecurityGroup] $SecurityGroup; NetworkInterface( [string] $name, + [ResourceGroup] $resourceGroup, [Subnet] $subnet, [PublicIpAddress] $publicIpAddress, [SecurityGroup] $securityGroup - ): base($name, @($subnet, $publicIpAddress, $securityGroup)) { - $this.Subnet = $subnet; - $this.PublicIpAddress = $publicIpAddress; - $this.SecurityGroup = $securityGroup; + ): base($name, $resourceGroup, @($subnet, $publicIpAddress, $securityGroup)) { + $this.Subnet = $subnet + $this.PublicIpAddress = $publicIpAddress + $this.SecurityGroup = $securityGroup } - [object] GetInfo([object] $context) { - return Get-AzureRMNetworkInterface -Name $this.Name -AzureRmContext $context; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMNetworkInterface ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { - $publicIpAddressInfo = $this.PublicIpAddress.GetOrCreate($p); - $subnetInfo = $this.Subnet.GetOrCreate($p); - $securityGroupInfo = $this.SecurityGroup.GetOrCreate($p); + $publicIpAddressInfo = $this.PublicIpAddress.GetOrCreate($p) + $subnetInfo = $this.Subnet.GetOrCreate($p) + $securityGroupInfo = $this.SecurityGroup.GetOrCreate($p) return New-AzureRmNetworkInterface ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` -PublicIpAddressId $publicIpAddressInfo.Id ` @@ -374,7 +444,7 @@ class NetworkInterface: AzureObject { } } -class VirtualMachine: AzureObject { +class VirtualMachine: Resource1 { [NetworkInterface] $NetworkInterface; [pscredential] $Credential; [string] $ImageName; @@ -383,31 +453,34 @@ class VirtualMachine: AzureObject { VirtualMachine( [string] $name, - [NetworkInterface] $networkInterface, [ResourceGroup] $resourceGroup, + [NetworkInterface] $networkInterface, [PSCredential] $credential, [string] $imageName, [object] $images, [string] $size): - base($name, @($networkInterface, $resourceGroup)) { + base($name, $resourceGroup, @($networkInterface)) { - $this.Credential = $credential; - $this.ImageName = $imageName; - $this.NetworkInterface = $networkInterface; - $this.Images = $images; - $this.Size = $size; + $this.Credential = $credential + $this.ImageName = $imageName + $this.NetworkInterface = $networkInterface + $this.Images = $images + $this.Size = $size } - [object] GetInfo([object] $context) { - return Get-AzureRMVirtualMachine -Name $this.Name -AzureRmContext $context; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMVirtualMachine ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { - $networkInterfaceInstance = $this.NetworkInterface.GetOrCreate($p); + $networkInterfaceInstance = $this.NetworkInterface.GetOrCreate($p) - $vmImage = $this.Images | Where-Object { $_.Name -eq $this.ImageName } | Select-Object -First 1; + $vmImage = $this.Images | Where-Object { $_.Name -eq $this.ImageName } | Select-Object -First 1 if (-not $vmImage) { - throw "Unknown image: " + $this.ImageName; + throw "Unknown image: " + $this.ImageName } $vmConfig = New-AzureRmVMConfig -VMName $p.Name -VMSize $this.Size -ErrorAction Stop @@ -442,7 +515,7 @@ class VirtualMachine: AzureObject { -ErrorAction Stop return New-AzureRmVm ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -VM $vmConfig ` -AzureRmContext $p.Context `