diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/Common/ComputeAutoMapperProfile.cs b/src/CLU/Microsoft.Azure.Commands.Compute/Common/ComputeAutoMapperProfile.cs index f7d976c13afe..b49c3954e108 100644 --- a/src/CLU/Microsoft.Azure.Commands.Compute/Common/ComputeAutoMapperProfile.cs +++ b/src/CLU/Microsoft.Azure.Commands.Compute/Common/ComputeAutoMapperProfile.cs @@ -68,13 +68,13 @@ public static bool Initialize() protected override void Configure() { //Mapper.CreateMap(); - //Mapper.CreateMap(); + Mapper.CreateMap(); //Mapper.CreateMap(); Mapper.CreateMap(); //Mapper.CreateMap(); - //Mapper.CreateMap(); + Mapper.CreateMap(); //Mapper.CreateMap(); Mapper.CreateMap(); diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageCommand.cs new file mode 100644 index 000000000000..6258e05f4f19 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageCommand.cs @@ -0,0 +1,94 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Get, ProfileNouns.VirtualMachineExtensionImage)] + [OutputType(typeof(PSVirtualMachineExtensionImage))] + [OutputType(typeof(PSVirtualMachineExtensionImageDetails))] + public class GetAzureVMExtensionImageCommand : VirtualMachineExtensionImageBaseCmdlet + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] + public string Location { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] + public string PublisherName { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] + public string Type { get; set; } + + [Parameter, ValidateNotNullOrEmpty] + public string FilterExpression { get; set; } + + [Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)] + public string Version { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + if (string.IsNullOrEmpty(this.Version)) + { + // TODO, FilterExpression + var result = this.VirtualMachineExtensionImageClient.ListVersions(Location.Canonicalize(), PublisherName, Type); + + var images = from r in result + select new PSVirtualMachineExtensionImage + { + Id = r.Id, + Location = r.Location, + Version = r.Name, + PublisherName = this.PublisherName, + Type = this.Type, + FilterExpression = this.FilterExpression + }; + + WriteObject(result, true); + // TODO: Cannot Write the Result from Linq Select. + //WriteObject(images, true); + } + else + { + var result = this.VirtualMachineExtensionImageClient.Get(Location.Canonicalize(), PublisherName, Type, Version); + + var image = new PSVirtualMachineExtensionImageDetails + { + Id = result.Id, + Location = result.Location, + HandlerSchema = result.HandlerSchema, + OperatingSystem = result.OperatingSystem, + ComputeRole = result.ComputeRole, + SupportsMultipleExtensions = result.SupportsMultipleExtensions, + VMScaleSetEnabled = result.VmScaleSetEnabled, + Version = result.Name, + PublisherName = this.PublisherName, + Type = this.Type, + FilterExpression = this.FilterExpression + }; + + WriteObject(image); + } + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageTypeCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageTypeCommand.cs new file mode 100644 index 000000000000..52eaad14bfe0 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/GetAzureVMExtensionImageTypeCommand.cs @@ -0,0 +1,57 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Get, ProfileNouns.VirtualMachineExtensionImageType)] + [OutputType(typeof(PSVirtualMachineExtensionImageType))] + public class GetAzureVMExtensionImageTypeCommand : VirtualMachineExtensionImageBaseCmdlet + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] + public string Location { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] + public string PublisherName { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + var result = this.VirtualMachineExtensionImageClient.ListTypes(Location.Canonicalize(), PublisherName); + + var images = from r in result + select new PSVirtualMachineExtensionImageType + { + Id = r.Id, + Location = r.Location, + Type = r.Name, + PublisherName = this.PublisherName + }; + + WriteObject(result, true); + // TODO: Cannot Write the Result from Linq Select. + //WriteObject(images, true); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/VirtualMachineExtensionImageBaseCmdlet.cs b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/VirtualMachineExtensionImageBaseCmdlet.cs new file mode 100644 index 000000000000..226a9e74d983 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/ExtensionImages/VirtualMachineExtensionImageBaseCmdlet.cs @@ -0,0 +1,29 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Management.Compute; + +namespace Microsoft.Azure.Commands.Compute +{ + public abstract class VirtualMachineExtensionImageBaseCmdlet : ComputeClientBaseCmdlet + { + public IVirtualMachineExtensionImagesOperations VirtualMachineExtensionImageClient + { + get + { + return ComputeClient.ComputeManagementClient.VirtualMachineExtensionImages; + } + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachine.cs b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachine.cs new file mode 100644 index 000000000000..e5be5900dc62 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachine.cs @@ -0,0 +1,178 @@ +// +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Warning: This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if the +// code is regenerated. + +using Microsoft.Azure.Management.Compute.Models; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace Microsoft.Azure.Commands.Compute.Models +{ + public class PSVirtualMachine : PSOperation + { + // Gets or sets the property of 'ResourceGroupName' + public string ResourceGroupName + { + get + { + if (string.IsNullOrEmpty(Id)) return null; + Regex r = new Regex(@"(.*?)/resourcegroups/(?\S+)/providers/(.*?)", RegexOptions.IgnoreCase); + Match m = r.Match(Id); + return m.Success ? m.Groups["rgname"].Value : null; + } + } + + // Gets or sets the property of 'Id' + public string Id { get; set; } + + // Gets or sets the property of 'Name' + public string Name { get; set; } + + // Gets or sets the property of 'Type' + public string Type { get; set; } + + // Gets or sets the property of 'Location' + public string Location { get; set; } + + // Gets or sets the property of 'Tags' + public IDictionary Tags { get; set; } + + [JsonIgnore] + public string TagsText + { + get { return JsonConvert.SerializeObject(Tags, Formatting.Indented); } + } + + // Gets or sets the reference Id of the availailbity set to which this virtual machine belongs. + public SubResource AvailabilitySetReference { get; set; } + + [JsonIgnore] + public string AvailabilitySetReferenceText + { + get { return JsonConvert.SerializeObject(AvailabilitySetReference, Formatting.Indented); } + } + + // Gets or sets the diagnostics profile. + public DiagnosticsProfile DiagnosticsProfile { get; set; } + + [JsonIgnore] + public string DiagnosticsProfileText + { + get { return JsonConvert.SerializeObject(DiagnosticsProfile, Formatting.Indented); } + } + + // Gets the virtual machine child extension resources. + public IList Extensions { get; set; } + + [JsonIgnore] + public string ExtensionsText + { + get { return JsonConvert.SerializeObject(Extensions, Formatting.Indented); } + } + + // Gets or sets the hardware profile. + public HardwareProfile HardwareProfile { get; set; } + + [JsonIgnore] + public string HardwareProfileText + { + get { return JsonConvert.SerializeObject(HardwareProfile, Formatting.Indented); } + } + + // Gets the virtual machine instance view. + public VirtualMachineInstanceView InstanceView { get; set; } + + [JsonIgnore] + public string InstanceViewText + { + get { return JsonConvert.SerializeObject(InstanceView, Formatting.Indented); } + } + + // Gets or sets the network profile. + public NetworkProfile NetworkProfile { get; set; } + + [JsonIgnore] + public string NetworkProfileText + { + get { return JsonConvert.SerializeObject(NetworkProfile, Formatting.Indented); } + } + + // Gets or sets the OS profile. + public OSProfile OSProfile { get; set; } + + [JsonIgnore] + public string OSProfileText + { + get { return JsonConvert.SerializeObject(OSProfile, Formatting.Indented); } + } + + // Gets or sets the purchase plan when deploying virtual machine from VM Marketplace images. + public Plan Plan { get; set; } + + [JsonIgnore] + public string PlanText + { + get { return JsonConvert.SerializeObject(Plan, Formatting.Indented); } + } + + // Gets or sets the provisioning state, which only appears in the response. + public string ProvisioningState { get; set; } + + // Gets or sets the storage profile. + public StorageProfile StorageProfile { get; set; } + + [JsonIgnore] + public string StorageProfileText + { + get { return JsonConvert.SerializeObject(StorageProfile, Formatting.Indented); } + } + + [JsonIgnore] + public string[] DataDiskNames + { + get + { + if (this.StorageProfile == null) return null; + var listStr = new List(); + foreach (var item in StorageProfile.DataDisks) + { + listStr.Add(item.Name); + } + return listStr.ToArray(); + } + } + + [JsonIgnore] + public string[] NetworkInterfaceIDs + { + get + { + if (this.NetworkProfile == null) return null; + var listStr = new List(); + foreach (var item in NetworkProfile.NetworkInterfaces) + { + listStr.Add(item.Id); + } + return listStr.ToArray(); + } + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineExtensionImage.cs b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineExtensionImage.cs index b159c279de6b..831df31574d1 100644 --- a/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineExtensionImage.cs +++ b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineExtensionImage.cs @@ -36,8 +36,8 @@ public class PSVirtualMachineExtensionImageDetails : PSVirtualMachineExtensionIm public string ComputeRole { get; set; } - public bool SupportsMultipleExtensions { get; set; } + public bool? SupportsMultipleExtensions { get; set; } - public bool VMScaleSetEnabled { get; set; } + public bool? VMScaleSetEnabled { get; set; } } } diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineInstanceView.cs b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineInstanceView.cs new file mode 100644 index 000000000000..ab7a29c3fccd --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/Models/PSVirtualMachineInstanceView.cs @@ -0,0 +1,111 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Management.Compute.Models; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Microsoft.Azure.Commands.Compute.Models +{ + public class PSVirtualMachineInstanceView + { + public string ResourceGroupName { get; set; } + + public string Name { get; set; } + + public BootDiagnosticsInstanceView BootDiagnostics { get; set; } + + [JsonIgnore] + public string BootDiagnosticsText + { + get { return JsonConvert.SerializeObject(BootDiagnostics, Formatting.Indented); } + } + + public IList Disks { get; set; } + + [JsonIgnore] + public string DisksText + { + get { return JsonConvert.SerializeObject(Disks, Formatting.Indented); } + } + + public IList Extensions { get; set; } + + [JsonIgnore] + public string ExtensionsText + { + get { return JsonConvert.SerializeObject(Extensions, Formatting.Indented); } + } + + public int? PlatformFaultDomain { get; set; } + + public int? PlatformUpdateDomain { get; set; } + + public string RemoteDesktopThumbprint { get; set; } + + public VirtualMachineAgentInstanceView VMAgent { get; set; } + + [JsonIgnore] + public string VMAgentText + { + get { return JsonConvert.SerializeObject(VMAgent, Formatting.Indented); } + } + + public IList Statuses { get; set; } + + [JsonIgnore] + public string StatusesText + { + get { return JsonConvert.SerializeObject(Statuses, Formatting.Indented); } + } + } + + public static class PSVirtualMachineInstanceViewExtension + { + public static PSVirtualMachineInstanceView ToPSVirtualMachineInstanceView( + this VirtualMachineInstanceView virtualMachineInstanceView, + string resourceGroupName = null, + string vmName = null) + { + PSVirtualMachineInstanceView result = new PSVirtualMachineInstanceView + { + ResourceGroupName = resourceGroupName, + Name = vmName, + BootDiagnostics = virtualMachineInstanceView.BootDiagnostics, + Disks = virtualMachineInstanceView.Disks, + Extensions = virtualMachineInstanceView.Extensions, + Statuses = virtualMachineInstanceView.Statuses, + PlatformFaultDomain = virtualMachineInstanceView.PlatformFaultDomain, + PlatformUpdateDomain = virtualMachineInstanceView.PlatformUpdateDomain, + RemoteDesktopThumbprint = virtualMachineInstanceView.RdpThumbPrint, + VMAgent = virtualMachineInstanceView.VmAgent + }; + + return result; + } + + public static PSVirtualMachineInstanceView ToPSVirtualMachineInstanceView( + this VirtualMachine response, + string resourceGroupName = null, + string vmName = null) + { + if (response == null) + { + return null; + } + + return response.InstanceView == null ? null : response.InstanceView.ToPSVirtualMachineInstanceView(resourceGroupName, vmName); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/RestartAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/RestartAzureVMCommand.cs new file mode 100644 index 000000000000..58b4d4136ca9 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/RestartAzureVMCommand.cs @@ -0,0 +1,45 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsLifecycle.Restart, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class RestartAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The virtual machine name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + this.VirtualMachineClient.Restart(this.ResourceGroupName, this.Name); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SaveAzureVMImageCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SaveAzureVMImageCommand.cs new file mode 100644 index 000000000000..c566d816e6cb --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SaveAzureVMImageCommand.cs @@ -0,0 +1,98 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System.Management.Automation; +using System.IO; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsData.Save, ProfileNouns.VirtualMachineImage, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class SaveAzureVMImageCommand : VirtualMachineActionBaseCmdlet + { + [Alias("VMName")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The virtual machine name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The Destination Container Name.")] + [ValidateNotNullOrEmpty] + public string DestinationContainerName { get; set; } + + [Alias("VirtualHardDiskNamePrefix")] + [Parameter( + Mandatory = true, + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The Virtual Hard Disk Name Prefix.")] + [ValidateNotNullOrEmpty] + public string VHDNamePrefix { get; set; } + + [Parameter( + Position = 4, + ValueFromPipelineByPropertyName = true, + HelpMessage = "To Overwrite.")] + [ValidateNotNullOrEmpty] + public SwitchParameter Overwrite { get; set; } + + [Parameter( + Position = 5, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The file path in which the template of the captured image is stored")] + [ValidateNotNullOrEmpty] + public string Path { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + var parameters = new VirtualMachineCaptureParameters + { + DestinationContainerName = DestinationContainerName, + OverwriteVhds = Overwrite.IsPresent, + VhdPrefix = VHDNamePrefix + }; + + var op = this.VirtualMachineClient.Capture( + this.ResourceGroupName, + this.Name, + parameters); + + var result = Mapper.Map(op); + + if (!string.IsNullOrWhiteSpace(this.Path)) + { + File.WriteAllText(this.Path, result.Output); + } + + WriteObject(result); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SetAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SetAzureVMCommand.cs new file mode 100644 index 000000000000..a0fcd638a0e3 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/SetAzureVMCommand.cs @@ -0,0 +1,50 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Management.Compute; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Set, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + public class SetAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The virtual machine name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "To generalize virtual machine.")] + [ValidateNotNullOrEmpty] + public SwitchParameter Generalized { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + this.VirtualMachineClient.Generalize(this.ResourceGroupName, this.Name); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StartAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StartAzureVMCommand.cs new file mode 100644 index 000000000000..6569bf149244 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StartAzureVMCommand.cs @@ -0,0 +1,45 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsLifecycle.Start, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class StartAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The virtual machine name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + this.VirtualMachineClient.Start(this.ResourceGroupName, this.Name); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StopAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StopAzureVMCommand.cs new file mode 100644 index 000000000000..dff595e426c6 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/StopAzureVMCommand.cs @@ -0,0 +1,76 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsLifecycle.Stop, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class StopAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The virtual machine name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = false, + HelpMessage = "To force the stopping.")] + [ValidateNotNullOrEmpty] + public SwitchParameter Force { get; set; } + + [Parameter( + Mandatory = false, + HelpMessage = "To keep the VM provisioned.")] + [ValidateNotNullOrEmpty] + public SwitchParameter StayProvisioned { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + // TODO: Properties & Resourcess + //if (this.Force.IsPresent || this.ShouldContinue(Microsoft.Azure.Commands.Compute.Properties.Resources.VirtualMachineStoppingConfirmation, Microsoft.Azure.Commands.Compute.Properties.Resources.VirtualMachineStoppingCaption)) + if (this.Force.IsPresent || this.ShouldContinue("Microsoft.Azure.Commands.Compute.Properties.Resources.VirtualMachineStoppingConfirmation", "Microsoft.Azure.Commands.Compute.Properties.Resources.VirtualMachineStoppingCaption")) + { + Action> call = f => + { + f(this.ResourceGroupName, this.Name); + }; + + if (this.StayProvisioned) + { + call(this.VirtualMachineClient.PowerOff); + } + else + { + call(this.VirtualMachineClient.Deallocate); + } + } + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/VirtualMachineActionBaseCmdlet.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/VirtualMachineActionBaseCmdlet.cs new file mode 100644 index 000000000000..0705d199f7c5 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Action/VirtualMachineActionBaseCmdlet.cs @@ -0,0 +1,61 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Management.Automation; +using System.Text.RegularExpressions; + +namespace Microsoft.Azure.Commands.Compute +{ + public abstract class VirtualMachineActionBaseCmdlet : VirtualMachineBaseCmdlet + { + protected const string ResourceGroupNameParameterSet = "ResourceGroupNameParameterSetName"; + protected const string IdParameterSet = "IdParameterSetName"; + + [Parameter( + Mandatory = true, + Position = 0, + ParameterSetName = ResourceGroupNameParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The resource group name.")] + [ValidateNotNullOrEmpty] + public string ResourceGroupName { get; set; } + + [Parameter( + Mandatory = true, + Position = 0, + ParameterSetName = IdParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The resource group name.")] + [ValidateNotNullOrEmpty] + public string Id { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + if (this.ParameterSetName.Equals(IdParameterSet)) + { + this.ResourceGroupName = GetResourceGroupNameFromId(this.Id); + } + } + + protected string GetResourceGroupNameFromId(string idString) + { + var match = Regex.Match(idString, @"resourceGroups/([A-Za-z0-9\-]+)/"); + return (match.Success) + ? match.Groups[1].Value + : null; + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMAdditionalUnattendContentCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMAdditionalUnattendContentCommand.cs new file mode 100644 index 000000000000..324aaaf14489 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMAdditionalUnattendContentCommand.cs @@ -0,0 +1,96 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Add an Additional Unattend Content Object to VM + /// + [Cmdlet( + VerbsCommon.Add, + ProfileNouns.AdditionalUnattendContent), + OutputType( + typeof(PSVirtualMachine))] + public class NewAzureAdditionalUnattendContentCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + private const string defaultComponentName = "Microsoft-Windows-Shell-Setup"; + private const string defaultPassName = "oobeSystem"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "XML Formatted Content.")] + [ValidateNotNullOrEmpty] + public string Content { get; set; } + + [Parameter( + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Setting Name.")] + [ValidateNotNullOrEmpty] + public string SettingName { get; set; } + + protected override void ProcessRecord() + { + if (this.VM.OSProfile == null) + { + this.VM.OSProfile = new OSProfile(); + } + + if (this.VM.OSProfile.WindowsConfiguration == null && this.VM.OSProfile.LinuxConfiguration == null) + { + this.VM.OSProfile.WindowsConfiguration = new WindowsConfiguration(); + } + else if (this.VM.OSProfile.WindowsConfiguration == null && this.VM.OSProfile.LinuxConfiguration != null) + { + // TODO: Properties & Resources + throw new ArgumentException("Microsoft.Azure.Commands.Compute.Properties.Resources.BothWindowsAndLinuxConfigurationsSpecified"); + } + + if (this.VM.OSProfile.WindowsConfiguration.AdditionalUnattendContent == null) + { + this.VM.OSProfile.WindowsConfiguration.AdditionalUnattendContent = new List (); + } + + this.VM.OSProfile.WindowsConfiguration.AdditionalUnattendContent.Add( + new AdditionalUnattendContent + { + ComponentName = defaultComponentName, + Content = this.Content, + PassName = defaultPassName, + SettingName = this.SettingName, + }); + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs new file mode 100644 index 000000000000..3c55744193f1 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs @@ -0,0 +1,135 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.Add, + ProfileNouns.DataDisk), + OutputType( + typeof(PSVirtualMachine))] + public class AddAzureVMDataDiskCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskName)] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskVhdUri)] + [ValidateNotNullOrEmpty] + public string VhdUri { get; set; } + + [Parameter( + Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskCaching)] + [ValidateNotNullOrEmpty] + [ValidateSet(ValidateSetValues.ReadOnly, ValidateSetValues.ReadWrite, ValidateSetValues.None)] + public string Caching { get; set; } + + [Parameter( + Mandatory = true, + Position = 4, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskSizeInGB)] + [AllowNull] + public int? DiskSizeInGB { get; set; } + + [Parameter( + Mandatory = false, + Position = 5, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskLun)] + [ValidateNotNullOrEmpty] + public int? Lun { get; set; } + + [Parameter( + Mandatory = true, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskCreateOption)] + [ValidateNotNullOrEmpty] + [ValidateSet(DiskCreateOptionTypes.Empty, DiskCreateOptionTypes.Attach, DiskCreateOptionTypes.FromImage)] + public string CreateOption { get; set; } + + [Alias("SourceImage")] + [Parameter( + Position = 7, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMSourceImageUri)] + [ValidateNotNullOrEmpty] + public string SourceImageUri { get; set; } + + protected override void ProcessRecord() + { + var storageProfile = this.VM.StorageProfile; + + if (storageProfile == null) + { + storageProfile = new StorageProfile(); + } + + if (storageProfile.DataDisks == null) + { + storageProfile.DataDisks = new List(); + } + + storageProfile.DataDisks.Add(new DataDisk + { + Name = this.Name, + Caching = this.Caching, + DiskSizeGB = this.DiskSizeInGB, + Lun = this.Lun.GetValueOrDefault(), + Vhd = new VirtualHardDisk + { + Uri = this.VhdUri + }, + CreateOption = this.CreateOption, + Image = string.IsNullOrEmpty(this.SourceImageUri) ? null : new VirtualHardDisk + { + Uri = this.SourceImageUri + } + }); + + this.VM.StorageProfile = storageProfile; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMNetworkInterfaceCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMNetworkInterfaceCommand.cs new file mode 100644 index 000000000000..2e1935b99abb --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMNetworkInterfaceCommand.cs @@ -0,0 +1,171 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Setup the network interface. + /// + [Cmdlet( + VerbsCommon.Add, + ProfileNouns.NetworkInterface, + DefaultParameterSetName = NicIdParamSetName), + OutputType( + typeof(PSVirtualMachine))] + public class AddAzureVMNetworkInterfaceCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + protected const string NicIdParamSetName = "GetNicFromNicId"; + protected const string NicObjectParamSetName = "GetNicFromNicObject"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = NicIdParamSetName, + HelpMessage = HelpMessages.VMProfile)] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + ParameterSetName = NicObjectParamSetName, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Alias("NicId", "NetworkInterfaceId")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMNetworkInterfaceID, + ParameterSetName = NicIdParamSetName)] + [ValidateNotNullOrEmpty] + public string Id { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipeline = true, + ParameterSetName = NicObjectParamSetName)] + [ValidateNotNullOrEmpty] + public List NetworkInterface { get; set; } + + [Parameter( + Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + ParameterSetName = NicIdParamSetName)] + [ValidateNotNullOrEmpty] + public SwitchParameter Primary { get; set; } + + protected override void ProcessRecord() + { + var networkProfile = this.VM.NetworkProfile; + + if (networkProfile == null) + { + networkProfile = new NetworkProfile + { + NetworkInterfaces = new List() + }; + } + + if (networkProfile.NetworkInterfaces == null) + { + networkProfile.NetworkInterfaces = new List(); + } + + if (this.ParameterSetName.Equals(NicIdParamSetName)) + { + if (!this.Primary.IsPresent) + { + if (! networkProfile.NetworkInterfaces.Any(e => e.Id.Equals(this.Id))) + { + networkProfile.NetworkInterfaces.Add(new NetworkInterfaceReference + { + Id = this.Id, + }); + } + + if (networkProfile.NetworkInterfaces.Count > 1) + { + // run through the entire list of networkInterfaces and if Primary is not set, set them to false + foreach (var nic in networkProfile.NetworkInterfaces) + { + nic.Primary = nic.Primary ?? false; + } + } + } + else + { + foreach (var networkInterfaceReference in networkProfile.NetworkInterfaces) + { + networkInterfaceReference.Primary = false; + } + + var existingNic = networkProfile.NetworkInterfaces.Where(e => e.Id.Equals(this.Id)).FirstOrDefault(); + if (existingNic == null) + { + networkProfile.NetworkInterfaces.Add( + new NetworkInterfaceReference + { + Id = this.Id, + Primary = true + }); + } + else + { + existingNic.Primary = true; + } + } + } + else + { + // Nic Object Parameter Set + foreach (var nic in this.NetworkInterface) + { + var existingNic = networkProfile.NetworkInterfaces.Where(e => e.Id.Equals(nic.Id)).FirstOrDefault(); + + if (existingNic == null) + { + networkProfile.NetworkInterfaces.Add( + new NetworkInterfaceReference + { + Id = nic.Id, + Primary = nic.Primary + }); + } + else + { + existingNic.Primary = nic.Primary; + } + } + } + + this.VM.NetworkProfile = networkProfile; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSecretCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSecretCommand.cs new file mode 100644 index 000000000000..02a155ff1ce4 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSecretCommand.cs @@ -0,0 +1,128 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Add a Vault Secret Group object to VM + /// + [Cmdlet( + VerbsCommon.Add, + ProfileNouns.VaultSecretGroup), + OutputType( + typeof(PSVirtualMachine))] + public class NewAzureVaultSecretGroupCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Alias("Id")] + [Parameter( + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The ID for Source Vault")] + [ValidateNotNullOrEmpty] + public string SourceVaultId { get; set; } + + [Parameter( + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Certificate store in LocalMachine")] + [ValidateNotNullOrEmpty] + public string CertificateStore { get; set; } + + [Parameter( + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = "URL referencing a secret in a Key Vault.")] + [ValidateNotNullOrEmpty] + public string CertificateUrl { get; set; } + + protected override void ProcessRecord() + { + if (this.VM.OSProfile == null) + { + this.VM.OSProfile = new OSProfile(); + } + + if (this.VM.OSProfile.Secrets == null) + { + this.VM.OSProfile.Secrets = new List(); + } + + int i = 0; + + for(; i <= this.VM.OSProfile.Secrets.Count; i++) + { + if (i == this.VM.OSProfile.Secrets.Count) + { + var sourceVault = new SubResource { + Id = this.SourceVaultId + }; + + var vaultCertificates = new List{ + new VaultCertificate() + { + CertificateStore = this.CertificateStore, + CertificateUrl = this.CertificateUrl, + } + }; + + this.VM.OSProfile.Secrets.Add( + new VaultSecretGroup() + { + SourceVault = sourceVault, + VaultCertificates = vaultCertificates, + }); + + break; + } + + if (this.VM.OSProfile.Secrets[i].SourceVault != null && this.VM.OSProfile.Secrets[i].SourceVault.Id.Equals(this.SourceVaultId)) + { + if (this.VM.OSProfile.Secrets[i].VaultCertificates == null) + { + this.VM.OSProfile.Secrets[i].VaultCertificates = new List(); + } + + this.VM.OSProfile.Secrets[i].VaultCertificates.Add( + new VaultCertificate() + { + CertificateStore = this.CertificateStore, + CertificateUrl = this.CertificateUrl, + }); + + break; + } + } + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSshPublicKeyCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSshPublicKeyCommand.cs new file mode 100644 index 000000000000..c03ca8bc4bce --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/AddAzureVMSshPublicKeyCommand.cs @@ -0,0 +1,96 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Common.Properties; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Add an Ssh Public Key object to VM + /// + [Cmdlet( + VerbsCommon.Add, + ProfileNouns.SshPublicKey), + OutputType( + typeof(PSVirtualMachine))] + public class NewAzureSshPublicKeyCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Certificate Public Key")] + [ValidateNotNullOrEmpty] + public string KeyData { get; set; } + + [Parameter( + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Full Path on VM where SSH Public Key is Stored.")] + [ValidateNotNullOrEmpty] + public string Path { get; set; } + + protected override void ProcessRecord() + { + + if (this.VM.OSProfile == null) + { + this.VM.OSProfile = new OSProfile(); + } + + if (this.VM.OSProfile.WindowsConfiguration == null && this.VM.OSProfile.LinuxConfiguration == null) + { + this.VM.OSProfile.LinuxConfiguration = new LinuxConfiguration(); + } + else if (this.VM.OSProfile.WindowsConfiguration != null && this.VM.OSProfile.LinuxConfiguration == null) + { + throw new ArgumentException(Resources.ResourceManager.GetString("BothWindowsAndLinuxConfigurationsSpecified")); + } + + if (this.VM.OSProfile.LinuxConfiguration.Ssh == null) + { + this.VM.OSProfile.LinuxConfiguration.Ssh = new SshConfiguration(); + } + + if (this.VM.OSProfile.LinuxConfiguration.Ssh.PublicKeys == null) + { + this.VM.OSProfile.LinuxConfiguration.Ssh.PublicKeys = new List(); + } + + this.VM.OSProfile.LinuxConfiguration.Ssh.PublicKeys.Add( + new SshPublicKey + { + KeyData = this.KeyData, + Path = this.Path, + }); + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/NewAzureVMConfigCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/NewAzureVMConfigCommand.cs new file mode 100644 index 000000000000..95084eb45d2c --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/NewAzureVMConfigCommand.cs @@ -0,0 +1,79 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Management.Automation; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using Microsoft.Azure.Management.Compute.Models; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.New, + ProfileNouns.VirtualMachineConfig), + OutputType( + typeof(PSVirtualMachine))] + public class NewAzureVMConfigCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("ResourceName", "Name")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The VM name.")] + [ValidateNotNullOrEmpty] + public string VMName { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMSize)] + [ValidateNotNullOrEmpty] + public string VMSize { get; set; } + + [Parameter( + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The Availability Set Id.")] + [ValidateNotNullOrEmpty] + public string AvailabilitySetId { get; set; } + + protected override bool IsUsageMetricEnabled + { + get { return true; } + } + + protected override void ProcessRecord() + { + var vm = new PSVirtualMachine + { + Name = this.VMName, + AvailabilitySetReference = string.IsNullOrEmpty(this.AvailabilitySetId) ? null : new SubResource + { + Id = this.AvailabilitySetId + } + }; + + if (!string.IsNullOrEmpty(this.VMSize)) + { + vm.HardwareProfile = new HardwareProfile(); + vm.HardwareProfile.VmSize = this.VMSize; + } + + WriteObject(vm); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMDataDiskCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMDataDiskCommand.cs new file mode 100644 index 000000000000..e20be44a38f8 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMDataDiskCommand.cs @@ -0,0 +1,70 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.Remove, + ProfileNouns.DataDisk), + OutputType( + typeof(PSVirtualMachine))] + public class RemoveAzureVMDataDiskCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Alias("Name")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskName)] + [ValidateNotNullOrEmpty] + public string[] DataDiskNames { get; set; } + + protected override void ProcessRecord() + { + var storageProfile = this.VM.StorageProfile; + + if (storageProfile != null && storageProfile.DataDisks != null) + { + var disks = storageProfile.DataDisks.ToList(); + var comp = StringComparison.OrdinalIgnoreCase; + foreach (var diskName in DataDiskNames) + { + disks.RemoveAll(d => string.Equals(d.Name, diskName, comp)); + } + storageProfile.DataDisks = disks; + } + + this.VM.StorageProfile = storageProfile; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMNetworkInterfaceCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMNetworkInterfaceCommand.cs new file mode 100644 index 000000000000..8393263449cd --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/RemoveAzureVMNetworkInterfaceCommand.cs @@ -0,0 +1,79 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Linq; +using System.Management.Automation; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Setup the network interface. + /// + [Cmdlet( + VerbsCommon.Remove, + ProfileNouns.NetworkInterface), + OutputType( + typeof(PSVirtualMachine))] + public class RemoveAzureVMNetworkInterfaceCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Alias("Id", "NicIds")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMNetworkInterfaceID)] + [ValidateNotNullOrEmpty] + public string[] NetworkInterfaceIDs { get; set; } + + protected override void ProcessRecord() + { + var networkProfile = this.VM.NetworkProfile; + + foreach (var id in this.NetworkInterfaceIDs) + { + if (networkProfile != null && + networkProfile.NetworkInterfaces != null && + networkProfile.NetworkInterfaces.Any(nic => + string.Equals(nic.Id, id, StringComparison.OrdinalIgnoreCase))) + { + var nicReference = networkProfile.NetworkInterfaces.First(nic => string.Equals(nic.Id, id, StringComparison.OrdinalIgnoreCase)); + networkProfile.NetworkInterfaces.Remove(nicReference); + } + } + + if (!networkProfile.NetworkInterfaces.Any()) + { + networkProfile = null; + } + + this.VM.NetworkProfile = networkProfile; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMBootDiagnosticsCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMBootDiagnosticsCommand.cs new file mode 100644 index 000000000000..9f22122562de --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMBootDiagnosticsCommand.cs @@ -0,0 +1,141 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Common.Authentication; +using Microsoft.Azure.Commands.Common.Authentication.Models; +using Microsoft.Azure.Commands.Common.Properties; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.Azure.Management.Storage; +using Microsoft.Azure.Management.Storage.Models; +using System; +using System.Globalization; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.Set, + ProfileNouns.BootDiagnostics), + OutputType( + typeof(PSVirtualMachine))] + public class SetAzureVMBootDiagnosticsCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + private const string EnableParameterSet = "EnableBootDiagnostics"; + private const string DisableParameterSet = "DisableBootDiagnostics"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = EnableParameterSet, + HelpMessage = HelpMessages.VMBootDiagnosticsEnable)] + public SwitchParameter Enable { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = DisableParameterSet, + HelpMessage = HelpMessages.VMBootDiagnosticsDisable)] + public SwitchParameter Disable { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ParameterSetName = EnableParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMBootDiagnosticsResourceGroupName)] + [ValidateNotNullOrEmpty] + public string ResourceGroupName { get; set; } + + [Parameter( + Mandatory = false, + Position = 3, + ParameterSetName = EnableParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMBootDiagnosticsStorageAccountName)] + [ValidateNotNullOrEmpty] + public string StorageAccountName { get; set; } + + protected override void ProcessRecord() + { + var diagnosticsProfile = this.VM.DiagnosticsProfile; + + diagnosticsProfile = diagnosticsProfile ?? new DiagnosticsProfile(); + + diagnosticsProfile.BootDiagnostics = diagnosticsProfile.BootDiagnostics ?? new BootDiagnostics(); + + diagnosticsProfile.BootDiagnostics.Enabled = this.Enable.IsPresent; + + if (this.Enable.IsPresent) + { + if (string.IsNullOrEmpty(this.StorageAccountName)) + { + if (diagnosticsProfile.BootDiagnostics.StorageUri == null) + { + ThrowNoStorageAccount(); + } + } + else + { + var storageClient = ClientFactory.CreateClient( + DefaultProfile.Context, AzureEnvironment.Endpoint.ResourceManager); + var storageAccount = storageClient.StorageAccounts.GetProperties(this.ResourceGroupName, this.StorageAccountName); + + if (storageAccount.AccountType.Equals(AccountType.PremiumLRS)) + { + ThrowPremiumStorageError(this.StorageAccountName); + } + + diagnosticsProfile.BootDiagnostics.StorageUri = storageAccount.PrimaryEndpoints.Blob; + } + } + + this.VM.DiagnosticsProfile = diagnosticsProfile; + + WriteObject(this.VM); + } + + private void ThrowPremiumStorageError(string storageAccountName) + { + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + Resources.ResourceManager.GetString("PremiumStorageAccountForBootDiagnostics"), storageAccountName)), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + + private void ThrowNoStorageAccount() + { + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(Resources.ResourceManager.GetString("BootDiagnosticsNoStorageAccountError")), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMDataDiskCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMDataDiskCommand.cs new file mode 100644 index 000000000000..2a1ad1fe0a06 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMDataDiskCommand.cs @@ -0,0 +1,132 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Commands.Compute.Properties; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.Set, + ProfileNouns.DataDisk), + OutputType( + typeof(PSVirtualMachine))] + public class SetAzureVMDataDiskCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + private const string NameParameterSet = "ChangeWithName"; + private const string LunParameterSet = "ChangeWithLun"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = NameParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskName)] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = LunParameterSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskLun)] + [ValidateNotNullOrEmpty] + public int? Lun { get; set; } + + [Parameter( + Mandatory = false, + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskCaching)] + [ValidateNotNullOrEmpty] + [ValidateSet(ValidateSetValues.ReadOnly, ValidateSetValues.ReadWrite, ValidateSetValues.None)] + public string Caching { get; set; } + + [Parameter( + Mandatory = false, + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskSizeInGB)] + [AllowNull] + public int? DiskSizeInGB { get; set; } + + protected override void ProcessRecord() + { + var storageProfile = this.VM.StorageProfile; + + if (storageProfile == null || storageProfile.DataDisks == null) + { + ThrowDataDiskNotExistError(); + } + + var dataDisk = (this.ParameterSetName.Equals(LunParameterSet)) + ? storageProfile.DataDisks.SingleOrDefault(disk => disk.Lun == this.Lun) + : storageProfile.DataDisks.SingleOrDefault(disk => disk.Name == this.Name); + + if (dataDisk == null) + { + ThrowDataDiskNotExistError(); + } + else + { + if (! string.IsNullOrWhiteSpace(this.Caching)) + { + dataDisk.Caching = this.Caching; + } + if (this.DiskSizeInGB != null) + { + dataDisk.DiskSizeGB = this.DiskSizeInGB; + } + } + + this.VM.StorageProfile = storageProfile; + + WriteObject(this.VM); + } + + private void ThrowDataDiskNotExistError() + { + var missingDisk = (this.ParameterSetName.Equals(LunParameterSet)) + ? string.Format("LUN # {0}", this.Lun) + : "Name: " + this.Name; + + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + Resources.ResourceManager.GetString("DataDiskNotAssignedForVM"), missingDisk)), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOSDiskCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOSDiskCommand.cs new file mode 100644 index 000000000000..446a6afcee5e --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOSDiskCommand.cs @@ -0,0 +1,229 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Management.Automation; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using Microsoft.Azure.Management.Compute.Models; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet( + VerbsCommon.Set, + ProfileNouns.OSDisk, + DefaultParameterSetName = DefaultParamSet), + OutputType( + typeof(PSVirtualMachine))] + public class SetAzureVMOSDiskCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + protected const string DefaultParamSet = "DefaultParamSet"; + protected const string WindowsParamSet = "WindowsParamSet"; + protected const string LinuxParamSet = "LinuxParamSet"; + protected const string WindowsAndDiskEncryptionParameterSet = "WindowsDiskEncryptionParameterSet"; + protected const string LinuxAndDiskEncryptionParameterSet = "LinuxDiskEncryptionParameterSet"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Alias("OSDiskName", "DiskName")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskName)] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Alias("OSDiskVhdUri", "DiskVhdUri")] + [Parameter( + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskVhdUri)] + [ValidateNotNullOrEmpty] + public string VhdUri { get; set; } + + [Parameter( + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskCaching)] + [ValidateNotNullOrEmpty] + [ValidateSet(ValidateSetValues.ReadOnly, ValidateSetValues.ReadWrite, ValidateSetValues.None)] + public string Caching { get; set; } + + [Alias("SourceImage")] + [Parameter( + Position = 4, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMSourceImageUri)] + [ValidateNotNullOrEmpty] + public string SourceImageUri { get; set; } + + [Parameter( + Mandatory = true, + Position = 5, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMDataDiskCreateOption)] + [ValidateNotNullOrEmpty] + [ValidateSet(DiskCreateOptionTypes.Empty, DiskCreateOptionTypes.Attach, DiskCreateOptionTypes.FromImage)] + public string CreateOption { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskWindowsOSType)] + [Parameter( + ParameterSetName = WindowsAndDiskEncryptionParameterSet, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskWindowsOSType)] + public SwitchParameter Windows { get; set; } + + [Parameter( + ParameterSetName = LinuxParamSet, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskLinuxOSType)] + [Parameter( + ParameterSetName = LinuxAndDiskEncryptionParameterSet, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskLinuxOSType)] + public SwitchParameter Linux { get; set; } + + [Parameter( + ParameterSetName = WindowsAndDiskEncryptionParameterSet, + Mandatory = true, + Position = 7, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskDiskEncryptionKeyUrl)] + [Parameter( + ParameterSetName = LinuxAndDiskEncryptionParameterSet, + Mandatory = true, + Position = 7, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskDiskEncryptionKeyUrl)] + public string DiskEncryptionKeyUrl { get; set; } + + [Parameter( + ParameterSetName = WindowsAndDiskEncryptionParameterSet, + Mandatory = true, + Position = 8, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskDiskEncryptionKeyVaultId)] + [Parameter( + ParameterSetName = LinuxAndDiskEncryptionParameterSet, + Mandatory = true, + Position = 8, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskDiskEncryptionKeyVaultId)] + public string DiskEncryptionKeyVaultId { get; set; } + + [Parameter( + ParameterSetName = WindowsAndDiskEncryptionParameterSet, + Mandatory = false, + Position = 9, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskKeyEncryptionKeyUrl)] + [Parameter( + ParameterSetName = LinuxAndDiskEncryptionParameterSet, + Mandatory = false, + Position = 9, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskKeyEncryptionKeyUrl)] + public string KeyEncryptionKeyUrl { get; set; } + + [Parameter( + ParameterSetName = WindowsAndDiskEncryptionParameterSet, + Mandatory = false, + Position = 10, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskKeyEncryptionKeyVaultId)] + [Parameter( + ParameterSetName = LinuxAndDiskEncryptionParameterSet, + Mandatory = false, + Position = 10, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMOSDiskKeyEncryptionKeyVaultId)] + public string KeyEncryptionKeyVaultId { get; set; } + + protected override void ProcessRecord() + { + if (this.VM.StorageProfile == null) + { + this.VM.StorageProfile = new StorageProfile(); + } + + if ((string.IsNullOrEmpty(this.KeyEncryptionKeyVaultId) && !string.IsNullOrEmpty(this.KeyEncryptionKeyUrl)) + || (!string.IsNullOrEmpty(this.KeyEncryptionKeyVaultId) && string.IsNullOrEmpty(this.KeyEncryptionKeyUrl))) + { + WriteError(new ErrorRecord( + new Exception(Properties.Resources.ResourceManager.GetString("VMOSDiskDiskEncryptionBothKekVaultIdAndKekUrlRequired")), + string.Empty, ErrorCategory.InvalidArgument, null)); + } + + this.VM.StorageProfile.OsDisk = new OSDisk + { + Caching = this.Caching, + Name = this.Name, + OsType = this.Windows.IsPresent ? OperatingSystemTypes.Windows : this.Linux.IsPresent ? OperatingSystemTypes.Linux : null, + Vhd = string.IsNullOrEmpty(this.VhdUri) ? null : new VirtualHardDisk + { + Uri = this.VhdUri + }, + Image = string.IsNullOrEmpty(this.SourceImageUri) ? null : new VirtualHardDisk + { + Uri = this.SourceImageUri + }, + CreateOption = this.CreateOption, + EncryptionSettings = + (this.ParameterSetName.Equals(WindowsAndDiskEncryptionParameterSet) || this.ParameterSetName.Equals(LinuxAndDiskEncryptionParameterSet)) + ? new DiskEncryptionSettings + { + DiskEncryptionKey = new KeyVaultSecretReference + { + SourceVault = new SubResource + { + Id = this.DiskEncryptionKeyVaultId + }, + SecretUrl = this.DiskEncryptionKeyUrl + }, + KeyEncryptionKey = (this.KeyEncryptionKeyVaultId == null || this.KeyEncryptionKeyUrl == null) + ? null + : new KeyVaultKeyReference + { + KeyUrl = this.KeyEncryptionKeyUrl, + SourceVault = new SubResource + { + Id = this.KeyEncryptionKeyVaultId + }, + } + } + : null + }; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOperatingSystemCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOperatingSystemCommand.cs new file mode 100644 index 000000000000..ca21f8ec964e --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMOperatingSystemCommand.cs @@ -0,0 +1,237 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Commands.Compute.Properties; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.WindowsAzure.Commands.Common; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using System; +using System.Collections.Generic; +using System.Management.Automation; +using System.Text; + +namespace Microsoft.Azure.Commands.Compute +{ + /// + /// Setup the virtual machine's OS profile. + /// + [Cmdlet( + VerbsCommon.Set, + ProfileNouns.OperatingSystem, + DefaultParameterSetName = WindowsParamSet), + OutputType( + typeof(PSVirtualMachine))] + public class SetAzureVMOperatingSystemCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + protected const string WindowsParamSet = "Windows"; + protected const string LinuxParamSet = "Linux"; + + [Alias("VMProfile")] + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMProfile)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Windows")] + [ValidateNotNullOrEmpty] + public SwitchParameter Windows { get; set; } + + [Parameter( + ParameterSetName = LinuxParamSet, + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Linux")] + [ValidateNotNullOrEmpty] + public SwitchParameter Linux { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMComputerName)] + [ValidateNotNullOrEmpty] + public string ComputerName { get; set; } + + [Parameter( + Mandatory = true, + Position = 3, + ValueFromPipelineByPropertyName = true, + HelpMessage = HelpMessages.VMCredential)] + [ValidateNotNullOrEmpty] + public PSCredential Credential { get; set; } + + [Parameter( + Position = 4, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Custom data")] + [ValidateNotNullOrEmpty] + public string CustomData { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 5, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The Provision VM Agent.")] + [ValidateNotNullOrEmpty] + public SwitchParameter ProvisionVMAgent { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 6, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Enable Automatic Update")] + [ValidateNotNullOrEmpty] + public SwitchParameter EnableAutoUpdate { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 7, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Time Zone")] + [ValidateNotNullOrEmpty] + public string TimeZone { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 8, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Enable WinRM Http protocol")] + [ValidateNotNullOrEmpty] + public SwitchParameter WinRMHttp { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 9, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Enable WinRM Https protocol")] + [ValidateNotNullOrEmpty] + public SwitchParameter WinRMHttps { get; set; } + + [Parameter( + ParameterSetName = WindowsParamSet, + Position = 10, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Url for WinRM certificate")] + [ValidateNotNullOrEmpty] + public Uri WinRMCertificateUrl { get; set; } + + // Linux Parameter Sets + [Parameter( + ParameterSetName = LinuxParamSet, + Position = 5, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Enable WinRM Https protocol")] + [ValidateNotNullOrEmpty] + public SwitchParameter DisablePasswordAuthentication { get; set; } + + protected override void ProcessRecord() + { + this.VM.OSProfile = new OSProfile + { + ComputerName = this.ComputerName, + AdminUsername = this.Credential.UserName, + // TODO: SecureString + //AdminPassword = SecureStringExtensions.ConvertToString(this.Credential.Password), + AdminPassword = this.Credential.Password, + CustomData = string.IsNullOrWhiteSpace(this.CustomData) ? null : Convert.ToBase64String(Encoding.UTF8.GetBytes(this.CustomData)), + }; + + if (this.ParameterSetName == LinuxParamSet) + { + if (this.VM.OSProfile.WindowsConfiguration != null) + { + throw new ArgumentException(Resources.ResourceManager.GetString("BothWindowsAndLinuxConfigurationsSpecified")); + } + + if (this.VM.OSProfile.LinuxConfiguration == null) + { + this.VM.OSProfile.LinuxConfiguration = new LinuxConfiguration(); + } + + this.VM.OSProfile.LinuxConfiguration.DisablePasswordAuthentication = + (this.DisablePasswordAuthentication.IsPresent) + ? (bool?)true + : null; + } + else + { + if (this.VM.OSProfile.LinuxConfiguration != null) + { + throw new ArgumentException(Resources.ResourceManager.GetString("BothWindowsAndLinuxConfigurationsSpecified")); + } + + if (this.VM.OSProfile.WindowsConfiguration == null) + { + this.VM.OSProfile.WindowsConfiguration = new WindowsConfiguration(); + this.VM.OSProfile.WindowsConfiguration.AdditionalUnattendContent = null; + } + + var listenerList = new List(); + + if (this.WinRMHttp.IsPresent) + { + listenerList.Add(new WinRMListener + { + Protocol = ProtocolTypes.Http, + CertificateUrl = null, + }); + } + + if (this.WinRMHttps.IsPresent) + { + listenerList.Add(new WinRMListener + { + Protocol = ProtocolTypes.Https, + CertificateUrl = this.WinRMCertificateUrl.ToString(), + }); + } + + // OS Profile + this.VM.OSProfile.WindowsConfiguration.ProvisionVMAgent = + (this.ProvisionVMAgent.IsPresent) + ? (bool?) true + : null; + + this.VM.OSProfile.WindowsConfiguration.EnableAutomaticUpdates = + this.EnableAutoUpdate.IsPresent + ? (bool?) true + : null; + + this.VM.OSProfile.WindowsConfiguration.TimeZone = this.TimeZone; + + this.VM.OSProfile.WindowsConfiguration.WinRM = + ! (this.WinRMHttp.IsPresent || this.WinRMHttps.IsPresent) + ? null + : new WinRMConfiguration + { + Listeners = listenerList, + }; + } + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMSourceImage.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMSourceImage.cs new file mode 100644 index 000000000000..48fc642d9a73 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Config/SetAzureVMSourceImage.cs @@ -0,0 +1,70 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Management.Automation; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.WindowsAzure.Commands.Utilities.Common; +using Microsoft.Azure.Management.Compute.Models; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Set, ProfileNouns.SourceImage, DefaultParameterSetName = ImageReferenceParameterSet), + OutputType(typeof(PSVirtualMachine))] + public class SetAzureVMSourceImageCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet + { + protected const string ImageReferenceParameterSet = "ImageReferenceParameterSet"; + + [Alias("VMProfile")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter(ParameterSetName = ImageReferenceParameterSet, Mandatory = true, Position = 1, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string PublisherName { get; set; } + + [Parameter(ParameterSetName = ImageReferenceParameterSet, Mandatory = true, Position = 2, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Offer { get; set; } + + [Parameter(ParameterSetName = ImageReferenceParameterSet, Mandatory = true, Position = 3, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Skus { get; set; } + + [Parameter(ParameterSetName = ImageReferenceParameterSet, Mandatory = true, Position = 4, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Version { get; set; } + + protected override void ProcessRecord() + { + if (this.VM.StorageProfile == null) + { + this.VM.StorageProfile = new StorageProfile(); + } + + this.VM.StorageProfile.ImageReference = new ImageReference + { + Publisher = PublisherName, + Offer = Offer, + Sku = Skus, + Version = Version + }; + + WriteObject(this.VM); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMBootDiagnosticsDataCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMBootDiagnosticsDataCommand.cs new file mode 100644 index 000000000000..6c674f6b365e --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMBootDiagnosticsDataCommand.cs @@ -0,0 +1,183 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.Common.Authentication.Models; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Storage; +using Microsoft.WindowsAzure.Storage.Auth; +using Microsoft.WindowsAzure.Storage.Blob; +using System; +using System.Globalization; +using System.IO; +using System.Management.Automation; +using System.Text; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Get, ProfileNouns.BootDiagnosticsData, DefaultParameterSetName = WindowsParamSet)] + [OutputType(typeof(PSVirtualMachine), typeof(PSVirtualMachineInstanceView))] + public class GetAzureVMBootDiagnosticsDataCommand : VirtualMachineBaseCmdlet + { + private const string WindowsParamSet = "WindowsParamSet"; + private const string LinuxParamSet = "LinuxParamSet"; + + [Parameter( + Mandatory = true, + Position = 0, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string ResourceGroupName { get; set; } + + [Alias("ResourceName", "VMName")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ParameterSetName = WindowsParamSet)] + public SwitchParameter Windows { get; set; } + + [Parameter( + Mandatory = true, + Position = 2, + ParameterSetName = LinuxParamSet)] + public SwitchParameter Linux { get; set; } + + [Parameter( + Mandatory = true, + Position = 3, + ParameterSetName = WindowsParamSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Path and name of the output RDP file.")] + [Parameter( + Mandatory = false, + Position = 3, + ParameterSetName = LinuxParamSet, + ValueFromPipelineByPropertyName = true, + HelpMessage = "Path and name of the output RDP file.")] + [ValidateNotNullOrEmpty] + public string LocalPath { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + var result = this.VirtualMachineClient.Get(this.ResourceGroupName, this.Name, "instanceView"); + if (result == null) + { + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + "no virtual machine")), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + + if (result.DiagnosticsProfile == null + || result.DiagnosticsProfile.BootDiagnostics == null + || result.DiagnosticsProfile.BootDiagnostics.Enabled == null + || !result.DiagnosticsProfile.BootDiagnostics.Enabled.Value + || result.DiagnosticsProfile.BootDiagnostics.StorageUri == null) + { + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + "no diagnostic profile enabled")), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + + if (result.InstanceView == null + || result.InstanceView.BootDiagnostics == null) + { + ThrowTerminatingError + (new ErrorRecord( + new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + "no boot diagnostic")), + string.Empty, + ErrorCategory.InvalidData, + null)); + } + + if (this.Windows.IsPresent + || (this.Linux.IsPresent && !string.IsNullOrEmpty(this.LocalPath))) + { + var screenshotUri = new Uri(result.InstanceView.BootDiagnostics.ConsoleScreenshotBlobUri); + var localFile = this.LocalPath + screenshotUri.Segments[2]; + DownloadFromBlobUri(screenshotUri, localFile); + } + + + if (this.Linux.IsPresent) + { + var logUri = new Uri(result.InstanceView.BootDiagnostics.SerialConsoleLogBlobUri); + + var localFile = (this.LocalPath ?? Path.GetTempPath()) + logUri.Segments[2]; + + DownloadFromBlobUri(logUri, localFile); + + var sb = new StringBuilder(); + using (var reader = new StreamReader(System.IO.File.OpenRead(localFile))) + { + string line; + while ((line = reader.ReadLine()) != null) + { + sb.AppendLine(line); + } + }; + + WriteObject(sb.ToString()); + } + }); + } + + private void DownloadFromBlobUri(Uri sourceUri, string localFileInfo) + { + // TODO : BlobUri + //BlobUri blobUri; + //string storagekey=""; + //if (!BlobUri.TryParseUri(sourceUri, out blobUri)) + //{ + // throw new ArgumentOutOfRangeException("Source", sourceUri.ToString()); + //} + // + //var storageClient = ClientFactory.CreateClient( + // DefaultProfile.Context, AzureEnvironment.Endpoint.ResourceManager); + // + // + //var storageService = storageClient.StorageAccounts.GetProperties(this.ResourceGroupName, blobUri.StorageAccountName); + //if (storageService != null) + //{ + // var storageKeys = storageClient.StorageAccounts.ListKeys(this.ResourceGroupName, storageService.Name); + // storagekey = storageKeys.Key1; + //} + + //StorageCredentials storagecred = new StorageCredentials(blobUri.StorageAccountName, storagekey); + //var blob = new CloudBlob(sourceUri, storagecred); + // + //blob.DownloadToFile(localFileInfo, FileMode.Create); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMCommand.cs new file mode 100644 index 000000000000..36b4c5bd173e --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/GetAzureVMCommand.cs @@ -0,0 +1,136 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.Rest.Azure; +using System; +using System.Collections.Generic; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Get, ProfileNouns.VirtualMachine, DefaultParameterSetName = ListAllVirtualMachinesParamSet)] + [OutputType(typeof(PSVirtualMachine), typeof(PSVirtualMachineInstanceView))] + public class GetAzureVMCommand : VirtualMachineBaseCmdlet + { + protected const string GetVirtualMachineInResourceGroupParamSet = "GetVirtualMachineInResourceGroupParamSet"; + protected const string ListVirtualMachineInResourceGroupParamSet = "ListVirtualMachineInResourceGroupParamSet"; + protected const string ListAllVirtualMachinesParamSet = "ListAllVirtualMachinesParamSet"; + protected const string ListNextLinkVirtualMachinesParamSet = "ListNextLinkVirtualMachinesParamSet"; + + [Parameter( + Mandatory = true, + Position = 0, + ParameterSetName = ListVirtualMachineInResourceGroupParamSet, + ValueFromPipelineByPropertyName = true)] + [Parameter( + Mandatory = true, + Position = 0, + ParameterSetName = GetVirtualMachineInResourceGroupParamSet, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string ResourceGroupName { get; set; } + + [Alias("ResourceName", "VMName")] + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = GetVirtualMachineInResourceGroupParamSet, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Position = 2, + ParameterSetName = GetVirtualMachineInResourceGroupParamSet)] + [ValidateNotNullOrEmpty] + public SwitchParameter Status { get; set; } + + [Parameter( + Mandatory = true, + Position = 1, + ParameterSetName = ListNextLinkVirtualMachinesParamSet, + ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public Uri NextLink { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + if (!string.IsNullOrEmpty(this.Name)) + { + if (Status) + { + var result = this.VirtualMachineClient.Get(this.ResourceGroupName, this.Name, "instanceView"); + WriteObject(result.ToPSVirtualMachineInstanceView(this.ResourceGroupName, this.Name)); + } + else + { + var result = this.VirtualMachineClient.Get(this.ResourceGroupName, this.Name); + var psResult = Mapper.Map(result); + WriteObject(psResult); + } + } + else + { + IPage vmListResult = null; + if (!string.IsNullOrEmpty(this.ResourceGroupName)) + { + vmListResult = this.VirtualMachineClient.List(this.ResourceGroupName); + } + else if (this.NextLink != null) + { + vmListResult = this.VirtualMachineClient.ListNext(this.NextLink.ToString()); + } + else + { + vmListResult = this.VirtualMachineClient.ListAll(); + } + + var psResultList = new List(); + + while (vmListResult != null) + { + if (vmListResult != null) + { + foreach (var item in vmListResult) + { + var psItem = Mapper.Map(item); + psResultList.Add(psItem); + } + } + + if (!string.IsNullOrEmpty(vmListResult.NextPageLink)) + { + vmListResult = this.VirtualMachineClient.ListNext(vmListResult.NextPageLink); + } + else + { + vmListResult = null; + } + } + + WriteObject(psResultList, true); + } + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs new file mode 100644 index 000000000000..10a813b329ca --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs @@ -0,0 +1,244 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Common.Authentication.Models; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Commands.Compute.Properties; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using Microsoft.Azure.Management.Storage; +using Microsoft.Azure.Management.Storage.Models; +using System; +using System.Collections; +using System.Linq; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.New, ProfileNouns.VirtualMachine)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class NewAzureVMCommand : VirtualMachineBaseCmdlet + { + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string ResourceGroupName { get; set; } + + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public string Location { get; set; } + + [Alias("VMProfile")] + [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public Hashtable[] Tags { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + if (this.VM.DiagnosticsProfile == null) + { + var storageUri = GetOrCreateStorageAccountForBootDiagnostics(); + + if (storageUri != null) + { + this.VM.DiagnosticsProfile = new DiagnosticsProfile + { + BootDiagnostics = new BootDiagnostics + { + Enabled = true, + StorageUri = storageUri.ToString(), + } + }; + } + } + + ExecuteClientAction(() => + { + var parameters = new VirtualMachine + { + DiagnosticsProfile = this.VM.DiagnosticsProfile, + HardwareProfile = this.VM.HardwareProfile, + StorageProfile = this.VM.StorageProfile, + NetworkProfile = this.VM.NetworkProfile, + OsProfile = this.VM.OSProfile, + Plan = this.VM.Plan, + AvailabilitySet = this.VM.AvailabilitySetReference, + Location = !string.IsNullOrEmpty(this.Location) ? this.Location : this.VM.Location, + Tags = this.Tags != null ? this.Tags.ToDictionary() : this.VM.Tags + }; + + var op = this.VirtualMachineClient.CreateOrUpdate(this.ResourceGroupName, this.VM.Name, parameters); + var result = Mapper.Map(op); + WriteObject(result); + }); + } + + private Uri GetOrCreateStorageAccountForBootDiagnostics() + { + var storageAccountName = GetStorageAccountNameFromStorageProfile(); + var storageClient = + ClientFactory.CreateClient(DefaultProfile.Context, + AzureEnvironment.Endpoint.ResourceManager); + + if (!string.IsNullOrEmpty(storageAccountName)) + { + try + { + var storageAccountResponse = storageClient.StorageAccounts.GetProperties(this.ResourceGroupName, + storageAccountName); + if (!storageAccountResponse.AccountType.Equals(AccountType.PremiumLRS)) + { + return new Uri(storageAccountResponse.PrimaryEndpoints.Blob); + } + } + catch (Exception e) + { + if (e.Message.Contains("ResourceNotFound")) + { + WriteWarning(string.Format( + Properties.Resources.ResourceManager.GetString("StorageAccountNotFoundForBootDiagnostics"), storageAccountName)); + } + else + { + WriteWarning(string.Format( + Properties.Resources.ResourceManager.GetString("ErrorDuringGettingStorageAccountForBootDiagnostics"), storageAccountName, e.Message)); + } + } + } + + var storageAccount = TryToChooseExistingStandardStorageAccount(storageClient); + + if (storageAccount == null) + { + return CreateStandardStorageAccount(storageClient); + } + + WriteWarning(string.Format(Properties.Resources.ResourceManager.GetString("UsingExistingStorageAccountForBootDiagnostics"), storageAccount.Name)); + + return new Uri(storageAccount.PrimaryEndpoints.Blob); + } + + private string GetStorageAccountNameFromStorageProfile() + { + if (this.VM == null + || this.VM.StorageProfile == null + || this.VM.StorageProfile.OsDisk == null + || this.VM.StorageProfile.OsDisk.Vhd == null + || this.VM.StorageProfile.OsDisk.Vhd.Uri == null) + { + return null; + } + + return GetStorageAccountNameFromUriString(this.VM.StorageProfile.OsDisk.Vhd.Uri); + } + + private StorageAccount TryToChooseExistingStandardStorageAccount(StorageManagementClient client) + { + var storageAccountList = client.StorageAccounts.ListByResourceGroup(this.ResourceGroupName); + if (storageAccountList == null) + { + return null; + } + + try + { + return storageAccountList.First( + e => e.AccountType.HasValue && !e.AccountType.Value.Equals(AccountType.PremiumLRS)); + } + catch (InvalidOperationException e) + { + if (e.Message.Contains("Sequence contains no matching element")) + { + return null; + } + throw; + } + } + + private Uri CreateStandardStorageAccount(StorageManagementClient client) + { + string storageAccountName; + + var i = 0; + bool? nameAvailable = null; + do + { + storageAccountName = GetRandomStorageAccountName(i); + i++; + + nameAvailable = client.StorageAccounts.CheckNameAvailability(storageAccountName).NameAvailable; + } + while (i < 10 && nameAvailable.HasValue && nameAvailable.Value); + + var storaeAccountParameter = new StorageAccountCreateParameters + { + AccountType = AccountType.StandardGRS, + Location = this.Location ?? this.VM.Location, + }; + + try + { + client.StorageAccounts.Create(this.ResourceGroupName, storageAccountName, storaeAccountParameter); + var getresponse = client.StorageAccounts.GetProperties(this.ResourceGroupName, storageAccountName); + WriteWarning(string.Format(Resources.ResourceManager.GetString("CreatingStorageAccountForBootDiagnostics"), storageAccountName)); + + return new Uri(getresponse.PrimaryEndpoints.Blob); + } + catch (Exception e) + { + // Failed to create a storage account for boot diagnostics. + WriteWarning(string.Format(Properties.Resources.ResourceManager.GetString("ErrorDuringCreatingStorageAccountForBootDiagnostics"), e)); + return null; + } + } + + private string GetRandomStorageAccountName(int interation) + { + const int maxSubLength = 5; + const int maxResLength = 6; + const int maxVMLength = 4; + + var subscriptionName = VirtualMachineCmdletHelper.GetTruncatedStr(this.DefaultContext.Subscription.Name, maxSubLength); + var resourcename = VirtualMachineCmdletHelper.GetTruncatedStr(this.ResourceGroupName, maxResLength); + var vmname = VirtualMachineCmdletHelper.GetTruncatedStr(this.VM.Name, maxVMLength); + var datetimestr = DateTime.Now.ToString("MMddHHmm"); + + var output = subscriptionName + resourcename + vmname + datetimestr + interation; + + output = new string((from c in output where char.IsLetterOrDigit(c) select c).ToArray()); + + return output.ToLowerInvariant(); + } + + private static string GetStorageAccountNameFromUriString(string uriStr) + { + Uri uri; + + if (!Uri.TryCreate(uriStr, UriKind.RelativeOrAbsolute, out uri)) + { + return null; + } + + var storageUri = uri.Authority; + var index = storageUri.IndexOf('.'); + return storageUri.Substring(0, index); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/RemoveAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/RemoveAzureVMCommand.cs new file mode 100644 index 000000000000..b9e66d33327a --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/RemoveAzureVMCommand.cs @@ -0,0 +1,55 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Commands.Compute.Properties; +using Microsoft.Azure.Management.Compute; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsCommon.Remove, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class RemoveAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Alias("ResourceName", "VMName")] + [Parameter( + Mandatory = true, + Position = 1, + ValueFromPipelineByPropertyName = true, + HelpMessage = "The resource name.")] + [ValidateNotNullOrEmpty] + public string Name { get; set; } + + [Parameter( + Position = 2, + HelpMessage = "To force the removal.")] + [ValidateNotNullOrEmpty] + public SwitchParameter Force { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + ExecuteClientAction(() => + { + if (this.Force.IsPresent || this.ShouldContinue(Resources.ResourceManager.GetString("VirtualMachineRemovalConfirmation"), Resources.ResourceManager.GetString("VirtualMachineRemovalCaption"))) + { + this.VirtualMachineClient.Delete(this.ResourceGroupName, this.Name); + } + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/UpdateAzureVMCommand.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/UpdateAzureVMCommand.cs new file mode 100644 index 000000000000..6a48dcf8db56 --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/Operation/UpdateAzureVMCommand.cs @@ -0,0 +1,62 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using AutoMapper; +using Microsoft.Azure.Commands.Compute.Common; +using Microsoft.Azure.Commands.Compute.Models; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Compute.Models; +using System.Collections; +using System.Management.Automation; + +namespace Microsoft.Azure.Commands.Compute +{ + [Cmdlet(VerbsData.Update, ProfileNouns.VirtualMachine, DefaultParameterSetName = ResourceGroupNameParameterSet)] + [OutputType(typeof(PSComputeLongRunningOperation))] + public class UpdateAzureVMCommand : VirtualMachineActionBaseCmdlet + { + [Alias("VMProfile")] + [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [ValidateNotNullOrEmpty] + public PSVirtualMachine VM { get; set; } + + [Parameter(ValueFromPipelineByPropertyName = true)] + public Hashtable[] Tags { get; set; } + + protected override void ProcessRecord() + { + base.ProcessRecord(); + + ExecuteClientAction(() => + { + var parameters = new VirtualMachine + { + DiagnosticsProfile = this.VM.DiagnosticsProfile, + HardwareProfile = this.VM.HardwareProfile, + StorageProfile = this.VM.StorageProfile, + NetworkProfile = this.VM.NetworkProfile, + OsProfile = this.VM.OSProfile, + Plan = this.VM.Plan, + AvailabilitySet = this.VM.AvailabilitySetReference, + Location = this.VM.Location, + Tags = this.Tags != null ? this.Tags.ToDictionary() : this.VM.Tags + }; + + var op = this.VirtualMachineClient.CreateOrUpdate(this.ResourceGroupName, this.VM.Name, parameters); + var result = Mapper.Map(op); + WriteObject(result); + }); + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineBaseCmdlet.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineBaseCmdlet.cs new file mode 100644 index 000000000000..1528ccb647fa --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineBaseCmdlet.cs @@ -0,0 +1,29 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Management.Compute; + +namespace Microsoft.Azure.Commands.Compute +{ + public abstract class VirtualMachineBaseCmdlet : ComputeClientBaseCmdlet + { + public IVirtualMachinesOperations VirtualMachineClient + { + get + { + return ComputeClient.ComputeManagementClient.VirtualMachines; + } + } + } +} diff --git a/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineCmdletHelper.cs b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineCmdletHelper.cs new file mode 100644 index 000000000000..b183ac9d1c9e --- /dev/null +++ b/src/CLU/Microsoft.Azure.Commands.Compute/VirtualMachine/VirtualMachineCmdletHelper.cs @@ -0,0 +1,27 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +namespace Microsoft.Azure.Commands.Compute +{ + public class VirtualMachineCmdletHelper + { + public static string GetTruncatedStr(string inputStr, int maxLength) + { + if (inputStr == null) return string.Empty; + return (inputStr.Length > maxLength) + ? inputStr.Substring(0, maxLength) + : inputStr; + } + } +}