about_Debuggers

Descripción breve

Describe el depurador de PowerShell.

Descripción larga

La depuración es el proceso de examinar un script mientras se ejecuta para identificar y corregir errores en las instrucciones del script. El depurador de PowerShell puede ayudarle a examinar e identificar errores e ineficiencias en los scripts, funciones, comandos, configuraciones o expresiones de Desired State Configuration (DSC) de PowerShell.

A partir de PowerShell 5.0, el depurador de PowerShell se ha actualizado para depurar scripts, funciones, comandos, configuraciones o expresiones que se ejecutan en la consola o en el entorno de scripting integrado (ISE) de Windows PowerShell en equipos remotos.

Nota:

Windows PowerShell ISE solo admite Windows PowerShell. Para PowerShell 6 y versiones posteriores, debe usar Visual Studio Code con la extensión para PowerShell. Para obtener más información, consulte Depuración con Visual Studio Code.

Cmdlets del depurador

El depurador de PowerShell incluye el siguiente conjunto de cmdlets:

  • Set-PSBreakpoint: establece puntos de interrupción en líneas, variables y comandos.
  • Get-PSBreakpoint: obtiene puntos de interrupción en la sesión actual.
  • Disable-PSBreakpoint: desactiva los puntos de interrupción en la sesión actual.
  • Enable-PSBreakpoint: vuelve a habilitar los puntos de interrupción en la sesión actual.
  • Remove-PSBreakpoint: elimina puntos de interrupción de la sesión actual.
  • Get-PSCallStack: muestra la pila de llamadas actual.

Inicio y detención del depurador

Para iniciar el depurador, establezca uno o varios puntos de interrupción y ejecute el script, el comando o la función que desea depurar.

Cuando se llega a un punto de interrupción, la ejecución se detiene y el control se convierte en el depurador.

Para detener el depurador, ejecute el script, el comando o la función hasta que se complete. O bien, escriba stop o t.

Comandos del depurador

Cuando use el depurador en la consola de PowerShell, use los siguientes comandos para controlar la ejecución. En Windows PowerShell ISE, use comandos en el menú Depurar.

Nota:

Para obtener información sobre cómo usar el depurador en otras aplicaciones host, consulte la documentación de la aplicación host.

  • s, : ejecuta la siguiente instrucción y, a continuación, StepIntose detiene.

  • v, StepOver: ejecuta la instrucción siguiente, pero omite las funciones y las invocaciones. Las instrucciones omitidas se ejecutan, pero no se depuran paso a paso.

  • Ctrl+Break: (Interrumpir todo en ISE) Divide en un script en ejecución dentro de la consola de PowerShell o Windows PowerShell ISE. Tenga en cuenta que Ctrl+Interrumpir en Windows PowerShell 2.0, 3.0 y 4.0 cierra el programa. Interrumpir todo funciona tanto en scripts locales como remotos en ejecución interactiva.

  • o, StepOut: realiza pasos fuera de la función actual; subir un nivel si está anidado. Si está en el cuerpo principal, continúa hasta el final o el siguiente punto de interrupción. Las instrucciones omitidas se ejecutan, pero no se depuran paso a paso.

  • c, Continue: continúa ejecutándose hasta que se complete el script o hasta que se alcance el siguiente punto de interrupción. Las instrucciones omitidas se ejecutan, pero no se depuran paso a paso.

  • l, List: muestra la parte del script que se está ejecutando. De forma predeterminada, muestra la línea actual, cinco líneas anteriores y 10 líneas posteriores. Para continuar enumerando el script, presione ENTRAR.

  • l <m>, List: muestra 16 líneas del script a partir del número de línea especificado por <m>.

  • l <m> <n>, List: muestra <n> las líneas del script, empezando por el número de línea especificado por <m>.

  • q, , StopExit: deja de ejecutar el script y sale del depurador. Si está depurando un trabajo mediante la ejecución del Debug-Job cmdlet , el Exit comando desasocia el depurador y permite que el trabajo continúe ejecutándose.

  • k, Get-PsCallStack: muestra la pila de llamadas actual.

  • <Enter>: repite el último comando si era Step (s), StepOver (v) o List (l). De lo contrario, representa una acción de envío.

  • ?, h: muestra la Ayuda del comando del depurador.

Para salir del depurador, puede usar Stop (q).

A partir de PowerShell 5.0, puede ejecutar el comando Exit para salir de una sesión de depuración anidada que inició ejecutando Debug-Job o Debug-Runspace.

Con estos comandos del depurador, puede ejecutar un script, detenerlo en un punto de preocupación, examinar los valores de las variables y el estado del sistema y seguir ejecutando el script hasta que haya identificado un problema.

Nota:

Si entra en una instrucción con un operador de redireccionamiento, como >, el depurador de PowerShell realiza pasos en todas las instrucciones restantes del script.

Mostrar los valores de las variables de script

Mientras se encuentra en el depurador, también puede escribir comandos, mostrar el valor de las variables, usar cmdlets y ejecutar scripts en la línea de comandos. Puede mostrar el valor actual de todas las variables del script que se está depurando, excepto las siguientes variables automáticas:

$_
$Args
$Input
$MyInvocation
$PSBoundParameters

Cuando se muestra el valor de cualquiera de estas variables, se obtiene el valor de esa variable para una canalización interna que usa el depurador, no el valor de la variable en el script.

Para mostrar el valor de estas variables para el script que se está depurando, agregue líneas al script para guardar estos valores en una nueva variable. Establezca el punto de interrupción después de estas nuevas líneas. A continuación, puede mostrar el valor de la nueva variable.

Por ejemplo,

$scriptArgs = $Args
$scriptname = $MyInvocation.PSCommandPath

Entorno del depurador

Cuando llegue a un punto de interrupción, escriba el entorno del depurador. El símbolo del sistema cambia para que comience por "[DBG]:". Además, en algunas aplicaciones host, como la consola de PowerShell, se abre una solicitud anidada para la depuración. Puede detectar el mensaje anidado repitiendo caracteres mayores que (ASCII 62) que aparecen en el símbolo del sistema.

Para obtener más información sobre cómo personalizar el mensaje, consulte about_Prompts.

Puede encontrar el nivel de anidamiento mediante la $NestedPromptLevel variable automática. La variable automática, $PSDebugContext, se define en el ámbito local. Puede usar la presencia de la $PSDebugContext variable para determinar si se ejecuta en el depurador.

Por ejemplo:

if ($PSDebugContext) {"Debugging"} else {"Not Debugging"}

Puede usar el valor de la variable en la $PSDebugContext depuración.

[DBG]: PS>>> $PSDebugContext.InvocationInfo

Name   CommandLineParameters  UnboundArguments  Location
----   ---------------------  ----------------  --------
=      {}                     {}                C:\ps-test\vote.ps1 (1)

Depuración y ámbito

La separación en el depurador no cambia el ámbito en el que está funcionando, pero cuando se llega a un punto de interrupción en un script, se mueve al ámbito del script. El ámbito del script es un elemento secundario del ámbito en el que ejecutó el depurador.

Para buscar las variables y alias que se definen en el ámbito del script, use el parámetro Scope de los Get-Alias cmdlets o Get-Variable .

Por ejemplo, el siguiente comando obtiene las variables en el ámbito local (script):

Get-Variable -scope 0

Esta es una manera útil de ver solo las variables que definió en el script y que definió durante la depuración.

Depuración en la línea de comandos

Al establecer un punto de interrupción variable o un punto de interrupción de comando, puede establecer el punto de interrupción solo en un archivo de script. Sin embargo, de forma predeterminada, el punto de interrupción se establece en todo lo que se ejecuta en la sesión actual.

Por ejemplo, si establece un punto de interrupción en la $name variable, el depurador se interrumpe en cualquier $name variable de cualquier script, comando, función, cmdlet de script o expresión que ejecute hasta que deshabilite o quite el punto de interrupción.

Esto le permite depurar los scripts en un contexto más realista en el que podrían verse afectados por funciones, variables y otros scripts en la sesión y en el perfil del usuario.

Los puntos de interrupción de línea son específicos de los archivos de script, por lo que solo se establecen en archivos de script.

Funciones de depuración

Cuando se establece un punto de interrupción en una función que tiene beginsecciones , processy end , el depurador se interrumpe en la primera línea de cada sección.

Por ejemplo:

function test-cmdlet {
    begin {
        write-output "Begin"
    }
    process {
        write-output "Process"
    }
    end {
        write-output "End"
    }
}

C:\PS> Set-PSBreakpoint -command test-cmdlet

C:\PS> test-cmdlet

Begin
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:test-cmdlet'

test-cmdlet

[DBG]: C:\PS> c
Process
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:test-cmdlet'

test-cmdlet

[DBG]: C:\PS> c
End
Entering debug mode. Use h or ? for help.

Hit Command breakpoint on 'prompt:test-cmdlet'

test-cmdlet

[DBG]: C:\PS>

Depuración de scripts remotos

Puede ejecutar Enter-PSSession para iniciar una sesión interactiva de PowerShell remota en la que puede establecer puntos de interrupción y depurar archivos de script y comandos en el equipo remoto. Enter-PSSession permite volver a conectar una sesión desconectada que ejecuta un script o comando en un equipo remoto. Si el script en ejecución alcanza un punto de interrupción, la sesión de cliente inicia automáticamente el depurador. Si la sesión desconectada que ejecuta un script ya ha alcanzado un punto de interrupción, Enter-PSSession inicia automáticamente el depurador de línea de comandos cuando se vuelve a conectar a la sesión.

En el ejemplo siguiente se muestra cómo funciona esto. Los puntos de interrupción se han establecido en las líneas 6, 11, 22 y 25 del script. Cuando se inicia el depurador, hay dos cambios de identificación en el símbolo del sistema:

  • Nombre del equipo en el que se ejecuta la sesión
  • Mensaje de DBG que le permite saber que está en modo de depuración
Enter-PSSession -Cn localhost
[localhost]: PS C:\psscripts> Set-PSBreakpoint .\ttest19.ps1 6,11,22,25

ID Script          Line     Command          Variable          Action
-- ------          ----     -------          --------          ------
0 ttest19.ps1          6
1 ttest19.ps1          11
2 ttest19.ps1          22
3 ttest19.ps1          25

[localhost]: PS C:\psscripts> .\ttest19.ps1
Hit Line breakpoint on 'C:\psscripts\ttest19.ps1:11'

At C:\psscripts\ttest19.ps1:11 char:1
+ $winRMName = "WinRM"
# + ~

[localhost]: [DBG]: PS C:\psscripts>> list

6:      1..5 | foreach { sleep 1; Write-Output "hello2day $_" }
7:  }
# 8:

9:  $count = 10
10:  $psName = "PowerShell"
11:* $winRMName = "WinRM"
12:  $myVar = 102
# 13:

14:  for ($i=0; $i -lt $count; $i++)
15:  {
16:      sleep 1
17:      Write-Output "Loop iteration is: $i"
18:      Write-Output "MyVar is $myVar"
# 19:

20:      hello2day
# 21:


[localhost]: [DBG]: PS C:\psscripts>> stepover
At C:\psscripts\ttest19.ps1:12 char:1
+ $myVar = 102
# + ~

[localhost]: [DBG]: PS C:\psscripts>> quit
[localhost]: PS C:\psscripts> Exit-PSSession
PS C:\psscripts>

Ejemplos

Este script de prueba detecta la versión de PowerShell y muestra un mensaje adecuado para la versión. Incluye una función, una llamada a función y una variable.

El siguiente comando muestra el contenido del archivo de script de prueba:

PS C:\PS-test>  Get-Content test.ps1

function psversion {
  "PowerShell " + $PSVersionTable.PSVersion
  if ($PSVersionTable.PSVersion.Major -lt 7) {
    "Upgrade to PowerShell 7!"
  }
  else {
    "Have you run a background job today (start-job)?"
  }
}

$scriptName = $MyInvocation.PSCommandPath
psversion
"Done $scriptName."

Para empezar, establezca un punto de interrupción en un punto de interés en el script, como una línea, un comando, una variable o una función.

Empiece por crear un punto de interrupción de línea en la primera línea del script Test.ps1 en el directorio actual.

PS C:\ps-test> Set-PSBreakpoint -line 1 -script test.ps1

El comando devuelve un objeto System.Management.Automation.LineBreakpoint .

Column     : 0
Line       : 1
Action     :
Enabled    : True
HitCount   : 0
Id         : 0
Script     : C:\ps-test\test.ps1
ScriptName : C:\ps-test\test.ps1

Ahora, inicie el script.

PS C:\ps-test> .\test.ps1

Cuando el script alcanza el primer punto de interrupción, el mensaje de punto de interrupción indica que el depurador está activo. Describe el punto de interrupción y muestra una vista previa de la primera línea del script, que es una declaración de función. El símbolo del sistema también cambia para indicar que el depurador tiene control.

La línea de vista previa incluye el nombre del script y el número de línea del comando en vista previa.

Entering debug mode. Use h or ? for help.

Hit Line breakpoint on 'C:\ps-test\test.ps1:1'

test.ps1:1   function psversion {
DBG>

Use el comando Step (s) para ejecutar la primera instrucción en el script y para obtener una vista previa de la siguiente instrucción. La siguiente instrucción usa la $MyInvocation variable automática para establecer el valor de la $scriptName variable en la ruta de acceso y el nombre de archivo del archivo de script.

DBG> s
test.ps1:11  $scriptName = $MyInvocation.PSCommandPath

En este punto, la $scriptName variable no se rellena, pero puede comprobar el valor de la variable mostrando su valor. En este caso, el valor es $null.

DBG> $scriptname
DBG>

Use otro Step comando (s) para ejecutar la instrucción actual y para obtener una vista previa de la siguiente instrucción en el script. La siguiente instrucción llama a la psversion función .

DBG> s
test.ps1:12  psversion

En este punto, la $scriptName variable se rellena, pero se comprueba el valor de la variable mostrando su valor. En este caso, el valor se establece en la ruta de acceso del script.

DBG> $scriptName
C:\ps-test\test.ps1

Use otro comando Step para ejecutar la llamada de función. Presione ENTRAR o escriba "s" para Paso.

DBG> s
test.ps1:2       "PowerShell " + $PSVersionTable.PSVersion

El mensaje de depuración incluye una vista previa de la instrucción en la función . Para ejecutar esta instrucción y obtener una vista previa de la siguiente instrucción de la función, puede usar un Step comando . Pero, en este caso, use un comando StepOut (o). Completa la ejecución de la función (a menos que llegue a un punto de interrupción) y los pasos a la siguiente instrucción del script.

DBG> o
Windows PowerShell 2.0
Have you run a background job today (start-job)?
test.ps1:13  "Done $scriptName"

Dado que estamos en la última instrucción del script, los comandos Step, StepOut y Continue tienen el mismo efecto. En este caso, use StepOut (o).

Done C:\ps-test\test.ps1
PS C:\ps-test>

El comando StepOut ejecuta el último comando. El símbolo del sistema estándar indica que el depurador ha salido y devuelto el control al procesador de comandos.

Ahora, vuelva a ejecutar el depurador. En primer lugar, para eliminar el punto de interrupción actual, use los Get-PsBreakpoint cmdlets y Remove-PsBreakpoint . (Si cree que podría reutilizar el punto de interrupción, use el Disable-PsBreakpoint cmdlet en lugar de Remove-PsBreakpoint.

PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint

Este comando se puede abreviar como:

PS C:\ps-test> gbp | rbp

O bien, ejecute el comando escribiendo una función, como la siguiente función:

function delbr { gbp | rbp }

Ahora, cree un punto de interrupción en la $scriptname variable .

PS C:\ps-test> Set-PSBreakpoint -variable scriptname -script test.ps1

Puede abreviar el comando como:

PS C:\ps-test> sbp -v scriptname -s test.ps1

Ahora, inicie el script. El script alcanza el punto de interrupción de la variable. El modo predeterminado es Write, por lo que la ejecución se detiene justo antes de la instrucción que cambia el valor de la variable.

PS C:\ps-test> .\test.ps1
Hit Variable breakpoint on 'C:\ps-test\test.ps1:$scriptName'
(Write access)

test.ps1:11  $scriptName = $MyInvocation.PSCommandPath
DBG>

Muestra el valor actual de la $scriptName variable, que es $null.

DBG> $scriptName
DBG>

Use un Step comando (s) para ejecutar la instrucción que rellena la variable. A continuación, muestre el nuevo valor de la $scriptName variable.

DBG> $scriptName
C:\ps-test\test.ps1

Use un comando Step (s) para obtener una vista previa de la siguiente instrucción en el script.

DBG> s
test.ps1:12  psversion

La siguiente instrucción es una llamada a la psversion función . Para omitir la función pero seguir ejecutándola, use un StepOver comando (v). Si ya está en la función cuando usa StepOver, no es eficaz. Se muestra la llamada de función, pero no se ejecuta.

DBG> v
Windows PowerShell 2.0
Have you run a background job today (start-job)?
test.ps1:13  "Done $scriptName"

El StepOver comando ejecuta la función y muestra una vista previa de la siguiente instrucción en el script, que imprime la línea final.

Use un Stop comando (t) para salir del depurador. El símbolo del sistema vuelve al símbolo del sistema estándar.

C:\ps-test>

Para eliminar los puntos de interrupción, use los Get-PsBreakpoint cmdlets y Remove-PsBreakpoint .

PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint

Cree un nuevo punto de interrupción de comando en la psversion función .

PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1

Puede abreviar este comando para:

PS C:\ps-test> sbp -c psversion -s test.ps1

Ahora, ejecute el script.

PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'

test.ps1:12  psversion
DBG>

El script alcanza el punto de interrupción en la llamada de función. En este momento, aún no se ha llamado a la función . Esto le ofrece la oportunidad de usar el parámetro Action de Set-PSBreakpoint para establecer condiciones para la ejecución del punto de interrupción o para realizar tareas preparatorias o de diagnóstico, como iniciar un registro o invocar un script de diagnóstico o seguridad.

Para establecer una acción, use un comando Continue (c) para salir del script y un Remove-PsBreakpoint comando para eliminar el punto de interrupción actual. (Los puntos de interrupción son de solo lectura, por lo que no puede agregar una acción al punto de interrupción actual).

DBG> c
Windows PowerShell 2.0
Have you run a background job today (start-job)?
Done C:\ps-test\test.ps1

PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint
PS C:\ps-test>

Ahora, cree un nuevo punto de interrupción de comando con una acción. El comando siguiente establece un punto de interrupción de comando con una acción que registra el valor de la $scriptName variable cuando se llama a la función. Dado que la break palabra clave no se usa en la acción, la ejecución no se detiene. El verso (`) es el carácter de continuación de línea.

PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1  `
-action { add-content "The value of `$scriptName is $scriptName." `
-path action.log}

También puede agregar acciones que establezcan condiciones para el punto de interrupción. En el comando siguiente, el punto de interrupción del comando solo se ejecuta si la directiva de ejecución está establecida en RemoteSigned, la directiva más restrictiva que le permite ejecutar scripts.

PS C:\ps-test> Set-PSBreakpoint -script test.ps1 -command psversion `
-action { if ((Get-ExecutionPolicy) -eq "RemoteSigned") { break }}

La break palabra clave de la acción dirige al depurador para ejecutar el punto de interrupción. También puede usar la continue palabra clave para dirigir al depurador para que se ejecute sin interrumpir. Dado que la palabra clave predeterminada es continue, debe especificar break para detener la ejecución.

Ahora, ejecute el script.

PS C:\ps-test> .\test.ps1
Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion'

test.ps1:12  psversion

Dado que la directiva de ejecución se establece en RemoteSigned, la ejecución se detiene en la llamada de función.

En este momento, es posible que quiera comprobar la pila de llamadas. Use el Get-PsCallStack cmdlet o el comando del Get-PsCallStack depurador (k). El comando siguiente obtiene la pila de llamadas actual.

DBG> k
2: prompt
1: .\test.ps1: $args=[]
0: prompt: $args=[]

En este ejemplo se muestran solo algunas de las muchas maneras de usar el depurador de PowerShell.

Otras características de depuración en PowerShell

Además del depurador de PowerShell, PowerShell incluye otras características que puede usar para depurar scripts y funciones.

  • El Set-PSDebug cmdlet ofrece características de depuración de scripts muy básicas, como la ejecución paso a paso y el seguimiento.

  • Use el Set-StrictMode cmdlet para detectar referencias a variables no inicializadas, a referencias a propiedades no existentes de un objeto y a la sintaxis de función que no es válida.

  • Agregue instrucciones de diagnóstico a un script, como instrucciones que muestran el valor de variables, instrucciones que leen la entrada de la línea de comandos o instrucciones que informan de la instrucción actual. Use los cmdlets que contienen el verbo Write para esta tarea, como Write-Host, Write-Debug, Write-Warningy Write-Verbose.

Consulte también