Se eu tiver uma função que aceita mais de um parâmetro de string, o primeiro parâmetro parece obter todos os dados atribuídos a ele e os parâmetros restantes são passados como vazios.
Um script de teste rápido:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
A saída gerada é
$arg1 value: ABC DEF
$arg2 value:
A saída correta deve ser:
$arg1 value: ABC
$arg2 value: DEF
Isso parece ser consistente entre v1 e v2 em várias máquinas, então, obviamente, estou fazendo algo errado. Alguém pode apontar exatamente o que?
powershell
Nasir
fonte
fonte
Test "ABC" "DEF"
Respostas:
Os parâmetros nas chamadas para funções no PowerShell (todas as versões) são separados por espaço, não por vírgula . Além disso, os parênteses são totalmente desnecessários e causarão um erro de análise no PowerShell 2.0 (ou posterior) se
Set-StrictMode
estiver ativo. Os argumentos entre parênteses são usados apenas nos métodos .NET.fonte
(1,2,3)
para uma função é efetivamente tratado como uma matriz; um único argumento. Se você deseja usar argumentos de estilo de método OO, use os módulos:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
Powershell
é uma linguagem shell e é comum que as linguagens shell usem espaços como um separador de token. Eu não diria quePowershell
é ser diferente aqui, é bem em linha com outros shells padrão do sistema, comocmd
,sh
,bash
, etc.A resposta correta já foi fornecida, mas esse problema parece prevalecer o suficiente para justificar alguns detalhes adicionais para quem deseja entender as sutilezas.
Eu teria adicionado isso apenas como um comentário, mas queria incluir uma ilustração - rasguei isso do meu gráfico de referência rápida nas funções do PowerShell. Isso pressupõe que a assinatura da função f seja
f($a, $b, $c)
:Assim, pode-se chamar uma função com parâmetros posicionais separados por espaço ou parâmetros nomeados independentes de ordem . As outras armadilhas revelam que você precisa conhecer vírgulas, parênteses e espaços em branco.
Para uma leitura mais aprofundada, consulte o meu artigo Abaixo da toca do coelho: um estudo em dutos, funções e parâmetros do PowerShell . O artigo também contém um link para o gráfico de referência rápida / mural.
fonte
Há algumas respostas boas aqui, mas eu queria apontar algumas outras coisas. Os parâmetros de função são, na verdade, um local onde o PowerShell brilha. Por exemplo, você pode ter parâmetros nomeados ou posicionais em funções avançadas como:
Em seguida, você pode chamá-lo especificando o nome do parâmetro ou apenas usar parâmetros posicionais, já que os definiu explicitamente. Então, qualquer um destes funcionaria:
O primeiro exemplo funciona, embora
Name
seja fornecido em segundo lugar, porque usamos explicitamente o nome do parâmetro. O segundo exemplo funciona com base na posição, portanto,Name
seria necessário primeiro. Sempre que possível, tento sempre definir posições para que ambas as opções estejam disponíveis.O PowerShell também tem a capacidade de definir conjuntos de parâmetros. Ele usa isso no lugar da sobrecarga do método e, novamente, é bastante útil:
Agora, a função terá um nome ou um ID, mas não os dois. Você pode usá-los posicionalmente ou pelo nome. Como eles são de um tipo diferente, o PowerShell descobrirá isso. Então, tudo isso funcionaria:
Você também pode atribuir parâmetros adicionais aos vários conjuntos de parâmetros. (Esse foi um exemplo bastante básico, obviamente.) Dentro da função, você pode determinar qual conjunto de parâmetros foi usado com a propriedade $ PsCmdlet.ParameterSetName. Por exemplo:
Em uma nota lateral relacionada, também há validação de parâmetro no PowerShell. Esse é um dos meus recursos favoritos do PowerShell e torna o código dentro de suas funções muito limpo. Existem inúmeras validações que você pode usar. Alguns exemplos são:
No primeiro exemplo, ValidatePattern aceita uma expressão regular que garante que o parâmetro fornecido corresponda ao que você está esperando. Caso contrário, é lançada uma exceção intuitiva, informando exatamente o que está errado. Portanto, nesse exemplo, 'Something' funcionaria bem, mas 'Summer' não passaria na validação.
ValidateRange garante que o valor do parâmetro esteja no intervalo esperado para um número inteiro. Portanto, 10 ou 99 funcionariam, mas 101 lançaria uma exceção.
Outro útil é o ValidateSet, que permite definir explicitamente uma matriz de valores aceitáveis. Se algo mais for inserido, uma exceção será lançada. Também existem outros, mas provavelmente o mais útil é o ValidateScript. Isso requer um bloco de script que deve ser avaliado como $ true, para que o céu seja o limite. Por exemplo:
Neste exemplo, temos a certeza não apenas de que $ Path existe, mas também de um arquivo (em oposição a um diretório) e de uma extensão .csv. ($ _ refere-se ao parâmetro, quando dentro do seu bloco de script.) Você também pode passar blocos de script com várias linhas muito maiores, se esse nível for necessário, ou usar vários blocos de script como eu fiz aqui. É extremamente útil e contribui para boas funções limpas e exceções intuitivas.
fonte
My_Function -NamedParamater "ParamValue"
o estilo de chamada de função. Esse é um padrão que mais códigos de script PS devem seguir para facilitar a leitura.Você chama funções do PowerShell sem parênteses e sem usar a vírgula como separador. Tente usar:
No PowerShell, a vírgula (,) é um operador de matriz, por exemplo
Ele define
$a
uma matriz com três valores.fonte
fonte
Se você é um desenvolvedor de C # / Java / C ++ / Ruby / Python / Escolha a linguagem deste século deste século e deseja chamar sua função com vírgulas, porque é isso que sempre fez, então precisa de algo como isso:
Agora ligue para:
e você verá
fonte
Se você não souber (ou se importar) com quantos argumentos estará passando para a função, também poderá usar uma abordagem muito simples como;
Código :
Isso imprimiria todos os argumentos. Por exemplo:
Resultado
Acho isso particularmente útil ao criar funções que usam comandos externos que podem ter muitos parâmetros diferentes (e opcionais), mas confiam no comando para fornecer feedback sobre erros de sintaxe etc.
Aqui está outro exemplo do mundo real (criando uma função para o comando tracert, que eu odeio ter que lembrar do nome truncado);
Código :
fonte
Se você tentar:
você obtém:
Então você vê que os parênteses separam os parâmetros
Se você tentar:
você obtém:
Agora você pode encontrar alguma utilidade imediata entre parênteses - um espaço não se tornará um separador para o próximo parâmetro - em vez disso, você tem uma função eval.
fonte
@
) antes de os paren principais, como esta matriz vazia:@()
; ou esta matriz com dois números:@(1, 2)
.Como essa é uma pergunta frequente, quero mencionar que uma função do PowerShell deve usar verbos aprovados ( Verbo-Substantivo como o nome da função). A parte do verbo do nome identifica a ação que o cmdlet executa. A parte substantiva do nome identifica a entidade na qual a ação é executada. Essa regra simplifica o uso de seus cmdlets para usuários avançados do PowerShell.
Além disso, você pode especificar coisas como se o parâmetro é obrigatório e a posição do parâmetro:
Para passar o parâmetro para a função, você pode usar a posição :
Ou você especifica o nome do parâmetro :
Você não usa parênteses como quando chama uma função em C #.
Eu recomendaria sempre passar os nomes dos parâmetros ao usar mais de um parâmetro, pois isso é mais legível .
fonte
Get-Node
cmdlet. Ficaria claro para nós que precisamos invocarGet-Node
, nãoRetrieve-Node
, nemReceive-Node
, nem .....Não sei o que você está fazendo com a função, mas veja a palavra-chave 'param'. É um pouco mais poderoso para passar parâmetros para uma função e a torna mais amigável ao usuário. Abaixo está um link para um artigo excessivamente complexo da Microsoft sobre o assunto. Não é tão complicado quanto o artigo faz parecer.
Uso de parâmetros
Além disso, aqui está um exemplo de uma pergunta neste site:
Confira.
fonte
fonte
Eu afirmei o seguinte anteriormente:
O problema comum é usar a forma singular
$arg
, que está incorreta. Deve sempre ser plural como$args
.O problema não é esse. De fato,
$arg
pode ser qualquer outra coisa. O problema era o uso da vírgula e dos parênteses.Eu executo o seguinte código que funcionou e a saída a seguir:
Código:
Teste "ABC" "DEF"
Resultado:
fonte
Esta é uma
params
declaração adequada .Consulte about_Functions_Advanced_Parameters .
E de fato funciona.
fonte
Você pode passar parâmetros em uma função como esta também:
fonte
Não o vejo mencionado aqui, mas dividir seus argumentos é uma alternativa útil e se torna especialmente útil se você estiver construindo os argumentos para um comando dinamicamente (ao contrário de usar
Invoke-Expression
). Você pode dividir com matrizes para argumentos posicionais e hashtables para argumentos nomeados. aqui estão alguns exemplos:Splat com matrizes (argumentos posicionais)
Conexão de teste com argumentos posicionais
Com matriz de splatting
Splat com Hashtable (argumentos nomeados)
Conexão de teste com argumentos nomeados
Com Hashtable Splatting
Argumentos posicionais e nomeados de Splat simultaneamente
Conexão de teste com argumentos posicionais e nomeados
Matriz de splatting e tabelas de hash juntas
fonte