validate receive parameter mandatory help powershell parameters cmdlets cmdlet

mandatory - powershell receive parameters



Cómo usar correctamente los parámetros-verbose y-debug en cmdlet personalizado (8)

Con riesgo de revivir y viejo hilo. Aquí está mi solución.

function DoStuff { [CmdletBinding()] param () BEGIN { $CMDOUT=@{ Verbose=If ($PSBoundParameters.Verbose -eq $true) { $true } else { $false }; Debug=If ($PSBoundParameters.Debug -eq $true) { $true } else { $false } } } # BEGIN ENDS PROCESS { New-Item Example -ItemType Directory @CMDOUT } # PROCESS ENDS END { } #END ENDS }

Lo que hace diferente de los otros ejemplos es que contendrá "-Verbose: $ false" o "-Debug: $ false". Solo establecerá -Verbose / -Debug en $ true si usa lo siguiente:

DoStuff -Verbose DoStuff -Verbose:$true DoStuff -Debug DoStuff -Debug:$true

Por defecto, cualquier función nombrada que tenga el atributo [CmdletBinding ()] acepta los parámetros -debug y -verbose (y algunos otros) y tiene predefinidas las variables $ debug y $ verbose. Lo que estoy tratando de averiguar es cómo pasarlos a otros cmdlet que se llaman dentro de la función.

Digamos que tengo un cmdlet como este:

function DoStuff() { [CmdletBinding()] PROCESS { new-item Test -type Directory } }

if -debug or -debug se pasó a mi función Quiero pasar ese indicador en el cmdlet de new-item . ¿Cuál es el patrón correcto para hacer esto?


Creo que esta es la forma más fácil:

Function Test { [CmdletBinding()] Param ( [parameter(Mandatory=$False)] [String]$Message ) Write-Host "This is INFO message" if ($PSBoundParameters.debug) { Write-Host -fore cyan "This is DEBUG message" } if ($PSBoundParameters.verbose) { Write-Host -fore green "This is VERBOSE message" } "" } Test -Verbose -Debug


La mejor manera de hacerlo es configurando $VerbosePreference . Esto habilitará el nivel detallado para todo el script. No olvide deshabilitarlo al final del script.

Function test { [CmdletBinding()] param( $param1) if($psBoundParameters[''verbose'']) { $VerbosePreference = "Continue" Write-verbose " Verbose mode is on" } else { $VerbosePreference = "SilentlyContinue" Write-verbose " Verbose mode is Off" } <<your code>> }


No hay necesidad. PowerShell ya lo hace como lo demuestra el siguiente código.

function f { [cmdletbinding()]Param() "f is called" Write-Debug Debug Write-Verbose Verbose } function g { [cmdletbinding()]Param() "g is called" f } g -Debug -Verbose

El resultado es

g is called f is called DEBUG: Debug VERBOSE: Verbose

No se hace tan directo como pasar -Debug al siguiente cmdlet sin embargo. Se realiza a través de las variables $ DebugPreference y $ VerbrosePreference. Write-Debug y Write-Verbose actúan como usted esperaría, pero si quiere hacer algo diferente con debug o verbose, puede leer here cómo verificarlo usted mismo.


Puede construir una nueva tabla hash basada en los parámetros de corrección de errores o detallados y luego colocarla en el comando interno. Si solo especifica switches (y no está pasando un interruptor falso, como $ debug: $ false), simplemente puede verificar la existencia de depuración o verbose:

function DoStuff() { [CmdletBinding()] PROCESS { $HT=@{Verbose=$PSBoundParameters.ContainsKey''Verbose'');Debug=$PSBoundParameters.ContainsKey(''Debug'')} new-item Test -type Directory @HT } }

Si desea pasar el valor del parámetro, es más complicado, pero se puede hacer con:

function DoStuff { [CmdletBinding()] param() PROCESS { $v,$d = $null if(!$PSBoundParameters.TryGetValue(''Verbose'',[ref]$v)){$v=$false} if(!$PSBoundParameters.TryGetValue(''Debug'',[ref]$d)){$d=$false} $HT=@{Verbose=$v;Debug=$d} new-item Test -type Directory @HT } }


Puede establecer VerbosePreference como una variable global al iniciar el script y luego verificar la variable global en su cmdlet personalizado.

Guión:

$global:VerbosePreference = $VerbosePreference Your-CmdLet

Your-CmdLet:

if ($global:VerbosePreference -eq ''Continue'') { # verbose code }

La comprobación explícita de ''Continuar'' permite que el guión sea igual a -verbose:$false cuando se llama a CmdLet desde un guión que no establece la variable global (en cuyo caso es $null )


Quizás suene extraño, pero no hay una manera fácil para que un cmdlet conozca su modo detallado o de depuración. Echa un vistazo a la pregunta relacionada:

¿Cómo sabe un cmdlet cuándo debería llamar realmente a WriteVerbose ()?

Una opción no perfecta pero prácticamente razonable es introducir sus propios parámetros de cmdlet (por ejemplo, $MyVerbose , $MyDebug ) y usarlos explícitamente en el código.

function DoStuff { [CmdletBinding()] param ( # unfortunately, we cannot use Verbose name with CmdletBinding [switch]$MyVerbose ) process { if ($MyVerbose) { # do verbose stuff } # pass $MyVerbose in the cmdlet explicitly New-Item Test -Type Directory -Verbose:$MyVerbose } } DoStuff -MyVerbose

ACTUALIZAR

Cuando solo necesitamos un conmutador (no, por ejemplo, un valor de nivel de verbosidad), entonces el enfoque con $PSBoundParameters es tal vez mejor que los parámetros adicionales propuestos anteriormente:

function DoStuff { [CmdletBinding()] param() process { if ($PSBoundParameters[''Verbose'']) { # do verbose stuff } New-Item Test -Type Directory -Verbose:($PSBoundParameters[''Verbose''] -eq $true) } } DoStuff -Verbose

De todos modos, no es perfecto. Si hay mejores soluciones, me gustaría conocerlas yo mismo.


$PSBoundParameters no es lo que estás buscando. El uso del [CmdletBinding()] permite el uso de $PSCmdlet dentro del script, además de proporcionar un indicador detallado. De hecho, es el mismo Verbose que se supone que debes usar.

A través de [CmdletBinding()] , puede acceder a los parámetros enlazados a través de $PSCmdlet.MyInvocation.BoundParameters . Aquí hay una función que usa CmdletBinding y simplemente ingresa una solicitud anidada inmediatamente para examinar las variables disponibles dentro del alcance de la función.

PS D:/> function hi { [CmdletBinding()]param([string] $Salutation) $host.EnterNestedPrompt() }; hi -Salutation Yo -Verbose PS D:/>>> $PSBoundParameters ____________________________________________________________________________________________________ PS D:/>>> $PSCmdlet.MyInvocation.BoundParameters Key Value --- ----- Salutation Yo Verbose True

Entonces en tu ejemplo, querrías lo siguiente:

function DoStuff ` { [CmdletBinding()] param () process { new-item Test -type Directory ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true) } }

Esto cubre -Verbose, -Verbose: $ false, -Verbose: $ true, y el caso donde el cambio no está presente en absoluto.