Valor de retorno da função em PowerShell

desenvolvi uma função PowerShell que executa uma série de acções que envolvem provisionamento SharePoint locais de equipa. Em última análise, eu quero que a função retorne a URL do site provisionado como uma String então no final da minha função eu tenho o seguinte código:

$rs = $url.ToString();
return $rs;

o código que chama esta função parece:

$returnURL = MyFunction -param 1 ...
Estou à espera de uma corda, mas não é. Em vez disso, é um objeto do tipo de Sistema.Gestao.Automacao.Psmetod. Porquê? devolver esse tipo em vez de um tipo de corda?

 135
Author: Peter Mortensen, 2012-04-23

8 answers

PowerShell tem realmente uma semântica de retorno maluca - pelo menos quando visto de uma perspectiva de programação mais tradicional. Há duas ideias principais para entender:
  • Toda a saída é capturada e devolvida
  • a palavra-chave return indica apenas um ponto de saída lógico

Assim, os dois blocos de script que se seguem farão efectivamente a mesma coisa:

$a = "Hello, World"
return $a

 

$a = "Hello, World"
$a
return

A variável $a no segundo exemplo é deixada como saída no oleoduto e, como mencionado, toda a saída é devolvida. Na verdade, no segundo exemplo você poderia omitir o retorno inteiramente e você teria o mesmo comportamento (o retorno seria implícito como a função naturalmente completa e sai).

Sem mais da sua definição de função não posso dizer por que você está recebendo um objeto PSMethod. Meu palpite é que você provavelmente tem algo algumas linhas acima que não está sendo capturado e está sendo colocado no oleoduto de saída.

Também é vale a pena notar que você provavelmente não precisa desses pontos-e-vírgulas - a menos que esteja a aninhar várias expressões numa única linha.

Pode ler mais sobre a semântica de retorno napágina sobre a TechNet, ou invocando o comando {[[2]} da própria PowerShell.

 205
Author: Goyuix, 2012-04-23 21:01:56
Esta parte do PowerShell é provavelmente o aspecto mais estúpido. Qualquer saída externa gerada durante uma função irá poluir o resultado, às vezes não há saída e, em algumas condições, há alguma outra saída não planejada, além do seu valor de retorno planejado.

Então, o que eu faço é remover a atribuição da chamada de função original para que o resultado acabe no ecrã, e depois passar até que algo que eu não planeei aparece na janela do depurador (usando the PS ISE).

Mesmo coisas como reservar variáveis em âmbitos exteriores causam saída, como {[[0]} o que irritantemente cuspirá um falso para fora a menos que você o faça [boolean]$isEnabled = $false.

Outro bom é $someCollection.Add("thing") que cospe a nova contagem da colecção.

 35
Author: Luke Puplett, 2016-12-29 14:27:34
Com o PowerShell 5 Agora temos a capacidade de criar classes. Mudar a sua função para uma classe não só você pode digitá-la e retornar só irá devolver o objeto imediatamente anterior a ela. Aqui está um exemplo muito simples.
class test_class{
    [int]return_what() {
        $a = "Hello World"
        return 808979
    }
}
$tc = New-Object -TypeName test_class
$tc.return_what()

Se esta fosse uma função, o resultado esperado seria

Hello World
808979
Mas como Classe A única coisa devolvida é um INT 808979. Uma classe é mais ou menos como uma garantia de que só vai devolver o tipo declarado ou nulo.
 23
Author: DaSmokeDog, 2017-03-12 02:46:34
Como resultado, tenho devolvido o último objecto da matriz que recuperamos da função... não é uma boa solução, mas é melhor do que nada.
someFunction {
   $a = "hello"
   "Function is running"
   return $a
}

$b = someFunction
$b = $b[($b.count - 1)]  # or 
$b = $b[-1]              # simpler
 20
Author: Jonesy, 2016-05-17 06:12:51
{[[2]} eu passo em torno de um simples objeto Hashtable com um único membro do resultado para evitar a loucura de Retorno Como eu também quero sair para o console. Actua através do pass by reference.
function sample-loop($returnObj) {
  for($i = 0; $i -lt 10; $i++) {
    write-host "loop counter: $i"
    $returnObj.result++
  }
}

function main-sample() {
  $countObj = @{ result = 0 }
  sample-loop -returnObj $countObj
  write-host "_____________"
  write-host "Total = " ($countObj.result)
}

main-sample

Você pode ver o uso real de exemplo no meu projecto GitHub unpackTunes

 5
Author: What Would Be Cool, 2015-08-23 23:27:31
É difícil dizer sem olhar para o código. Certifique-se de que sua função não retorna mais do que um objeto e que você captura quaisquer resultados feitos de outras chamadas. O que você recebe para:
@($returnURL).count
De qualquer forma, duas sugestões:

Molda o objecto para o texto:

...
return [string]$rs

Ou apenas enclausurá - lo entre aspas, tal como acima, mas mais curto para o tipo:

...
return "$rs"
 4
Author: Shay Levy, 2012-04-23 21:02:33
A descrição do Luke da função resulta nestes cenários. Apenas desejo entender a causa raiz e a equipe de Produto PowerShell faria algo sobre o comportamento, parece ser bastante comum e tem custo ser muito tempo de depuração.

Para contornar esta questão, tenho usado variáveis globais em vez de retornar e usar o valor da chamada de função.

Aqui está outro tópico sobre o uso de variáveis globais: a definir um PowerShell variable from a function where the global variable name is a variable passed to the function
 4
Author: Ted B., 2017-05-23 11:47:16

O seguinte simplesmente devolve 4 como resposta. Quando você substitui as expressões Adicionar para strings, ele retorna o primeiro string.

Function StartingMain {
  $a = 1 + 3
  $b = 2 + 5
  $c = 3 + 7
  Return $a
}
Function StartingEnd($b) {
  Write-Host $b
}
StartingEnd(StartingMain)

Isto também pode ser feito para um array. O exemplo abaixo irá retornar "texto 2"

Function StartingMain {
  $a = ,@("Text 1","Text 2","Text 3")
  Return $a
}
Function StartingEnd($b) {
  Write-Host $b[1]
}
StartingEnd(StartingMain)

Note que você tem que chamar a função abaixo da função em si, caso contrário, a primeira vez que ela executar ele irá retornar um erro que ele não sabe o que "StartingMain" é.

Espero que ajude.
 3
Author: Edwin, 2017-01-13 00:41:35