1
00:00:00,240 --> 00:00:02,750
So let's go on to our PowerShell window

2
00:00:02,750 --> 00:00:05,450
again, and we'll debug a background job by

3
00:00:05,450 --> 00:00:08,870
stepping through it as it tries to

4
00:00:08,870 --> 00:00:11,470
execute. So the second approach that we

5
00:00:11,470 --> 00:00:14,520
have to being able to fix issues or at

6
00:00:14,520 --> 00:00:17,720
least identify issues within PowerShell

7
00:00:17,720 --> 00:00:20,850
jobs, background jobs, is to actually go

8
00:00:20,850 --> 00:00:23,130
through the process of using the debug

9
00:00:23,130 --> 00:00:25,870
option. Now the debug option is a

10
00:00:25,870 --> 00:00:28,430
PowerShell cmdlet called Debug‑Job. So if

11
00:00:28,430 --> 00:00:32,310
we type Debug‑Job, press Enter, it's

12
00:00:32,310 --> 00:00:35,710
expecting a job identifier, so a job that

13
00:00:35,710 --> 00:00:38,200
we can connect into. So if I just say

14
00:00:38,200 --> 00:00:40,300
get‑Job, you can see I've got a job here

15
00:00:40,300 --> 00:00:42,950
that's 15. So, for example, if I go in and

16
00:00:42,950 --> 00:00:50,830
say Debug‑Job, and then say 15, it'll fail

17
00:00:50,830 --> 00:00:52,440
because it doesn't need a specific

18
00:00:52,440 --> 00:00:55,340
identifier. If I go through the options

19
00:00:55,340 --> 00:00:58,140
‑Name ‑Id and say 15, it'll say the

20
00:00:58,140 --> 00:01:00,010
provided job and child jobs were examined,

21
00:01:00,010 --> 00:01:01,750
but no jobs were found that could be

22
00:01:01,750 --> 00:01:03,990
debugged. So that means there's a very

23
00:01:03,990 --> 00:01:06,600
specific way that these jobs must work. So

24
00:01:06,600 --> 00:01:08,680
if we just clear this out, what we're

25
00:01:08,680 --> 00:01:10,860
going to do is actually create a script

26
00:01:10,860 --> 00:01:12,760
block that I want to use, so I'm going to

27
00:01:12,760 --> 00:01:15,540
create a variable called ScriptBlock. I'm

28
00:01:15,540 --> 00:01:17,380
also going to use my squiggly brackets,

29
00:01:17,380 --> 00:01:20,120
and I'm going to create a variable,

30
00:01:20,120 --> 00:01:22,880
populate it with the value 10, then I'm

31
00:01:22,880 --> 00:01:26,190
going to use a command called

32
00:01:26,190 --> 00:01:29,280
Wait‑Debugger. Wait‑Debugger, it means

33
00:01:29,280 --> 00:01:31,310
that the job won't actually do anything or

34
00:01:31,310 --> 00:01:34,560
go any further until the debug option has

35
00:01:34,560 --> 00:01:36,660
been connected to it. I'm then going to

36
00:01:36,660 --> 00:01:39,090
see what the value of the variable is. And

37
00:01:39,090 --> 00:01:40,710
then what I'm going to do is I'm going to

38
00:01:40,710 --> 00:01:42,980
take my variable, and I'll add 10 to

39
00:01:42,980 --> 00:01:44,760
it,and then I'm going to complete my

40
00:01:44,760 --> 00:01:46,420
ScriptBlock. So really straightforward,

41
00:01:46,420 --> 00:01:47,830
nothing special. This could be a

42
00:01:47,830 --> 00:01:49,580
long‑running job. It could be anything,

43
00:01:49,580 --> 00:01:51,370
but It's something that contains

44
00:01:51,370 --> 00:01:54,520
Wait‑Debugger as a mechanism for us to

45
00:01:54,520 --> 00:01:56,940
hook into. So that's my ScriptBlock that's

46
00:01:56,940 --> 00:01:59,350
been defined. I'm now going to go ahead

47
00:01:59,350 --> 00:02:03,460
and generate a new job. So Start‑Job

48
00:02:03,460 --> 00:02:07,010
‑ScriptBlock, and I'll use the ScriptBlock

49
00:02:07,010 --> 00:02:09,680
that we just created. Okay, so if I just

50
00:02:09,680 --> 00:02:12,600
say job, you can see when I look at the

51
00:02:12,600 --> 00:02:15,040
jobs, something important. The state of

52
00:02:15,040 --> 00:02:18,520
the job says AtBreakpoint, That's the

53
00:02:18,520 --> 00:02:22,630
command Wait‑Debugger because I told it to

54
00:02:22,630 --> 00:02:25,780
wait until the debug has been connected.

55
00:02:25,780 --> 00:02:28,600
So what I can then do is say, Debug‑Job,

56
00:02:28,600 --> 00:02:31,190
look at the job, and then I'm going to

57
00:02:31,190 --> 00:02:34,410
pass my job object in. Now notice what

58
00:02:34,410 --> 00:02:37,530
happens. It says Entering debug mode. Use

59
00:02:37,530 --> 00:02:41,000
h or ? for help. So what does that mean?

60
00:02:41,000 --> 00:02:43,500
Well, the job is sitting there. Nothing

61
00:02:43,500 --> 00:02:45,650
has happened. So I'm going to type h, and

62
00:02:45,650 --> 00:02:47,410
you'll see it gives me some instructions

63
00:02:47,410 --> 00:02:50,160
of what I can do. We can stepInto the

64
00:02:50,160 --> 00:02:53,580
function, stepOver, stepOut, continue,

65
00:02:53,580 --> 00:02:56,210
quit, or detach, or we could just list

66
00:02:56,210 --> 00:02:58,140
what's going on. So, for example, if I do

67
00:02:58,140 --> 00:03:00,080
l, you can see it's going to be turned

68
00:03:00,080 --> 00:03:02,350
back what it's about to do. So in this

69
00:03:02,350 --> 00:03:04,650
instance, my ScriptBlock is set the

70
00:03:04,650 --> 00:03:07,340
variable to 10, wait for the debugger,

71
00:03:07,340 --> 00:03:09,590
show me the value, and then add 10 to it

72
00:03:09,590 --> 00:03:12,490
again. So if we press h again, you can see

73
00:03:12,490 --> 00:03:14,460
that what we can do is we can stepInto,

74
00:03:14,460 --> 00:03:17,830
stepOver, stepOut, continue, etc. So if I

75
00:03:17,830 --> 00:03:20,490
say stepInto with an s, it's going to go

76
00:03:20,490 --> 00:03:22,570
through, and it'll say, okay, I'm at line

77
00:03:22,570 --> 00:03:25,030
whatever. If I stepInto, it'll keep

78
00:03:25,030 --> 00:03:27,130
looping. Notice It showed me my number

79
00:03:27,130 --> 00:03:29,500
now. If I press stepInto again, it

80
00:03:29,500 --> 00:03:32,260
finishes and gives me my ID of 20. So I

81
00:03:32,260 --> 00:03:35,610
just walked through my PowerShell script

82
00:03:35,610 --> 00:03:37,640
as it was trying to do stuff. So the

83
00:03:37,640 --> 00:03:41,270
Debug‑Job command functions by looking for

84
00:03:41,270 --> 00:03:43,790
the Wait‑Debugger statements and then

85
00:03:43,790 --> 00:03:45,980
hooks into it so then you can do this line

86
00:03:45,980 --> 00:03:48,320
by line. Now how is that useful? Well,

87
00:03:48,320 --> 00:03:50,980
think about the logic of if you are trying

88
00:03:50,980 --> 00:03:54,050
to run a script against, you know, a large

89
00:03:54,050 --> 00:03:56,310
server environment and you want to be able

90
00:03:56,310 --> 00:03:59,670
to do specific things, but you also know

91
00:03:59,670 --> 00:04:02,410
that the script may fail at some point. In

92
00:04:02,410 --> 00:04:04,150
that instance, we would define the

93
00:04:04,150 --> 00:04:07,940
ScriptBlock, which could be a specific

94
00:04:07,940 --> 00:04:10,590
PowerShell file that you actually wanted

95
00:04:10,590 --> 00:04:14,300
to execute. So, for example, a PS1 file

96
00:04:14,300 --> 00:04:17,170
that you may have, and then from there,

97
00:04:17,170 --> 00:04:18,340
you can then go through and put a

98
00:04:18,340 --> 00:04:20,200
Wait‑Debugger statement in, and then it

99
00:04:20,200 --> 00:04:24,670
would allow you to step into line by line

100
00:04:24,670 --> 00:04:28,480
that script. So let's clear the screen,

101
00:04:28,480 --> 00:04:30,730
and we'll try a different one where we can

102
00:04:30,730 --> 00:04:32,140
actually, obviously, step right through

103
00:04:32,140 --> 00:04:34,930
this. So the first thing we have to do is

104
00:04:34,930 --> 00:04:37,270
start a specific job. So I'm going to say,

105
00:04:37,270 --> 00:04:39,100
Start, well, actually we'll do a variable

106
00:04:39,100 --> 00:04:41,500
so we know what we're looking for. So

107
00:04:41,500 --> 00:04:45,150
we're going to say Start‑Job, and I'm

108
00:04:45,150 --> 00:04:46,470
going to do a different one this time. I'm

109
00:04:46,470 --> 00:04:48,860
going to do a file path, and then I'm

110
00:04:48,860 --> 00:04:53,140
going to use a file called Count.ps1.

111
00:04:53,140 --> 00:04:55,430
Okay, so we have the job. Now let me look

112
00:04:55,430 --> 00:04:57,950
at the job status. So you can see that

113
00:04:57,950 --> 00:05:00,250
it's at the breakpoint, which means it's

114
00:05:00,250 --> 00:05:02,390
hit my Wait‑Debugger, but yet, we don't

115
00:05:02,390 --> 00:05:03,550
know what the code's going to run, so

116
00:05:03,550 --> 00:05:05,220
we'll look at that in a second. So what

117
00:05:05,220 --> 00:05:09,880
I'm going to do here is say Debug‑Job,

118
00:05:09,880 --> 00:05:12,590
click the ‑Job option, and then represent

119
00:05:12,590 --> 00:05:15,200
that, and now it's going to go into what's

120
00:05:15,200 --> 00:05:16,980
there. So how do we see what's inside of

121
00:05:16,980 --> 00:05:18,410
it? Well, let's press the list, and you

122
00:05:18,410 --> 00:05:20,360
can see from here, it's going to basically

123
00:05:20,360 --> 00:05:22,500
count from 0 to 10, it waits for the

124
00:05:22,500 --> 00:05:24,430
debugger, and then for each one, it should

125
00:05:24,430 --> 00:05:27,180
write a value of what it is. So if I say

126
00:05:27,180 --> 00:05:29,830
stepInto, now notice what happened. It

127
00:05:29,830 --> 00:05:32,940
just literally cleared and finished. Now

128
00:05:32,940 --> 00:05:35,380
depending on what the code is supposed to

129
00:05:35,380 --> 00:05:38,450
do, depending how it functions, notice how

130
00:05:38,450 --> 00:05:40,750
this one's written, it does this bit,

131
00:05:40,750 --> 00:05:43,340
pipes into this one, pipes into this one.

132
00:05:43,340 --> 00:05:45,280
So at no point am I waiting for the

133
00:05:45,280 --> 00:05:47,830
debugger to do anything because I've just

134
00:05:47,830 --> 00:05:50,380
passed it through the process. So

135
00:05:50,380 --> 00:05:52,320
sometimes the debug won't actually pick

136
00:05:52,320 --> 00:05:54,680
anything up. So let's just try that

137
00:05:54,680 --> 00:05:59,000
principle again. So this time around, what

138
00:05:59,000 --> 00:06:01,670
we'll do is use the same kind of syntax,

139
00:06:01,670 --> 00:06:04,180
but actually, we'll use a different file,

140
00:06:04,180 --> 00:06:05,790
and we'll start the job, so let's just

141
00:06:05,790 --> 00:06:07,400
check my job. It's sitting at a

142
00:06:07,400 --> 00:06:10,050
breakpoint, so we'll go through and do a

143
00:06:10,050 --> 00:06:12,380
debug, and then what we'll do is do a

144
00:06:12,380 --> 00:06:14,820
list. Now notice this time with the

145
00:06:14,820 --> 00:06:18,380
Wait‑Debug is inside the for each loop, so

146
00:06:18,380 --> 00:06:21,090
let me do stepInto. And, of course, now it

147
00:06:21,090 --> 00:06:23,650
starts to step in. So if we do step, the

148
00:06:23,650 --> 00:06:27,770
value is 0, the value is etc., and then it

149
00:06:27,770 --> 00:06:30,620
loops all the way through. So, writing

150
00:06:30,620 --> 00:06:33,090
PowerShell to utilize the Wait‑Debugger

151
00:06:33,090 --> 00:06:34,490
can be a little bit more complicated. It

152
00:06:34,490 --> 00:06:36,950
all depends where you want that to be and

153
00:06:36,950 --> 00:06:39,780
how you want it to flow inside a loop or

154
00:06:39,780 --> 00:06:41,900
even if you just want to be able to put it

155
00:06:41,900 --> 00:06:43,960
at the beginning and then kind of execute

156
00:06:43,960 --> 00:06:46,490
it. But that's the way how we use debug.

157
00:06:46,490 --> 00:06:48,450
So you simply put a Wait‑Debugger and then

158
00:06:48,450 --> 00:06:52,730
debug into the job itself. So, when trying

159
00:06:52,730 --> 00:06:56,110
to figure out how to kind of fix issues in

160
00:06:56,110 --> 00:06:58,390
background jobs, it's really those two

161
00:06:58,390 --> 00:07:00,570
options, debugging something to step

162
00:07:00,570 --> 00:07:03,080
through bit by bit, or it's to actually go

163
00:07:03,080 --> 00:07:06,000
through and to retrieve the status and the reason.

