All top-level resources should have a Get-*
cmdlet that allows users to list the resources in their subscription or a resource group, as well as get a specific resource. In addition, users should be able to provide the resource id of the resource they want to get, and the cmdlet will parse the string to get the necessary identity information.
To enable the scenarios mentioned previously, the cmdlet will need three parameter sets:
Get-AzFoo [-ResourceGroupName <String>]
Get-AzFoo -ResourceGroupName <String> -Name <String>
Get-AzFoo -ResourceId <String>
The first parameter set has an optional -ResourceGroupName
parameter, which allows the user to list all resources in a subscription or in a resource group. The second parameter set has required -ResourceGroupName
and -Name
parameters, which allows the user to get a specific resource. The third parameter set has a required -ResourceId
parameter, which allows the user to get a specific resource by resource id.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Get, "AzFoo", DefaultParameterSetName = ListParameterSet), OutputType(typeof(PSFoo))]
public class GetFooCommand : FooBaseCmdlet
{
private const string ListParameterSet = "ListParameterSet";
private const string GetByNameParameterSet = "GetByNameParameterSet";"
private const string GetByResourceIdParameterSet = "GetByResourceIdParameterSet";
[Parameter(Mandatory = false, ParameterSetName = ListParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = GetByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = GetByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = GetByResourceIdParameterSet )]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.Name = resourceIdentifier.ResourceName;
}
if (!string.IsNullOrEmpty(this.Name))
{
var result = new PSFoo(this.MySDKClient.Foo.Get(this.ResourceGroupName, this.Name));
WriteObject(result);
}
else if (!string.IsNullOrEmpty(this.ResourceGroupName))
{
var result = this.MySDKClient.Foo.ListByResourceGroup(this.ResourceGroupName).Select(f => new PSFoo(f));
WriteObject(result, true);
}
else
{
var result = this.MySDKClient.Foo.List().Select(f => new PSFoo(f));
WriteObject(result, true);
}
}
}
}
All top-level resources should have a New-*
cmdlet that allows users to create a resource with given properties. Properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being created.
Note: for long-running operations (~15s or longer), it is advised to add the -AsJob
to your cmdlet.
To enable the above scenario, only one parameter set is needed:
New-AzFoo -ResourceGroupName <String> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
This parameter set has required -ResourceGroupName
and -Name
parameters to satisfy the identity properties of the resource, as well as a few optional -PropertyX
parameters that allows the user to set values for properties. The parameter set also has optional -WhatIf
and -Confirm
parameters that are automatically included from the implementation of SupportsShouldProcess
.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.New, "AzFoo", DefaultParameterSetName = CreateParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSFoo))]
public class NewFooCommand : FooBaseCmdlet
{
private const string CreateParameterSet = "CreateParameterSet";
[Parameter(Mandatory = true, ParameterSetName = CreateParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = CreateParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = false, ParameterSetName = CreateParameterSet)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = false, ParameterSetName = CreateParameterSet)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
Foo existingFoo = null;
try
{
existingFoo = this.MySDKClient.Foo.Get(this.ResourceGroupName, this.Name);
}
catch
{
existingFoo = null;
}
if (existingFoo != null)
{
throw new Exception(string.Format("A Foo with name '{0}' in resource group '{1}' already exists. Please use Set/Update-AzFoo to update an existing Foo.", this.Name, this.ResourceGroupName));
}
existingFoo = new Foo()
{
Name = this.Name,
ResourceGroupName = this.ResourceGroupName,
Property1 = this.Property1,
Property2 = this.Property2,
...
}
if (this.ShouldProcess(this.Name, string.Format("Creating a new Foo in resource group '{0}' with name '{1}'.", this.ResourceGroupName, this.Name))
{
var result = new PSFoo(this.MySDKClient.Foo.CreateOrUpdate(existingFoo));
WriteObject(result);
}
}
}
}
All top-level resources should have a Remove-*
cmdlet that allows users to delete a specific resource. The user can delete a resource by providing all identity properties, the resource id, or the object representation of the resource. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being deleted. This cmdlet should also implement the -PassThru
parameter, which allows the user to receive output when no output would normally be provided.
To enable the scenarios mentioned previously, the cmdlet will need three parameter sets:
Remove-AzFoo -ResourceGroupName <String> -Name <String> [-PassThru] [-WhatIf] [-Confirm]
Remove-AzFoo -InputObject <PSFoo> [-PassThru] [-WhatIf] [-Confirm]
Remove-AzFoo -ResourceId <String> [-PassThru] [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
and -Name
parameters, which allows the user to explicitly provide the identity properties of the resource that they want to delete. The second parameter has a required -InputObject
parameter, which allows the user to pipe the result of the Get-*
and Set/Update-*
cmdlets to this cmdlet and delete the corresponding resource. The third parameter has a required -ResourceId
parameter, which allows the user to delete a specific resource by resource id.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Remove, "AzFoo", DefaultParameterSetName = DeleteByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(bool))]
public class RemoveFooCommand : FooBaseCmdlet
{
private const string DeleteByNameParameterSet = "DeleteByNameParameterSet";
private const string DeleteByInputObjectParameterSet = "DeleteByInputObjectParameterSet";
private const string DeleteByResourceIdParameterSet = "DeleteByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = DeleteByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = DeleteByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = DeleteByInputObjectParameterSet)]
[ValidateNotNull]
public PSFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = DeleteByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = false)]
public SwitchParameter PassThru { get; set; }
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.Name = this.InputObject.Name;
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.Name = resourceIdentifier.ResourceName;
}
if (this.ShouldProcess(this.Name, string.Format("Deleting Foo '{0}' in resource group {0}", this.Name, this.ResourceGroupName)))
{
this.MySDKClient.Foo.Delete(this.ResourceGroupName, this.Name);
if (this.IsPassThru.IsPresent)
{
WriteObject(true);
}
}
}
}
}
All top-level resources should have a Set-*
cmdlet that allows users to update an existing resource if the API follows PUT
semantics. If the API supports PATCH
semantics, then the cmdlet should be Update-*
(see below). The user can update an existing resource by providing all identity properties, the resource id, or the object representation of the resource. Similar to the New-*
cmdlet, properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being updated.
To enable the scenarios mentioned previously, the cmdlet will need three parameter sets:
Set-AzFoo -ResourceGroupName <String> -Name <String> -Property1 <Type1> -Property2 <Type2> ... [-WhatIf] [-Confirm]
Set-AzFoo -InputObject <PSFoo> [-Property1 <Type1>] -[Property2 <Type2>] ... [-WhatIf] [-Confirm]
Set-AzFoo -ResourceId <String> -Property1 <Type1> -Property2 <Type2> ... [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
and -Name
parameters, as well as required property parameters to set their values on the resource. The second parameter has a required -InputObject
parameter, as well as optional property parameters that override the value of the property on the given object if provided. The third parameter has a required -ResourceId
parameter, as well as required property parameters to set their values on the resource.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Set, "AzFoo", DefaultParameterSet = SetByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSFoo))]
public class SetFooCommand : FooBaseCmdlet
{
private const string SetByNameParameterSet = "SetByNameParameterSet";
private const string SetByInputObjectParameterSet = "SetByInputObjectParameterSet";
private const string SetByResourceIdParameterSet = "SetByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = SetByInputObjectParameterSet)]
[ValidateNotNull]
public PSFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = SetByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByResourceIdParameterSet)]
[Parameter(Mandatory = false, ParameterSetName = SetByInputObjectParameterSet)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByResourceIdParameterSet)]
[Parameter(Mandatory = false, ParameterSetName = SetByInputObjectParameterSet)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.Name = this.InputObject.Name;
this.Property1 = this.IsParameterBound(c => c.Property1) ? this.Property1 : this.InputObject.Property1;
this.Property2 = this.IsParameterBound(c => c.Property2) ? this.Property2 : this.InputObject.Property2;
...
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.Name = resourceIdentifier.ResourceName;
}
Foo foo = null;
try
{
foo = this.MySDKClient.Foo.Get(this.ResourceGroupName, this.Name);
}
catch
{
foo = null;
}
if (foo == null)
{
throw new Exception(string.Format("A Foo with name '{0}' in resource group '{1}' does not exist. Please use New-AzFoo to create a Foo with these properties.", this.Name, this.ResourceGroupName));
}
foo.Property1 = this.Property1;
foo.Property2 = this.Property2;
...
if (this.ShouldProcess(this.Name, string.Format("Updating Foo '{0}' in resource group '{1}'.", this.Name, this.ResourceGroupName)))
{
var result = new PSFoo(this.MySDKClient.Foo.Update(this.ResourceGroupName, this.Name, foo)
WriteObject(result);
}
}
}
}
All top-level resources should have an Update-*
cmdlet that allows users to update an existing resource if the API follows PATCH
semantics. If the API supports PUT
semantics, then the cmdlet should be Set-*
(see above). The user can update an existing resource by providing all identity properties, the resource id, or the object representation of the resource. Similar to the New-*
cmdlet, properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being updated.
Note: if the only property that a user is able to update through the PATCH
API is tags, then this cmdlet should not be implemented.
To enable the scenarios mentioned previously, the cmdlet will need three parameter sets:
Update-AzFoo -ResourceGroupName <String> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Update-AzFoo -InputObject <PSFoo> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Update-AzFoo -ResourceId <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
and -Name
parameters, the second parameter set has a required -InputObject
parameter, and the third parameter set has a required -ResourceId
parameter. All three parameter sets have optional property parameters that can be used to override the value of the property set on the retrieved/provided resource.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsData.Update, "AzFoo", DefaultParameterSet = UpdateByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSFoo))]
public class UpdateFooCommand : FooBaseCmdlet
{
private const string UpdateByNameParameterSet = "UpdateByNameParameterSet";
private const string UpdateByInputObjectParameterSet = "UpdateByInputObjectParameterSet";
private const string UpdateByResourceIdParameterSet = "UpdateByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = UpdateByInputObjectParameterSet)]
[ValidateNotNull]
public PSFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = UpdateByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = false)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = false)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.Name = this.InputObject.Name;
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.Name = resourceIdentifier.ResourceName;
}
Foo foo = null;
try
{
foo = this.MySDKClient.Foo.Get(this.ResourceGroupName, this.Name);
}
catch
{
foo = null;
}
if (foo == null)
{
throw new Exception(string.Format("A Foo with name '{0}' in resource group '{1}' does not exist. Please use New-AzFoo to create a Foo with these properties.", this.Name, this.ResourceGroupName));
}
foo.Property1 = this.IsParameterBound(c => c.Property1) ? this.Property1 : foo.Property1;
foo.Property2 = this.IsParameterBound(c => c.Property2) ? this.Property2 : foo.Property2;
...
if (this.ShouldProcess(this.Name, string.Format("Updating Foo '{0}' in resource group '{1}'.", this.Name, this.ResourceGroupName)))
{
var result = new PSFoo(this.MySDKClient.Foo.Update(this.ResourceGroupName, this.Name, foo)
WriteObject(result);
}
}
}
}
All child resources should have a Get-*
cmdlet that allows users to list the child resources under a parent resource, as well as get a specific resource. In addition, users should be able to provide the resource id of the resource they want to get, and the cmdlet will parse the string to get the necessary identity information.
To enable the scenarios mentioned previously, the cmdlet will need three parameter sets:
Get-AzChildFoo -ResourceGroupName <String> -FooName <String> [-Name <String>]
Get-AzChildFoo -FooObject <PSFoo> [-Name <String>]
Get-AzChildFoo -ResourceId <String>
The first parameter set has mandatory -ResourceGroupName
and -FooName
parameters to get the identity information about the parent resource, and then an optional -Name
parameter to allow the user to either list all child resources contained in the given parent or get the specific child resource. The second parameter set has required -FooObject
parameter, which can be piped from the parent Get-*
or Set/Update-*
cmdlet, and an optional -Name
parameter. The third parameter set has a required -ResourceId
parameter, which allows the user to get a specific child resource by resource id.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Get, "AzChildFoo", DefaultParameterSetName = GetByNameParameterSet), OutputType(typeof(PSChildFoo))]
public class GetChildFooCommand : FooBaseCmdlet
{
private const string GetByNameParameterSet = "GetByNameParameterSet";
private const string GetByParentObjectParameterSet = "GetByParentObjectParameterSet";
private const string GetByResourceIdParameterSet = "GetByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = GetByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = GetByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string FooName { get; set; }
[Parameter(Mandatory = false, ParameterSetName = GetByNameParameterSet)]
[Parameter(Mandatory = false, ParameterSetName = GetByParentObjectParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = GetByParentObjectParameterSet)]
[ValidateNotNull]
public PSFoo FooObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = GetByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.FooName = resourceIdentifier.ParentResource
this.Name = resourceIdentifier.ResourceName;
}
if (this.IsParameterBound(c => c.FooObject))
{
this.ResourceGroupName = this.FooObject.ResourceGroupName;
this.FooName = this.FooObject.Name;
}
if (!string.IsNullOrEmpty(this.Name))
{
var result = new PSChildFoo(this.MySDKClient.ChildFoo.Get(this.ResourceGroupName, this.FooName, this.Name));
WriteObject(result);
}
else
{
var result = this.MySDKClient.ChildFoo.ListByFoo(this.ResourceGroupName, this.FooName).Select(f => new PSChildFoo(f));
WriteObject(result, true);
}
}
}
}
All child resources should have a New-*
cmdlet that allows users to create a child resource with given properties. Properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being created.
Note: for long-running operations (~15s or longer), it is advised to add the -AsJob
to your cmdlet.
To enable the above scenario, the cmdlet will need two parameter sets:
New-AzChildFoo -ResourceGroupName <String> -FooName <String> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
New-AzChildFoo -FooObject <PSFoo> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
, -FooName
and -Name
parameters to satisfy the identity properties of the child resource, as well as a few optional -PropertyX
parameters that allows the user to set values for the properties. The second parameter set has a required -FooObject
parameter that can be piped from the parent resource's Get-*
and Set/Update-*
cmdlets.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.New, "AzChildFoo", DefaultParameterSetName = CreateByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSChildFoo))]
public class NewChildFooCommand : FooBaseCmdlet
{
private const string CreateByNameParameterSet = "CreateByNameParameterSet";
private const string CreateByParentObjectParameterSet = "CreateByParentObjectParameterSet";
[Parameter(Mandatory = true, ParameterSetName = CreateByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = CreateByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string FooName { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = CreateByParentObjectParameterSet)]
[ValidateNotNull]
public PSFoo FooObject { get; set; }
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = false)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = false)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.FooObject))
{
this.ResourceGroupName = this.FooObject.ResourceGroupName;
this.FooName = this.FooObject.FooName;
}
ChildFoo existingFoo = null;
try
{
existingChildFoo = this.MySDKClient.ChildFoo.Get(this.ResourceGroupName, this.FooName, this.Name);
}
catch
{
existingChildFoo = null;
}
if (existingChildFoo != null)
{
throw new Exception(string.Format("A ChildFoo with name '{0}' in resource group '{1}' under parent Foo '{2}' already exists. Please use Set/Update-AzChildFoo to update an existing ChildFoo.", this.Name, this.ResourceGroupName, this.FooName));
}
existingChildFoo = new ChildFoo()
{
Name = this.Name,
FooName = this.FooName,
ResourceGroupName = this.ResourceGroupName,
Property1 = this.Property1,
Property2 = this.Property2,
...
}
if (this.ShouldProcess(this.Name, string.Format("Creating a new ChildFoo in resource group '{0}' under parent Foo '{1}' with name '{2}'.", this.ResourceGroupName, this.FooName, this.Name))
{
var result = new PSChildFoo(this.MySDKClient.ChildFoo.CreateOrUpdate(existingChildFoo));
WriteObject(result);
}
}
}
}
All child resources should have a Remove-*
cmdlet that allows users to delete a specific child resource. The user can delete a child resource by providing all identity properties, the resource id of the child resource, or the object representation of the child resource. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the child resource actually being deleted. This cmdlet should also implement the -PassThru
parameter, which allows the user to receive the output when no output would normally be provided.
To enable the scenarios mentioned previously, the cmdlet will need four parameter sets:
Remove-AzChildFoo -ResourceGroupName <String> -FooName <String> -Name <String> [-PassThru] [-WhatIf] [-Confirm]
Remove-AzChildFoo -FooObject <PSFoo> -Name <String> [-PassThru] [-WhatIf] [-Confirm]
Remove-AzChildFoo -InputObject <PSChildFoo> [-PassThru] [-WhatIf] [-Confirm]
Remove-AzChildFoo -ResourceId <String> [-PassThru] [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
, -FooName
and -Name
parameters, which allows the user to explicitly provide the identity properties of the child resource that they want to delete. The second parameter has a required -FooObject
parameter, which allows the user to pipe the result of the parent resource's Get-*
and Set/Update-*
cmdlets to this cmdlet, as well as a required -Name
parameter. The third parameter has a required -InputObject
parameter, which allows the user to pipe the result of the Get-*
and Set/Update-*
cmdlets to this cmdlet and delete the corresponding child resource. The fourth parameter has a required -ResourceId
parameter, which allows the user to delete the specific child resource by resource id.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Remove, "AzChildFoo", DefaultParameterSetName = DeleteByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(bool))]
public class RemoveChildFooCommand : FooBaseCmdlet
{
private const string DeleteByNameParameterSet = "DeleteByNameParameterSet";
private const string DeleteByParentObjectParameterSet = "DeleteByParentObjectParameterSet";
private const string DeleteByInputObjectParameterSet = "DeleteByInputObjectParameterSet";
private const string DeleteByResourceIdParameterSet = "DeleteByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = DeleteByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = DeleteByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string FooName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = DeleteByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = DeleteByParentObjectParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = DeleteByParentObjectParameterSet)]
[ValidateNotNull]
public PSFoo FooObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = DeleteByInputObjectParameterSet)]
[ValidateNotNull]
public PSChildFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = DeleteByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = false)]
public SwitchParameter PassThru { get; set; }
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.FooObject))
{
this.ResourceGroupName = this.FooObject.ResourceGroupName;
this.FooName = this.FooObject.Name;
}
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.FooName = this.InputObject.FooName;
this.Name = this.InputObject.Name;
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.FooName = resourceIdentifier.ParentResource;
this.Name = resourceIdentifier.ResourceName;
}
if (this.ShouldProcess(this.Name, string.Format("Deleting ChildFoo '{0}' in resource group '{1}' under parent Foo '{2}'.", this.Name, this.ResourceGroupName, this.FooName)))
{
this.MySDKClient.ChildFoo.Delete(this.ResourceGroupName, this.FooName, this.Name);
if (this.IsPassThru.IsPresent)
{
WriteObject(true);
}
}
}
}
}
All child resources should have a Set-*
cmdlet that allows users to update an existing child resource if the API follows PUT
semantics. If the API supports PATCH
semantics, then the cmdlet should be Update-*
(see below). The user can update an existing child resource by providing all identity properties, the resource id, or the object representation of the child resource. Similar to the New-*
cmdlet, properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being updated.
To enable the scenarios mentioned previously, the cmdlet will need four parameter sets:
Set-AzChildFoo -ResourceGroupName <String> -FooName <String> -Name <String> -Property1 <Type1> -Property2 <Type2> ... [-WhatIf] [-Confirm]
Set-AzChildFoo -FooObject <PSFoo> -Name <String> -Property1 <Type1> -Property2 <Type2> ... [-WhatIf] [-Confirm]
Set-AzChildFoo -InputObject <PSChildFoo> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Set-AzChildFoo -ResourceId <String> -Property1 <Type1> -Property2 <Type2> ... [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
, -FooName
and -Name
parameters, as well as required property parameters to set their values on the child resource. The second parameter set has a required -FooObject
parameter, which allows the user to pipe the result of the parent resource's Get-*
and Set/Update-*
cmdlets to this cmdlet, as well as required property parameters. The third parameter set has a required -InputObject
parameter, as well as optional property parameters that override the value of the property on the given object if provided. The fourth parameter set has a required -ResourceIid
parameter, as well as required property parameters to set their values on the child resource.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsCommon.Set, "AzChildFoo", DefaultParameterSet = SetByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSChildFoo))]
public class SetChildFooCommand : FooBaseCmdlet
{
private const string SetByNameParameterSet = "SetByNameParameterSet";
private const string SetByParentObjectParameterSet = "SetByParentObjectParameterSet";
private const string SetByInputObjectParameterSet = "SetByInputObjectParameterSet";
private const string SetByResourceIdParameterSet = "SetByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)
[ValidateNotNullOrEmpty]
public string FooName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByParentObjectParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = SetByParentObjectParameterSet)]
[ValidateNotNull]
public PSFoo FooObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = SetByInputObjectParameterSet)]
[ValidateNotNull]
public PSChildFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = SetByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByParentObjectParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByResourceIdParameterSet)]
[Parameter(Mandatory = false, ParameterSetName = SetByInputObjectParameterSet)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = true, ParameterSetName = SetByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByParentObjectParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = SetByResourceIdParameterSet)]
[Parameter(Mandatory = false, ParameterSetName = SetByInputObjectParameterSet)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.FooObject))
{
this.ResourceGroupName = this.FooObject.ResourceGroupName;
this.FooName = this.FooObject.Name;
}
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.FooName = this.InputObject.FooName;
this.Name = this.InputObject.Name;
this.Property1 = this.IsParameterBound(c => c.Property1) ? this.Property1 : this.InputObject.Property1;
this.Property2 = this.IsParameterBound(c => c.Property2) ? this.Property2 : this.InputObject.Property2;
...
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.FooName = resourceIdentifier.ParentResource;
this.Name = resourceIdentifier.ResourceName;
}
ChildFoo childFoo = null;
try
{
childFoo = this.MySDKClient.ChildFoo.Get(this.ResourceGroupName, this.FooName, this.Name);
}
catch
{
childFoo = null;
}
if (childFoo == null)
{
throw new Exception(string.Format("A ChildFoo with name '{0}' in resource group '{1}' under parent Foo '{2}' does not exist. Please use New-AzChildFoo to create a ChildFoo with these properties.", this.Name, this.ResourceGroupName, this.FooName));
}
childFoo.Property1 = this.Property1;
childFoo.Property2 = this.Property2;
...
if (this.ShouldProcess(this.Name, string.Format("Updating Foo '{0}' in resource group '{1}' under parent Foo '{2}'.", this.Name, this.ResourceGroupName, this.FooName)))
{
var result = new PSChildFoo(this.MySDKClient.ChildFoo.Update(this.ResourceGroupName, this.FooName, this.Name, childFoo)
WriteObject(result);
}
}
}
}
All child resources should have an Update-*
cmdlet that allows users to update an existing child resource if the API follows PATCH
semantics. If the API supports PUT
semantics, then the cmdlet should be Set-*
(See above). The user can update an existing child resource by providing all identity properties, the resource id, or the object representation of the child resource. Similar to the New-*
cmdlet, properties that are required by the API should be mandatory parameters, and in the case where different combinations of properties are needed depending on a provided value (e.g., Windows and Linux VMs have different properties), multiple parameter sets should be used. This cmdlet should implement SupportsShouldProcess
to allow users to provide the -WhatIf
parameter and see what the result of executing the cmdlet is without the resource actually being updated.
To enable the scenarios mentioned previously, the cmdlet will need four parameter sets:
Update-AzChildFoo -ResourceGroupName <String> -FooName <String> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Update-AzChildFoo -FooObject <PSFoo> -Name <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Update-AzChildFoo -InputObject <PSChildFoo> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
Update-AzChildFoo -ResourceId <String> [-Property1 <Type1>] [-Property2 <Type2>] ... [-WhatIf] [-Confirm]
The first parameter set has required -ResourceGroupName
, -FooName
and -Name
parameters, the second parameter set has required -FooObject
and -Name
parameters, the third parameter set has a required -InputObject
parameter, and the fourth parameter set has a required -ResourceId
parameter. All four parameter sets have optional property parameters that can be used to override the value of the property set on the retrieved/provided resource.
Click to expand example
namespace Microsoft.Azure.Commands.Foo
{
[Cmdlet(VerbsData.Update, "AzChildFoo", DefaultParameterSet = UpdateByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSChildFoo))]
public class UpdateChildFooCommand : FooBaseCmdlet
{
private const string UpdateByNameParameterSet = "UpdateByNameParameterSet";
private const string UpdateByParentObjectParameterSet = "UpdateByParentObjectParameterSet";
private const string UpdateByInputObjectParameterSet = "UpdateByInputObjectParameterSet";
private const string UpdateByResourceIdParameterSet = "UpdateByResourceIdParameterSet";
[Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet)]
[ResourceGroupCompleter]
[ValidateNotNullOrEmpty]
public string ResourceGroupName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet)]
[ValidateNotNullOrEmpty]
public string FooName { get; set; }
[Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet)]
[Parameter(Mandatory = true, ParameterSetName = UpdateByParentObjectParameterSet)]
[ValidateNotNullOrEmpty]
public string Name { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = UpdateByParentObjectParameterSet)]
[ValidateNotNull]
public PSFoo FooObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = UpdateByInputObjectParameterSet)]
[ValidateNotNull]
public PSFoo InputObject { get; set; }
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = UpdateByResourceIdParameterSet)]
[ValidateNotNullOrEmpty]
public string ResourceId { get; set; }
[Parameter(Mandatory = false)]
public Type1 Property1 { get; set; }
[Parameter(Mandatory = false)]
public Type2 Property2 { get; set; }
// Excluding other property parameters
public override void ExecuteCmdlet()
{
if (this.IsParameterBound(c => c.FooObject))
{
this.ResourceGroupName = this.FooObject.ResourceGroupName;
this.FooName = this.FooObject.Name;
}
if (this.IsParameterBound(c => c.InputObject))
{
this.ResourceGroupName = this.InputObject.ResourceGroupName;
this.FooName = this.InputObject.FooName;
this.Name = this.InputObject.Name;
}
if (this.IsParameterBound(c => c.ResourceId))
{
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
this.ResourceGroupName = resourceIdentifier.ResourceGroupName;
this.FooName = resourceIdentifer.ParentResource;
this.Name = resourceIdentifier.ResourceName;
}
ChildFoo childFoo = null;
try
{
childFoo = this.MySDKClient.ChildFoo.Get(this.ResourceGroupName, this.FooName, this.Name);
}
catch
{
childFoo = null;
}
if (childFoo == null)
{
throw new Exception(string.Format("A ChildFoo with name '{0}' in resource group '{1}' under parent Foo '{2}' does not exist. Please use New-AzChildFoo to create a ChildFoo with these properties.", this.Name, this.ResourceGroupName, this.FooName));
}
childFoo.Property1 = this.IsParameterBound(c => c.Property1) ? this.Property1 : childFoo.Property1;
childFoo.Property2 = this.IsParameterBound(c => c.Property2) ? this.Property2 : childFoo.Property2;
...
if (this.ShouldProcess(this.Name, string.Format("Updating Foo '{0}' in resource group '{1}' under parent Foo '{2}'.", this.Name, this.ResourceGroupName, this.FooName)))
{
var result = new PSChildFoo(this.MySDKClient.ChildFoo.Update(this.ResourceGroupName, this.FooName, this.Name, childFoo)
WriteObject(result);
}
}
}
}