So let's go on to our PowerShell window
again, and we'll debug a background job by
stepping through it as it tries to
execute. So the second approach that we
have to being able to fix issues or at
least identify issues within PowerShell
jobs, background jobs, is to actually go
through the process of using the debug
option. Now the debug option is a
PowerShell cmdlet called Debug‑Job. So if
we type Debug‑Job, press Enter, it's
expecting a job identifier, so a job that
we can connect into. So if I just say
get‑Job, you can see I've got a job here
that's 15. So, for example, if I go in and
say Debug‑Job, and then say 15, it'll fail
because it doesn't need a specific
identifier. If I go through the options
‑Name ‑Id and say 15, it'll say the
provided job and child jobs were examined,
but no jobs were found that could be
debugged. So that means there's a very
specific way that these jobs must work. So
if we just clear this out, what we're
going to do is actually create a script
block that I want to use, so I'm going to
create a variable called ScriptBlock. I'm
also going to use my squiggly brackets,
and I'm going to create a variable,
populate it with the value 10, then I'm
going to use a command called
Wait‑Debugger. Wait‑Debugger, it means
that the job won't actually do anything or
go any further until the debug option has
been connected to it. I'm then going to
see what the value of the variable is. And
then what I'm going to do is I'm going to
take my variable, and I'll add 10 to
it,and then I'm going to complete my
ScriptBlock. So really straightforward,
nothing special. This could be a
long‑running job. It could be anything,
but It's something that contains
Wait‑Debugger as a mechanism for us to
hook into. So that's my ScriptBlock that's
been defined. I'm now going to go ahead
and generate a new job. So Start‑Job
‑ScriptBlock, and I'll use the ScriptBlock
that we just created. Okay, so if I just
say job, you can see when I look at the
jobs, something important. The state of
the job says AtBreakpoint, That's the
command Wait‑Debugger because I told it to
wait until the debug has been connected.
So what I can then do is say, Debug‑Job,
look at the job, and then I'm going to
pass my job object in. Now notice what
happens. It says Entering debug mode. Use
h or ? for help. So what does that mean?
Well, the job is sitting there. Nothing
has happened. So I'm going to type h, and
you'll see it gives me some instructions
of what I can do. We can stepInto the
function, stepOver, stepOut, continue,
quit, or detach, or we could just list
what's going on. So, for example, if I do
l, you can see it's going to be turned
back what it's about to do. So in this
instance, my ScriptBlock is set the
variable to 10, wait for the debugger,
show me the value, and then add 10 to it
again. So if we press h again, you can see
that what we can do is we can stepInto,
stepOver, stepOut, continue, etc. So if I
say stepInto with an s, it's going to go
through, and it'll say, okay, I'm at line
whatever. If I stepInto, it'll keep
looping. Notice It showed me my number
now. If I press stepInto again, it
finishes and gives me my ID of 20. So I
just walked through my PowerShell script
as it was trying to do stuff. So the
Debug‑Job command functions by looking for
the Wait‑Debugger statements and then
hooks into it so then you can do this line
by line. Now how is that useful? Well,
think about the logic of if you are trying
to run a script against, you know, a large
server environment and you want to be able
to do specific things, but you also know
that the script may fail at some point. In
that instance, we would define the
ScriptBlock, which could be a specific
PowerShell file that you actually wanted
to execute. So, for example, a PS1 file
that you may have, and then from there,
you can then go through and put a
Wait‑Debugger statement in, and then it
would allow you to step into line by line
that script. So let's clear the screen,
and we'll try a different one where we can
actually, obviously, step right through
this. So the first thing we have to do is
start a specific job. So I'm going to say,
Start, well, actually we'll do a variable
so we know what we're looking for. So
we're going to say Start‑Job, and I'm
going to do a different one this time. I'm
going to do a file path, and then I'm
going to use a file called Count.ps1.
Okay, so we have the job. Now let me look
at the job status. So you can see that
it's at the breakpoint, which means it's
hit my Wait‑Debugger, but yet, we don't
know what the code's going to run, so
we'll look at that in a second. So what
I'm going to do here is say Debug‑Job,
click the ‑Job option, and then represent
that, and now it's going to go into what's
there. So how do we see what's inside of
it? Well, let's press the list, and you
can see from here, it's going to basically
count from 0 to 10, it waits for the
debugger, and then for each one, it should
write a value of what it is. So if I say
stepInto, now notice what happened. It
just literally cleared and finished. Now
depending on what the code is supposed to
do, depending how it functions, notice how
this one's written, it does this bit,
pipes into this one, pipes into this one.
So at no point am I waiting for the
debugger to do anything because I've just
passed it through the process. So
sometimes the debug won't actually pick
anything up. So let's just try that
principle again. So this time around, what
we'll do is use the same kind of syntax,
but actually, we'll use a different file,
and we'll start the job, so let's just
check my job. It's sitting at a
breakpoint, so we'll go through and do a
debug, and then what we'll do is do a
list. Now notice this time with the
Wait‑Debug is inside the for each loop, so
let me do stepInto. And, of course, now it
starts to step in. So if we do step, the
value is 0, the value is etc., and then it
loops all the way through. So, writing
PowerShell to utilize the Wait‑Debugger
can be a little bit more complicated. It
all depends where you want that to be and
how you want it to flow inside a loop or
even if you just want to be able to put it
at the beginning and then kind of execute
it. But that's the way how we use debug.
So you simply put a Wait‑Debugger and then
debug into the job itself. So, when trying
to figure out how to kind of fix issues in
background jobs, it's really those two
options, debugging something to step
through bit by bit, or it's to actually go
through and to retrieve the status and the reason.