usar tutorial script como commands comandos powershell

script - powershell tutorial



Valor de retorno de la funciĆ³n en PowerShell (8)

Desarrollé una función de PowerShell que realiza una serie de acciones relacionadas con el aprovisionamiento de sitios del equipo de SharePoint . En última instancia, quiero que la función devuelva la URL del sitio aprovisionado como una cadena, por lo que al final de mi función tengo el siguiente código:

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

El código que llama a esta función se ve así:

$returnURL = MyFunction -param 1 ...

Así que estoy esperando un String, pero no es así. En cambio, es un objeto de tipo System.Management.Automation.PSMethod. ¿Por qué está volviendo ese tipo en lugar de un tipo de Cadena?


Como solución alternativa he estado devolviendo el último objeto de la matriz que obtuviste de la función ... no es una gran solución, pero es mejor que nada:

someFunction { $a = "hello" "Function is running" return $a } $b = someFunction $b = $b[($b.count - 1)] # or $b = $b[-1] # simpler


Con PowerShell 5 ahora tenemos la capacidad de crear clases. Al cambiar su función a una clase, no solo puede escribirla y devolverla SÓLO devolverá el objeto inmediatamente anterior. Aquí hay un ejemplo muy simple.

class test_class{ [int]return_what() { $a = "Hello World" return 808979 } } $tc = New-Object -TypeName test_class $tc.return_what()

Si esta fuera una función, el resultado esperado sería

Hello World 808979

pero como clase, lo único que se devuelve es un INT 808979. Una clase es como una garantía de que solo devolverá el tipo declarado o nulo.


Es difícil de decir sin mirar el código. Asegúrese de que su función no devuelva más de un objeto y que capture los resultados obtenidos de otras llamadas. ¿Qué obtienes por:

@($returnURL).count

De todos modos, dos sugerencias:

Emitir el objeto a la cadena:

... return [string]$rs

O simplemente enciérrelo entre comillas dobles, igual que arriba pero más corto para escribir:

... return "$rs"


Esta parte de PowerShell es probablemente el aspecto más estúpido. Cualquier salida extraña generada durante una función contaminará el resultado, a veces no hay salida y luego, en algunas condiciones, hay otra salida no planificada, además de su valor de retorno planificado.

Entonces, lo que hago es eliminar la asignación de la llamada de función original para que la salida termine en la pantalla, y luego paso hasta que algo que no planifiqué aparece en la ventana del depurador (usando el PS ISE).

Incluso cosas como reservar variables en ámbitos externos causan resultados, como [boolean]$isEnabled que [boolean]$isEnabled molestamente un False out a menos que lo haga [boolean]$isEnabled = $false .

Otra buena es $someCollection.Add("thing") que escupe el nuevo conteo de la colección.


La descripción de Lucas de los resultados de la función en estos escenarios parece estar en lo cierto. Solo deseo entender la causa raíz y el equipo de producto de PowerShell haría algo acerca del comportamiento, parece ser bastante común y ha costado demasiado tiempo de depuración.

Para evitar este problema, he estado usando variables globales en lugar de devolver y usar el valor de la llamada a la función.

Aquí hay otro hilo sobre el uso de las variables globales: Establecer una variable global de PowerShell a partir de una función donde el nombre de la variable global es una variable que se pasa a la función


Lo siguiente simplemente devuelve 4 como respuesta. Cuando reemplaza las expresiones de agregar cadenas, devuelve la primera cadena.

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

Esto también se puede hacer para una matriz. El siguiente ejemplo devolverá "Texto 2"

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

Tenga en cuenta que debe llamar a la función que se encuentra debajo de la función, de lo contrario la primera vez que la ejecute devolverá un error que no sabe qué es "StartingMain".

Espero que ayude


Paso alrededor de un simple objeto Hashtable con un solo miembro de resultado para evitar la locura de retorno ya que también quiero enviar a la consola. Actúa a través del pase por referencia.

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

Puedes ver ejemplos de uso real en mi proyecto GitHub para descomprimirTunes


PowerShell tiene una semántica de retorno realmente absurda, al menos cuando se ve desde una perspectiva de programación más tradicional. Hay dos ideas principales para entender:

  • Toda la salida se captura y se devuelve
  • La palabra clave de retorno realmente solo indica un punto de salida lógica

Por lo tanto, los siguientes dos bloques de scripts harán exactamente lo mismo:

$a = "Hello, World" return $a

$a = "Hello, World" $a return

La variable $ a en el segundo ejemplo se deja como salida en la canalización y, como se mencionó, se devuelve todo el resultado. De hecho, en el segundo ejemplo, podría omitir la devolución por completo y obtendría el mismo comportamiento (la devolución estaría implícita ya que la función se completa y se cierra naturalmente).

Sin más de su definición de función, no puedo decir por qué está recibiendo un objeto PSMethod. Mi suposición es que probablemente tengas algo que no está siendo capturado y está siendo colocado en la tubería de salida.

También vale la pena señalar que probablemente no necesite esos puntos y comas, a menos que anide múltiples expresiones en una sola línea.

Puede leer más sobre la semántica de retorno en la página about_Return en TechNet, o al invocar el comando help return de PowerShell.