Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

Better way of multiplayer IFs with PowerShell

Im wondering if I am tackling this in the best way or if there is a better way of achieving my task.

I've written a function in PowerShell which takes different parameters, but some of the parameters won't work together.

So for example if I'm running the function and specifying a computerName parameter then I can't also pass list of multiple computer names.

I know I can write multiple If statements as along the lines if If(($computerName) - and ($computerList)){Then write and error}

but there are several parameters not just two, so do I need to do an if for each set of parameters someone could type in, or is there a better way of me tackling this?

currently I have multiple Ifs like If $computerName -and !(log file) and $computerlist) then write an error etc.

question from:https://stackoverflow.com/questions/65924476/better-way-of-multiplayer-ifs-with-powershell

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The PowerShell-idiomatic solution here is to declare a parameter that accepts either:

function Get-Stuff
{
  param(
    [Parameter(ValueFromPipeline = $true)]
    [string[]]$ComputerName
  )

  process {
    foreach($Computer in $ComputerName){
      # do stuff with each individual -ComputerName argument
    }
  }
}

Now the user can do both

Get-Stuff -ComputerName oneComputerName

... and

"many","computer","names" |Get-Stuff

or for that matter

$computers = Get-Content .Computers.txt
Get-Stuff -ComputerName $computers
# or
$computers |Get-Stuff

I know I can write multiple If statements as along the lines of If(($computerName) -and ($computerList)){Then write and error}

You can, but this is generally a bad idea - to test whether an argument value was passed to a parameter is better done through the automatic variable $PSBoundParameters:

function Get-Stuff
{
  param(
    [string]$AParameter,
    [string]$ADifferentOne
  )

  if($PSBoundParameters.ContainsKey('AParameter')){
    # an argument was definitely provided to $AParameter
  }

  if($PSBoundParameters.ContainsKey('ADifferentOne')){
    # an argument was definitely provided to $ADifferentOne
  }
}

The answer to the implied question of "how do I declare and work with mutually exclusive parameters" is parameter sets:

function Verb-Noun
{
  param(
    [Parameter(Mandatory = $true, ParameterSetName = 'SingleComputer')]
    [string]$ComputerName,

    [Parameter(Mandatory = $true, ParameterSetName = 'MultipleComputers')]
    [string[]]$ComputerList

  )

  if($PSCmdlet.ParameterSetName -eq 'SingleComputer'){
    # just one, we can deal with $ComputerName
  }
  else {
    # we got multiple names via $ComputerList
  }

}

PowerShell now recognizes two distinct parameter sets, each of which only accepts one of our parameters:

PS ~> Get-Command Verb-Noun -Syntax

Verb-Noun -ComputerName <string> [<CommonParameters>]

Verb-Noun -ComputerList <string[]> [<CommonParameters>]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...