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.
Iniciar y detener el 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,StepInto
se 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
, ,Stop
Exit
: deja de ejecutar el script y sale del depurador. Si está depurando un trabajo mediante la ejecución delDebug-Job
cmdlet , elExit
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 eraStep
(s
),StepOver
(v
) oList
(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.
Depuración de flujos de trabajo
El depurador se puede usar para depurar flujos de trabajo de PowerShell, ya sea en la consola de PowerShell o en Windows PowerShell ISE. Hay algunas limitaciones con el uso del depurador de PowerShell para depurar flujos de trabajo.
- Puede ver las variables de flujo de trabajo mientras se encuentra en el depurador, pero no se admite la configuración de variables de flujo de trabajo desde el depurador.
- Finalización de tabulación cuando se detiene en el depurador de flujo de trabajo no está disponible.
- La depuración de flujos de trabajo solo funciona con la ejecución sincrónica de flujos de trabajo desde un script de PowerShell. No se pueden depurar flujos de trabajo si se ejecutan como un trabajo (con el parámetro AsJob ).
- No se implementan otros escenarios de depuración anidados, como un flujo de trabajo que llama a otro flujo de trabajo o un flujo de trabajo que llama a un script.
En el ejemplo siguiente se muestra cómo depurar un flujo de trabajo. Cuando el depurador pasa a la función de flujo de trabajo, el depurador solicita cambios en [WFDBG]
.
PS C:> Set-PSBreakpoint -Script C:\TestWFDemo1.ps1 -Line 8
ID Script Line Command Variable Action
-- ------ ---- ------- -------- ------
0 TestWFDemo1.ps1 8
PS C:> C:\TestWFDemo1.ps1
Entering debug mode. Use h or ? for help.
Hit Line breakpoint on 'C:\TestWFDemo1.ps1:8'
At C:\TestWFDemo1.ps1:8 char:5
+ Write-Output -InputObject "Now writing output:"
# ~~~~~
[WFDBG:localhost]: PS C:>> list
# 3:
4: workflow SampleWorkflowTest
5: {
6: param ($MyOutput)
# 7:
8:* Write-Output -InputObject "Now writing output:"
9: Write-Output -Input $MyOutput
# 10:
11: Write-Output -InputObject "Get PowerShell process:"
12: Get-Process -Name powershell
# 13:
14: Write-Output -InputObject "Workflow function complete."
15: }
# 16:
17: # Call workflow function
18: SampleWorkflowTest -MyOutput "Hello"
[WFDBG:localhost]: PS C:>> $MyOutput
Hello
[WFDBG:localhost]: PS C:>> stepOver
Now writing output:
At C:\TestWFDemo1.ps1:9 char:5
+ Write-Output -Input $MyOutput
# +!INCLUDE[]~
[WFDBG:localhost]: PS C:>> list
4: workflow SampleWorkflowTest
5: {
6: param ($MyOutput)
# 7:
8: Write-Output -InputObject "Now writing output:"
9:* Write-Output -Input $MyOutput
# 10:
11: Write-Output -InputObject "Get PowerShell process:"
12: Get-Process -Name powershell
# 13:
14: Write-Output -InputObject "Workflow function complete."
15: }
# 16:
17: # Call workflow function
18: SampleWorkflowTest -MyOutput "Hello"
# 19:
[WFDBG:localhost]: PS C:>> stepOver
Hello
At C:\TestWFDemo1.ps1:11 char:5
+ Write-Output -InputObject "Get PowerShell process:"
# +!INCLUDE[]~~~~~~~~~
[WFDBG:localhost]: PS C:>> stepOut
Get PowerShell process:
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
433 35 106688 128392 726 2.67 7124 powershell
499 44 134244 172096 787 2.79 7452 powershell
Workflow function complete.
Funciones de depuración
Cuando se establece un punto de interrupción en una función que tiene begin
secciones , process
y 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-Warning
yWrite-Verbose
.