Quantcast
Channel: The Official Scripting Guys Forum! forum
Viewing all articles
Browse latest Browse all 15028

I can't get ParameterSets to work

$
0
0

I'm new to PowerShell, and I'm having trouble with parameter sets. I've created a function that will retrieve memory info from a computer. I have the function working properly, except for the parameters sets. Here's the syntax I want to support:

#Run without parameters for memory usage on localhost:
  Get-MemoryUsage

#Get memory usage on remote system:
  Get-MemoryUsage [-ComputerName] <String>
#Examples:
#  Get-MemoryUsage -ComputerName mydc01
#  Get-MemoryUsage mydc01
#  "mydc01", "mydc02" | Get-MemoryUsage

#Get memory usage on remote system running on Hyper-V host, where "name" is the name of the virtual machine in Hyper-V manager:
  Get-MemoryUsage [-ComputerName] <String> [-HostName] <String> [-Name] <String>
#Examples:
#  Get-MemoryUsage -ComputerName mydc01 -HostName hvsvr -Name TheDC
#  Get-MemoryUsage mydc01 hvsvr TheDC

#Get memory usage on remote system running on Hyper-V host, where "ID" is the GUID of the virtual machine:
  Get-MemoryUsage [-ComputerName] <String> [-HostName] <String> [-ID] <GUID>
#Examples:
#  Get-MemoryUsage -ComputerName mydc01 -HostName hvsvr -ID 837b8cbc-b89c-4070-bf65-4b674bb380e4
#  Get-MemoryUsage mydc01 hvsvr [GUID]837b8cbc-b89c-4070-bf65-4b674bb380e4

#Lastly, I want to be able to pipeline in a [Microsoft.HyperV.PowerShell.VirtualMachine] object like so:
  Get-VM -ComputerName hvsvr -Name TheDC | Get-MemoryUsage -Computername mydc01
  $vm = Get-VM -Name TheDC ; Get-MemoryUsage mydc01 $vm

To summarize syntax:

  • You must always specify the computer name, unless you want to target the local computer
  • If targeting a Hyper-V virtual machine, you must also specify one of the following:
  • 1. The Hyper-V server and virtual machine name
  • 2. The Hyper-V server and virtual machine GUID
  • 3. A [Microsoft.HyperV.PowerShell.VirtualMachine] object

Here's the function declaration:

function Get-MemoryUsage {
    [CmdletBinding()]
    param (
        [Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="notVM", HelpMessage='Enter the computer name')]
        [Parameter(Position=0, ValueFromPipelineByPropertyName=$true, ParameterSetName="byName", HelpMessage='Enter the computer name of the guest virtual machine')]
        [Parameter(Position=0, ValueFromPipelineByPropertyName=$true, ParameterSetName="byID", HelpMessage='Enter the computer name of the guest virtual machine')]
        [Parameter(Position=0, ValueFromPipelineByPropertyName=$true, ParameterSetName="byObj", HelpMessage='Enter the computer name of the guest virtual machine')]
        [Alias('GuestName','GuestComputerName')] [String[]] $ComputerName=$env:COMPUTERNAME,

        [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="byName", HelpMessage='Enter the computer name of the Hyper-V host')]
        [Parameter(Position=1, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="byID", HelpMessage='Enter the computer name of the Hyper-V host')]
        [Alias('host','server')] [String[]] $HostName,

        [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="byObj")]
        [Alias('VirtualMachine')] [Microsoft.HyperV.PowerShell.VirtualMachine[]] $VM,

        [Parameter(Position=2, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="byName", HelpMessage='Enter the name of the virtual machine in Hyper-V')]
        [Alias('VirtualMachineName','Guest')][String[]] $Name,

        [Parameter(Position=2, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="byID", HelpMessage='Enter the GUID of the virtual machine')]
        [Alias('VirtualMachineId','vmid')][GUID[]] $ID
    )
    process {
        Write-Host $PsCmdlet.ParameterSetName
    }
}

It seems to work as expected except for this example (sometimes the user will pipe in both Name and Id, and I cannot stop them):

New-Object –Typename PSObject –Prop @{'HostName'="hvsvr";'GuestComputerName'="mydc01";'VirtualMachineId'=[GUID]"837b8cbc-b89c-4070-bf65-4b674bb380e4";'VirtualMachineName'="TheDC"} | Get-MemoryUsage

#Error:
Get-MemoryUsage : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:200
+ ... TheDC} | Get-MemoryUsage+                    ~~~~~~~~~~~~~~~+ CategoryInfo          : InvalidArgument: (@{VirtualMachin...m3 server 2012}:PSObject) [Get-MemoryUsage], ParameterBindingException+ FullyQualifiedErrorId : AmbiguousParameterSet,Get-MemoryUsage

#If I remove either the 'VirtualMachineName' or 'VirtualMachineId' property, it works.  Or if I remove the [GUID] cast, it works.

How can I fix this?

This whole declaration seems sloppy to me.  Is there a better way?  Suggestions are welcome.


-Tony


Viewing all articles
Browse latest Browse all 15028

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>