1
00:00:00,100 --> 00:00:03,830
So let's go onto our PowerShell console,

2
00:00:03,830 --> 00:00:05,540
and we'll look at how we investigate

3
00:00:05,540 --> 00:00:07,610
failed jobs by reviewing the current

4
00:00:07,610 --> 00:00:10,990
status of any jobs and then also examining

5
00:00:10,990 --> 00:00:14,540
the reason of why the job failed. So what

6
00:00:14,540 --> 00:00:17,350
I want to talk about now is retrieving the

7
00:00:17,350 --> 00:00:21,200
status and the reason for a potential

8
00:00:21,200 --> 00:00:24,220
failure of a job. Now, to do this, I first

9
00:00:24,220 --> 00:00:26,830
need to create a job. So let me create a

10
00:00:26,830 --> 00:00:31,490
variable, job = Start‑Job. I'll give it a

11
00:00:31,490 --> 00:00:35,940
name. We'll call it FailedJob so we know

12
00:00:35,940 --> 00:00:38,380
what we're looking at. And then in the

13
00:00:38,380 --> 00:00:42,820
ScriptBlock here, I'm going to do

14
00:00:42,820 --> 00:00:44,500
something weird. I'm basically just going

15
00:00:44,500 --> 00:00:50,510
to say New‑Item, so Path, I'm going to use

16
00:00:50,510 --> 00:00:53,800
a drive that doesn't exist, so that's

17
00:00:53,800 --> 00:01:02,110
going to cause me a failure, name 'Failed'

18
00:01:02,110 --> 00:01:11,430
‑ItemType Directory, and I'll set the

19
00:01:11,430 --> 00:01:16,870
ErrorAction to just Stop. So I'm using two

20
00:01:16,870 --> 00:01:18,820
bits of PowerShell here, one is to start

21
00:01:18,820 --> 00:01:20,980
the job, the second is to try and create a

22
00:01:20,980 --> 00:01:23,950
new items, such as a directory, in a drive

23
00:01:23,950 --> 00:01:25,570
that doesn't exist, and then my

24
00:01:25,570 --> 00:01:27,740
ErrorAction is to just Stop. So I'm going

25
00:01:27,740 --> 00:01:29,550
to kick that off, and then I'm going to

26
00:01:29,550 --> 00:01:31,710
click on my job here, and you'll see that

27
00:01:31,710 --> 00:01:34,670
my background job failed, so we have a

28
00:01:34,670 --> 00:01:37,570
specific FailedJob. Now, we can retrieve

29
00:01:37,570 --> 00:01:40,340
the details about the job. We can also

30
00:01:40,340 --> 00:01:44,970
retrieve the child jobs that initiated. So

31
00:01:44,970 --> 00:01:46,750
you can see here, we've got the FailedJob

32
00:01:46,750 --> 00:01:49,280
and then the job that was kicked off as

33
00:01:49,280 --> 00:01:52,170
part of that process. We can also then get

34
00:01:52,170 --> 00:01:55,270
the j+ob state, so I can say

35
00:01:55,270 --> 00:02:00,710
ChildJobState. And notice, when it comes

36
00:02:00,710 --> 00:02:02,450
back, you can't retrieve the specific

37
00:02:02,450 --> 00:02:04,520
value because you actually have to pass

38
00:02:04,520 --> 00:02:05,950
what it is you're looking for, which is

39
00:02:05,950 --> 00:02:08,210
failed, or completed, or something else.

40
00:02:08,210 --> 00:02:10,390
So just be aware, sometimes when you add

41
00:02:10,390 --> 00:02:12,810
the properties, like IncludeChildJob

42
00:02:12,810 --> 00:02:15,040
doesn't require a value, but ChildJobState

43
00:02:15,040 --> 00:02:18,550
does, so I can retrieve basic information.

44
00:02:18,550 --> 00:02:21,080
Now, what I can also do is obviously

45
00:02:21,080 --> 00:02:24,570
receive the job kind of details of what

46
00:02:24,570 --> 00:02:27,800
took place. So let me just create a

47
00:02:27,800 --> 00:02:31,030
variable called error, and what I'll do is

48
00:02:31,030 --> 00:02:37,410
we'll say, Receive‑Job, and I'm going to

49
00:02:37,410 --> 00:02:48,010
call it job, and it'll come back and say,

50
00:02:48,010 --> 00:02:50,650
New‑Item: Cannot find the drive. A drive

51
00:02:50,650 --> 00:02:53,670
with the name Z does not exist. So we have

52
00:02:53,670 --> 00:02:57,200
our standard message kind of response

53
00:02:57,200 --> 00:02:59,880
back, so I can at least retrieve.

54
00:02:59,880 --> 00:03:01,890
Remember, the Receive‑Job is all about

55
00:03:01,890 --> 00:03:04,950
getting the values that would come back if

56
00:03:04,950 --> 00:03:07,120
the job was successful. Now, what's

57
00:03:07,120 --> 00:03:09,900
interesting here is that once we have

58
00:03:09,900 --> 00:03:11,740
retrieved the job, then, of course, there

59
00:03:11,740 --> 00:03:14,320
are other bits of information that are

60
00:03:14,320 --> 00:03:17,040
available to us. So we have the error. So

61
00:03:17,040 --> 00:03:20,070
if I say error and just do Enter, what it

62
00:03:20,070 --> 00:03:21,940
does, as you can see, there's a whole

63
00:03:21,940 --> 00:03:24,090
bunch of stuff that kind of comes back and

64
00:03:24,090 --> 00:03:26,440
it says, Cannot override variable Error.

65
00:03:26,440 --> 00:03:29,090
It's read‑only, comes back with the Z

66
00:03:29,090 --> 00:03:30,800
error, then something else, something

67
00:03:30,800 --> 00:03:33,210
else, and basically spits out a whole

68
00:03:33,210 --> 00:03:36,210
bunch of information around not being able

69
00:03:36,210 --> 00:03:39,410
to get information back from the specific

70
00:03:39,410 --> 00:03:42,880
job. Now, what we can do is there are,

71
00:03:42,880 --> 00:03:45,350
remember the child jobs option, so, for

72
00:03:45,350 --> 00:03:48,920
example, if I say Get‑Job, it gives me the

73
00:03:48,920 --> 00:03:51,550
list of jobs, and I can say

74
00:03:51,550 --> 00:03:53,740
IncludeChildJobs, it gives me the list of

75
00:03:53,740 --> 00:03:55,920
the jobs that are there. So if I want to

76
00:03:55,920 --> 00:04:01,340
say Get‑Job ‑ID 16, for example, it's

77
00:04:01,340 --> 00:04:04,260
going to come back with that job itself.

78
00:04:04,260 --> 00:04:06,920
Now, what we can do with the child jobs is

79
00:04:06,920 --> 00:04:10,190
actually go in and retrieve the values of

80
00:04:10,190 --> 00:04:13,520
why the job failed, or at least from the

81
00:04:13,520 --> 00:04:15,910
main job too. So if we just go back to

82
00:04:15,910 --> 00:04:20,330
Get‑Job, job is 15 is my unique ID, so I'm

83
00:04:20,330 --> 00:04:27,880
going to say, Get‑Job ‑ID 15, and I'm

84
00:04:27,880 --> 00:04:31,380
going to do a Select statement here, and

85
00:04:31,380 --> 00:04:33,760
I'm going to expand the property called

86
00:04:33,760 --> 00:04:39,300
JobStateInfo. Now, JobStateInfo is a kind

87
00:04:39,300 --> 00:04:42,490
of container field that contains State and

88
00:04:42,490 --> 00:04:45,080
Reason. So what I could do at this point

89
00:04:45,080 --> 00:04:47,100
is I could then nest it back down again

90
00:04:47,100 --> 00:04:51,030
and say Select State, and that would give

91
00:04:51,030 --> 00:04:54,210
me the Failed value. If I had a Reason

92
00:04:54,210 --> 00:04:57,230
value, then I could also get the Reason

93
00:04:57,230 --> 00:04:58,770
value, which at this point is actually

94
00:04:58,770 --> 00:05:02,340
empty. So you can be aware that we can

95
00:05:02,340 --> 00:05:06,480
retrieve information around that specific

96
00:05:06,480 --> 00:05:09,790
type of message that's there. Now, what we

97
00:05:09,790 --> 00:05:12,300
can also do is if I just create a new

98
00:05:12,300 --> 00:05:14,940
variable called joberror, and I'm going to

99
00:05:14,940 --> 00:05:21,280
say, well, my job, or my error job, or at

100
00:05:21,280 --> 00:05:23,130
least, I think it was in lowercase, that

101
00:05:23,130 --> 00:05:28,840
was my job, I can say ChildJobs and then

102
00:05:28,840 --> 00:05:34,780
obviously pick a 0. What we could also do

103
00:05:34,780 --> 00:05:39,960
is if I just create a new variable, and

104
00:05:39,960 --> 00:05:42,340
we're going to populate it with the job

105
00:05:42,340 --> 00:05:46,730
itself, if I actually say ChildJobs and

106
00:05:46,730 --> 00:05:51,660
pick the first one, I can also get the

107
00:05:51,660 --> 00:05:56,490
JobStateInfo. So joberror, and you'll see

108
00:05:56,490 --> 00:05:59,200
it gives me this kind of state, and now I

109
00:05:59,200 --> 00:06:02,470
get a value in the Reason field as well.

110
00:06:02,470 --> 00:06:04,160
So what that means is that I can actually

111
00:06:04,160 --> 00:06:10,950
say JobStateInfo.Reason.Message. And now

112
00:06:10,950 --> 00:06:14,090
when I go to joberror, I get Cannot find a

113
00:06:14,090 --> 00:06:16,200
drive. A drive with the name Z does not

114
00:06:16,200 --> 00:06:18,580
exist. So there are a couple different

115
00:06:18,580 --> 00:06:20,780
ways of retrieving the same information.

116
00:06:20,780 --> 00:06:22,830
The first one, obviously, is to receive

117
00:06:22,830 --> 00:06:24,830
the job, which will give you the results

118
00:06:24,830 --> 00:06:26,960
back, which may or may not give you the

119
00:06:26,960 --> 00:06:29,510
actual error. The second option is to,

120
00:06:29,510 --> 00:06:32,500
obviously, just go and retrieve and use

121
00:06:32,500 --> 00:06:34,520
the Select statement to expand the

122
00:06:34,520 --> 00:06:37,120
property of Job State info, and then

123
00:06:37,120 --> 00:06:39,330
you'll get State and Reason. But if Reason

124
00:06:39,330 --> 00:06:41,570
is empty, then actually, what you'll need

125
00:06:41,570 --> 00:06:44,180
to do is go and do it this way, which is

126
00:06:44,180 --> 00:06:46,690
get the job, the child job, by the unique

127
00:06:46,690 --> 00:06:49,190
Identify here and then go and get the

128
00:06:49,190 --> 00:06:50,900
JobStateInfo, and then you'll get the

129
00:06:50,900 --> 00:06:54,040
reason and the message. So a simple way of

130
00:06:54,040 --> 00:06:57,150
being able to identify the reason why a

131
00:06:57,150 --> 00:07:00,240
specific job failed. Now, of course, we

132
00:07:00,240 --> 00:07:02,250
also have the ability, so if I just get

133
00:07:02,250 --> 00:07:04,510
rid of my job here and just say,

134
00:07:04,510 --> 00:07:13,530
job.ChildJobs and then just do Error, I

135
00:07:13,530 --> 00:07:15,330
can do that same thing. So if there's an

136
00:07:15,330 --> 00:07:17,570
Error on that first job, I get the

137
00:07:17,570 --> 00:07:21,470
message. If I do a second one or a third

138
00:07:21,470 --> 00:07:23,460
one, depending on the unique identifier, I

139
00:07:23,460 --> 00:07:26,200
might get that message back also. So just

140
00:07:26,200 --> 00:07:30,000
a couple of different ways of being able to retrieve that information.

