Eu desenvolvi uma função do PowerShell que executa várias ações que envolvem o provisionamento de sites da Equipe do SharePoint . Por fim, quero que a função retorne a URL do site provisionado como uma String, portanto, no final da minha função, tenho o seguinte código:
$rs = $url.ToString();
return $rs;
O código que chama essa função se parece com:
$returnURL = MyFunction -param 1 ...
Então, eu estou esperando uma String, mas não é. Em vez disso, é um objeto do tipo System.Management.Automation.PSMethod. Por que ele está retornando esse tipo em vez de um tipo String?
powershell
ChiliYago
fonte
fonte
Respostas:
O PowerShell tem semântica de retorno realmente maluca - pelo menos quando vista de uma perspectiva de programação mais tradicional. Há duas idéias principais para você entender:
Portanto, os dois blocos de script a seguir farão exatamente a mesma coisa:
A variável $ a no segundo exemplo é deixada como saída no pipeline e, como mencionado, toda a saída é retornada. De fato, no segundo exemplo, você poderia omitir completamente o retorno e obteria o mesmo comportamento (o retorno seria implícito, pois a função naturalmente termina e sai).
Sem mais definições de função, não sei dizer por que você está recebendo um objeto PSMethod. Meu palpite é que você provavelmente tem algo que algumas linhas acima não estão sendo capturadas e estão sendo colocadas no pipeline de saída.
Também é importante notar que você provavelmente não precisa desses pontos e vírgulas - a menos que esteja aninhando várias expressões em uma única linha.
Você pode ler mais sobre a semântica de retorno na página about_Return no TechNet ou chamando o
help return
comando do próprio PowerShell.fonte
write-debug
depois de definir a variável$DebugPreference = "Continue"
em vez de"SilentlyContinue"
echo
foi o problema para mim! Esse pequeno ponto lateral é muito, muito importante. Eu estava retornando uma hashtable, seguindo todo o resto, mas ainda assim o valor de retorno não era o que eu esperava. Removidoecho
e funcionou como um encanto.Essa parte do PowerShell é provavelmente o aspecto mais estúpido. Qualquer saída estranha gerada durante uma função poluirá o resultado. Às vezes, não há saída e, em algumas condições, há outra saída não planejada, além do valor de retorno planejado.
Portanto, removo a atribuição da chamada de função original, para que a saída acabe na tela e depois avance até que algo que eu não planejei saia na janela do depurador (usando o PowerShell ISE ).
Mesmo coisas como reservar variáveis em escopos externos causam saída, como a
[boolean]$isEnabled
que irrita irritantemente um False, a menos que você o faça[boolean]$isEnabled = $false
.Outra boa é
$someCollection.Add("thing")
que cospe a nova contagem de coleção.fonte
[boolean]$a
no PowerShell não declara a variável $ a. Você pode confirmar isso seguindo essa linha com a linha$a.gettype()
e comparar essa saída com quando você declara e inicializa com a sequência$a = [boolean]$false
.>
e<
já são usados para redirecionamento de fluxo de E / S para / de arquivos.>=
escreve stdout em um arquivo chamado=
.Com o PowerShell 5, agora temos a capacidade de criar classes. Mude sua função para uma classe, e return retornará apenas o objeto imediatamente anterior a ela. Aqui está um exemplo muito simples.
Se isso fosse uma função, a saída esperada seria
mas como uma classe, a única coisa retornada é o número inteiro 808979. Uma classe é como uma garantia de que ela retornará apenas o tipo declarado ou nulo.
fonte
static
métodos. Levando à sintaxe[test_class]::return_what()
return 808979
, função ou não.Write-Output
? Não é a saída do "console" mencionada aqui, é a saída da função / cmdlet. Se você quiser jogar o material no console existemWrite-Verbose
,Write-Host
eWrite-Error
funções, entre outros. Basicamente,Write-Output
está mais próximo dareturn
semântica, do que de um procedimento de saída do console. Não abuse, useWrite-Verbose
para verbosidade, é para isso que serve.Como solução alternativa, eu retornei o último objeto da matriz que você retorna da função ... Não é uma ótima solução, mas é melhor que nada:
Em suma, uma maneira mais simples de escrever a mesma coisa poderia ser:
fonte
$b = $b[-1]
seria uma maneira mais simples de obter o último elemento ou a matriz, mas ainda mais simples seria simplesmente não gerar valores que você não deseja.write-host
para produzi-las diretamente.Eu passo em torno de um objeto Hashtable simples com um único membro de resultado para evitar a loucura de retorno, pois também quero enviar para o console. Atua através de passagem por referência.
Você pode ver exemplos reais de uso no meu projeto GitHub, unpackTunes .
fonte
É difícil dizer sem olhar para o código. Verifique se sua função não retorna mais de um objeto e se captura todos os resultados obtidos com outras chamadas. O que você ganha por:
Enfim, duas sugestões:
Transmitir o objeto para string:
Ou apenas coloque-o entre aspas duplas, igual ao anterior, mas mais curto para digitar:
fonte
"$rs"
- oreturn
necessário apenas ao retornar cedo da função. Deixar de lado o retorno é o melhor idioma do PowerShell.A descrição de Lucas da função resulta nesses cenários parece correta. Eu só quero entender a causa raiz e a equipe do produto PowerShell faria algo sobre o comportamento. Parece ser bastante comum e me custou muito tempo de depuração.
Para contornar esse problema, eu tenho usado variáveis globais em vez de retornar e usar o valor da chamada de função.
Aqui está outra pergunta sobre o uso de variáveis globais: Definindo uma variável global do PowerShell a partir de uma função em que o nome da variável global é uma variável passada para a função
fonte
O seguinte simplesmente retorna 4 como resposta. Quando você substitui as expressões add para strings, ele retorna a primeira string.
Isso também pode ser feito para uma matriz. O exemplo abaixo retornará "Texto 2"
Observe que você precisa chamar a função abaixo da própria função. Caso contrário, na primeira execução, ele retornará um erro que não sabe o que é "StartingMain".
fonte
As respostas existentes estão corretas, mas às vezes você não está retornando algo explicitamente com a
Write-Output
ou areturn
, mas há algum valor misterioso nos resultados da função. Pode ser a saída de uma função embutida comoNew-Item
Todo esse ruído extra da criação do diretório está sendo coletado e emitido na saída. A maneira mais fácil de mitigar isso é adicionar
| Out-Null
ao final daNew-Item
instrução, ou você pode atribuir o resultado a uma variável e simplesmente não usá-la. Ficaria assim ...New-Item
é provavelmente o mais famoso deles, mas outros incluem todos osStringBuilder.Append*()
métodos, bem como oSqlDataAdapter.Fill()
método.fonte