diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.Tests.ps1 index 2bc2c51f4506..7129be2d677d 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 .\..\..\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 .\..\..\experiments\Compute.Experiments\AzureRM.Compute.Experiments.psd1 +$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.ToString() # Login $credentials = Get-Content -Path "C:\Users\sergey\Desktop\php-test.json" | ConvertFrom-Json @@ -17,11 +18,23 @@ $vmCredential = New-Object System.Management.Automation.PSCredential ($vmCompute New-AzVm -Name MyVM -Credential $vmCredential -WhatIf +# $job = New-AzVm -Name MyVMA -Credential $vmCredential -AsJob +# Receive-Job $job + +# exit + # $vm = New-AzVm # $vm = New-AzVm -Credential $vmCredential -$vm = New-AzVm -Name MyVM -Credential $vmCredential +$vm = New-AzVm -Name MyVMA1 -Credential $vmCredential -ResourceGroupName Crocodile +# $vm = New-AzVm -Name MyVMA $vm +# 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.psd1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 index a68c03dea379..10881a43238b 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psd1 @@ -1,126 +1,126 @@ -# -# Module manifest for module 'AzureRM.Compute.Experiments' -# -# Generated by: Microsoft -# -# Generated on: 9/1/2017 -# - -@{ - -# Script module or binary module file associated with this manifest. -RootModule = ".\AzureRM.Compute.Experiments.psm1" - -# Version number of this module. -ModuleVersion = '1.0.7' - -# Supported PSEditions -# CompatiblePSEditions = @() - -# ID used to uniquely identify this module -GUID = 'b5a94030-df85-43fa-b581-54069f88428f' - -# Author of this module -Author = 'Microsoft' - -# Company or vendor of this module -CompanyName = 'Microsoft' - -# Copyright statement for this module -Copyright = 'Microsoft' - -# Description of the functionality provided by this module -Description = 'Azure Compute experiments for VM creation' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '5.0' - -# Name of the Windows PowerShell host required by this module -# PowerShellHostName = '' - -# Minimum version of the Windows PowerShell host required by this module -# PowerShellHostVersion = '' - -# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. -# DotNetFrameworkVersion = '' - -# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. -# CLRVersion = '' - -# Processor architecture (None, X86, Amd64) required by this module -# ProcessorArchitecture = '' - -# 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"; } -) - -# Assemblies that must be loaded prior to importing this module -# RequiredAssemblies = @() - -# Script files (.ps1) that are run in the caller's environment prior to importing this module. -# ScriptsToProcess = @() - -# Type files (.ps1xml) to be loaded when importing this module -# TypesToProcess = @() - -# Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() - -# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -# 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' - -# 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 = - -# Variables to export from this module -VariablesToExport = '*' - -# Aliases 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 aliases to export. -AliasesToExport = @() - -# DSC resources to export from this module -# DscResourcesToExport = @() - -# List of all modules packaged with this module -# ModuleList = @() - -# List of all files packaged with this module -# FileList = @() - -# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. -PrivateData = @{ - - PSData = @{ - - # Tags applied to this module. These help with module discovery in online galleries. - # Tags = @() - - # A URL to the license for this module. - # LicenseUri = '' - - # A URL to the main website for this project. - # ProjectUri = '' - - # A URL to an icon representing this module. - # IconUri = '' - - # ReleaseNotes of this module - # ReleaseNotes = '' - - } # End of PSData hashtable - -} # End of PrivateData hashtable - -# HelpInfo URI of this module -# HelpInfoURI = '' - -# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. -# DefaultCommandPrefix = '' - -} +# +# Module manifest for module 'AzureRM.Compute.Experiments' +# +# Generated by: Microsoft +# +# Generated on: 9/1/2017 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = ".\AzureRM.Compute.Experiments.psm1" + +# Version number of this module. +ModuleVersion = '1.0.19' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'b5a94030-df85-43fa-b581-54069f88428f' + +# Author of this module +Author = 'Microsoft' + +# Company or vendor of this module +CompanyName = 'Microsoft' + +# Copyright statement for this module +Copyright = 'Microsoft' + +# Description of the functionality provided by this module +Description = 'Azure Compute experiments for VM creation' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '5.0' + +# Name of the Windows PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the Windows PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# CLRVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +RequiredModules = @( + @{ 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 +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# 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' + +# 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 = + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases 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 aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} diff --git a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 index d8520069081f..b82bfef37acf 100644 --- a/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 +++ b/experiments/Compute.Experiments/AzureRM.Compute.Experiments.psm1 @@ -5,64 +5,100 @@ 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()][string] $ImageName = "Win2016Datacenter", + [Parameter()][string] $Size = "Standard_DS1_v2", - [Parameter()][PSCredential] $Credential, - [Parameter()][string] $ImageName = "Win2012R2Datacenter", - [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 + } - $vni = [VirtualNetwork]::new($VirtualNetworkName); - $piai = [PublicIpAddress]::new($PublicIpAddressName); - $sgi = [SecurityGroup]::new($SecurityGroupName); + $rgi = [ResourceGroup]::new($ResourceGroupName) + + $vni = [VirtualNetwork]::new($VirtualNetworkName, $rgi, $AddressPrefix) + $subnet = [Subnet]::new($SubnetName, $vni, $SubnetAddressPrefix) + $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, - $vni, + $rgi, + $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( $null, - $nii, $rgi, + $nii, $Credential, $ImageName, $images, - $Size); + $Size) # infer a location - $locationi = [Location]::new(); + $locationi = [Location]::new() if (-not $Location) { - $vmi.UpdateLocation($locationi); + $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); + $createParams = [CreateParams]::new($Name, $locationi.Value, $context) if ($PSCmdlet.ShouldProcess($Name, "Creating a virtual machine")) { - $resourceGroup = $rgi.GetOrCreate($createParams); - $vmResponse = $vmi.Create($createParams); - - return [PSAzureVm]::new( - $resourceGroup.ResourceId, - $Name - ); + 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 = { + [hashtable] $params = $args[0] + New-AzVm @params + } + return Start-Job $script -ArgumentList $arguments + } else { + # Force to create Resource Group before anything else. + $rg = $rgi.GetOrCreate($createParams) + $vmResponse = $vmi.Create($createParams) + return [PSAzureVm]::new( + $rg.ResourceId, + $VirtualMachine.Name + ) + } } } } @@ -72,8 +108,8 @@ class PSAzureVm { [string] $Name; PSAzureVm([string] $resourceGroupId, [string] $name) { - $this.ResourceGroupId = $resourceGroupId; - $this.Name = $name; + $this.ResourceGroupId = $resourceGroupId + $this.Name = $name } } @@ -82,20 +118,24 @@ 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) { - $this.Name = $name; - $this.Location = $location; - $this.ResourceGroupName = $resourceGroupName; + CreateParams( + [string] $name, + [string] $location, + [object] $context) + { + $this.Name = $name + $this.Location = $location + $this.Context = $context } } @@ -103,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() { - 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) { + [void] UpdateLocation([Location] $location, [object] $context) { if ($this.Priority -gt $location.Priority) { if ($this.Name) { - $location.Value = $this.GetInfo().Location; - $location.Priority = $this.Priority; - } else { - foreach ($child in $this.Children) { - $child.UpdateLocation($location); + $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(); - } 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 } } @@ -153,128 +215,236 @@ class ResourceGroup: AzureObject { ResourceGroup([string] $name): base($name, @()) { } - [object] GetInfo() { - return Get-AzureRmResourceGroup -Name $this.Name; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRmResourceGroup ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { return New-AzureRmResourceGroup ` -Name $p.Name ` -Location $p.Location ` - -WarningAction SilentlyContinue; + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -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 { - VirtualNetwork([string] $name): base($name) { + [string] $AddressPrefix; + + VirtualNetwork( + [string] $name, + [ResourceGroup] $resourceGroup, + [string] $addressPrefix + ): base($name, $resourceGroup) { + $this.AddressPrefix = $addressPrefix } - [object] GetInfo() { - return Get-AzureRmVirtualNetwork -Name $this.Name; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRmVirtualNetwork ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { - $subnetConfig = New-AzureRmVirtualNetworkSubnetConfig ` - -Name "Subnet" ` - -AddressPrefix "192.168.1.0/24" return New-AzureRmVirtualNetwork ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` - -AddressPrefix "192.168.0.0/16" ` - -Subnet $subnetConfig ` - -WarningAction SilentlyContinue + -AddressPrefix $this.AddressPrefix ` + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } class PublicIpAddress: Resource1 { - PublicIpAddress([string] $name): base($name) { + [string] $DomainNameLabel; + [string] $AllocationMethod; + + PublicIpAddress( + [string] $name, + [ResourceGroup] $resourceGroup, + [string] $domainNameLabel, + [string] $allocationMethod + ): base($name, $resourceGroup) { + $this.DomainNameLabel = $domainNameLabel + $this.AllocationMethod = $allocationMethod } - [object] GetInfo() { - return Get-AzureRMPublicIpAddress -Name $this.Name; + [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 ` - -AllocationMethod Static ` - -WarningAction SilentlyContinue + -DomainNameLabel $this.DomainNameLabel.ToLower() ` + -AllocationMethod $this.AllocationMethod ` + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } class SecurityGroup: Resource1 { - SecurityGroup([string] $name): base($name) { + [int[]] $OpenPorts; + + SecurityGroup( + [string] $name, + [ResourceGroup] $resourceGroup, + [int[]] $OpenPorts + ): base($name, $resourceGroup) { + $this.OpenPorts = $OpenPorts } - [object] GetInfo() { - return Get-AzureRMSecurityGroup -Name $this.Name; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMSecurityGroup ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [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]" + $priority = 1000 + foreach ($port in $this.OpenPorts) { + $name = $p.Name + $port + $securityRuleConfig = New-AzureRmNetworkSecurityRuleConfig ` + -Name $name ` + -Protocol "Tcp" ` + -Priority $priority ` + -Access "Allow" ` + -Direction "Inbound" ` + -SourcePortRange "*" ` + -SourceAddressPrefix "*" ` + -DestinationPortRange $port ` + -DestinationAddressPrefix "*" ` + -ErrorAction Stop + $rules.Add($securityRuleConfig) + ++$priority + } return New-AzureRmNetworkSecurityGroup ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` - -SecurityRules $securityRuleConfig ` - -WarningAction SilentlyContinue + -SecurityRules $rules ` + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } -class NetworkInterface: AzureObject { +class Subnet: AzureObject { [VirtualNetwork] $VirtualNetwork; + [string] $SubnetAddressPrefix; + + Subnet([string] $name, [VirtualNetwork] $virtualNetwork, [string] $subnetAddressPrefix): + base($name, @($virtualNetwork)) { + $this.VirtualNetwork = $virtualNetwork + $this.SubnetAddressPrefix = $subnetAddressPrefix + } + + [object] GetInfoOrThrow([object] $context) { + $virutalNetworkInfo = $this.VirtualNetwork.GetInfo($context) + if (!$virutalNetworkInfo) { + return $null + } + return $virutalNetworkInfo ` + | Get-AzureRmVirtualNetworkSubnetConfig -Name $this.Name -ErrorAction Stop + } + + [object] Create([CreateParams] $p) { + $virtualNetworkInfo = $this.VirtualNetwork.GetOrCreate($p) + Add-AzureRmVirtualNetworkSubnetConfig ` + -VirtualNetwork $virtualNetworkInfo ` + -Name $p.Name ` + -AddressPrefix $this.SubnetAddressPrefix + $virtualNetworkInfo = Set-AzureRmVirtualNetwork ` + -VirtualNetwork $virtualNetworkInfo ` + -AzureRmContext $p.Context ` + -ErrorAction Stop + return Get-AzureRmVirtualNetworkSubnetConfig ` + -VirtualNetwork $virtualNetworkInfo ` + -Name $p.Name + } +} + +class NetworkInterface: Resource1 { + [Subnet] $Subnet; [PublicIpAddress] $PublicIpAddress; [SecurityGroup] $SecurityGroup; NetworkInterface( [string] $name, - [VirtualNetwork] $virtualNetwork, + [ResourceGroup] $resourceGroup, + [Subnet] $subnet, [PublicIpAddress] $publicIpAddress, [SecurityGroup] $securityGroup - ): base($name, @($virtualNetwork, $publicIpAddress, $securityGroup)) { - $this.VirtualNetwork = $virtualNetwork; - $this.PublicIpAddress = $publicIpAddress; - $this.SecurityGroup = $securityGroup; + ): base($name, $resourceGroup, @($subnet, $publicIpAddress, $securityGroup)) { + $this.Subnet = $subnet + $this.PublicIpAddress = $publicIpAddress + $this.SecurityGroup = $securityGroup } - [object] GetInfo() { - return Get-AzureRMNetworkInterface -Name $this.Name; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMNetworkInterface ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [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) + $securityGroupInfo = $this.SecurityGroup.GetOrCreate($p) return New-AzureRmNetworkInterface ` - -ResourceGroupName $p.ResourceGroupName ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -Name $p.Name ` - -PublicIpAddressId $xpublicIpAddress.Id ` - -SubnetId $xvirtualNetwork.Subnets[0].Id ` - -NetworkSecurityGroupId $xsecurityGroup.Id ` - -WarningAction SilentlyContinue + -PublicIpAddressId $publicIpAddressInfo.Id ` + -SubnetId $subnetInfo.Id ` + -NetworkSecurityGroupId $securityGroupInfo.Id ` + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } -class VirtualMachine: AzureObject { +class VirtualMachine: Resource1 { [NetworkInterface] $NetworkInterface; [pscredential] $Credential; [string] $ImageName; @@ -283,51 +453,52 @@ 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() { - return Get-AzureRMVirtualMachine -Name $this.Name; + [object] GetInfoOrThrow([object] $context) { + return Get-AzureRMVirtualMachine ` + -Name $this.Name ` + -AzureRmContext $context ` + -ErrorAction Stop } [object] Create([CreateParams] $p) { - $networkInterfaceInstance = $this.NetworkInterface.GetOrCreate($p); - - if (-not $this.Credential) { - $this.Credential = Get-Credential; - } + $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; - $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 } } @@ -338,13 +509,18 @@ 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 ` + -ResourceGroupName $this.GetResourceGroupName($p) ` -Location $p.Location ` -VM $vmConfig ` - -WarningAction SilentlyContinue + -AzureRmContext $p.Context ` + -WarningAction SilentlyContinue ` + -ErrorAction Stop } } @@ -445,4 +621,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/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 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 +# }