So let's go into our environment,
and we'll look at how we can create scheduled tasks using
PowerShell for exporting all of the log data.
So our final piece here is to go ahead and create a
scheduled task and some kind of process that's going to go
through and connect to those machines.
So I'm going to flick over to Visual Studio Code here.
And in here, I have two files.
The first one is a Servers file, which is going to have Windows Server 2022.
And a tip we'll do, we'll just change this to be Windows 10.
So those are my two machines.
I could also add Windows 2012.
I could also add Windows 2016,
as well as some of those servers that I might have available to me.
So I'm going to save that, so that's my Servers file.
Then I also have the actual thing that I would like to do,
which is called Query‑Logs.ps1.
So this is a PowerShell file.
Now, this means that when I execute my scheduled task,
I actually want it to go ahead and run this piece of code as part of that.
So the first thing I'm going to do here is just adjust a couple of things.
I'm going to get rid of this path and update it to be Servers.csv.
So the first thing we're going to do here is we're going to import the CSV file,
which, if I click back into here, it's my list of servers.
And then I set the path to be the output of where I want things to go.
What I'm then able to do is use that list of servers that we just added,
and I'm going to use a standard ForEach‑Object,
as you can see here.
And then I'm going to call a function, which we'll talk about in a second,
called Invoke‑RemoteSession.
So effectively, open the CSV file, set the path, loop each of the servers.
Once we have that list of servers,
then I'm going to call this new function we've
created called Invoke‑RemoteSession, which has a single property of a server.
And basically, every time we run the ForEach‑Object,
it's going to call this function,
which is going to go ahead and say create me a session
using New‑PSSession to that computer name.
I could use SSHTransport, which we've used in the past,
which will then change the protocol that's being used.
Or I could leave it, and it will use the default WS‑MAN.
Now once that's done, that's going to create me sessions.
So this will create me PowerShell sessions only.
Now at that point, once I have sessions, I effectively want to iterate the logs.
I'm going to move this over here a little bit. And we have a
new function called Invoke‑LogRetrieval,
which requires a session and a log entry or a name that we wish to utilize.
It's then going to use the existing session that we have created and go and run
a ScriptBlock of basically get me whatever the log name is,
WinEvents,
get me a maximum of 10 and then whatever was created in the last 24 hours.
And then select me the objects of ID and message.
Now, of course, the difficulty is here, if I scroll back to the top,
I'm creating PSSessions,
so how do I know what those PSSessions are because there could be 5 servers,
1 server, or 50 servers in there.
So what we do here is go down to this line where it
says sessions = Get‑PSSession.
So before I do anything, I go and iterate the existing sessions.
Remember the Get‑PSSession will show you whether it's a WS‑MAN session,
SSH session, whether it's Windows or Linux,
whatever it would be, it gives me all the details.
I can then use a standard foreach option to iterate each of the sessions.
And then, as you can see in these three here,
I'm going to go ahead and invoke that log retrieval for the application log,
the security log, and the system log.
And then my last task here is to use Export‑Csv and create those CSV files.
So, that's what this file is going to do.
I'm just going to click File and Save here so I have it updated.
And then what we're going to do is just execute it to make sure it works.
I'm going to copy sections of it and go over to my path here.
And inside my terminal, I'm going to press Enter.
If I just click and type servers here,
you'll see it gives me the list of all the servers,
so we know that that's functioning.
I'm then going to go back to my code,
and I'm going to take the functions that are being
created and put those in first.
And the reason you'll need the functions is because I can't call the
function if I don't have the function existing.
So it's important about the order of the PowerShell file.
Now I can go into here and say servers ForEach‑Object,
call that invoke mechanism, and I'm going to do this.
And, of course, oh, I've left the SSH in, which I didn't want to do.
So let me just clear that for a second, and I'll go back.
We're not going to use SSH.
We're just going to use standard WS‑MAN.
So let me take this function.
I need to repaste it over here like so.
And then I can take that same service option again.
So let me clear that and paste it in.
Now, of course,
you'll notice here that it only created one of those remote connections,
and that's okay,
and that's because I was just using names just to illustrate
that we could put any of the servers in there.
But we could use IP address is too to connect,
but we successfully connected to the Windows 2022 server.
So let me just clear that here.
So if I now do Get‑PSSession,
you'll see we have a couple of different options available to us.
We have 1, 3, and 5 because of previous connections that are there,
and they're all WS‑MAN.
If you wanted to remove a session, we can say Remove‑PSSession,
and we can iterate through the various properties,
but there's an ID option.
I can say 1, and I can say 3, and then when I say Get‑PSSession,
I only have one.
So let me clear that.
Let's go back to my Visual Studio Code.
And then, we're now going to say fill the sessions option for me like so.
Sessions shows that one option.
And then, I'm now going to say for each of the sessions that we've got,
I want you to go ahead and retrieve the log files and export them.
So I'm going to press Enter here, and it was really, really quick.
So what did that actually do?
Well if I go to my Windows directory here,
go to my PSFolder, you can see that, sure enough , I have an Application.csv,
a Security, and a System.
If I right‑click here and say Open with Code,
you can see it's retrieved that information for the various log entries.
I'm going to go to Security, Open with Code,
you'll see there's my security ones like message have logged off.
And if I go into System here, Open with Code, you can see I have the same thing.
So,
it's really straightforward to be able to create something that
can retrieve log files from a remote machine.
Now that's all good and well, but how do we create the actual scheduled task?
Well the first thing we're going to do is create
the components that are required, and basically they're variables.
So I'm going to create a variable called action,
and the action is called New‑ScheduledTaskAction,
and it references that Query‑Logs PowerShell file.
That's going to be what it executes.
I can then go through and set the trigger.
The trigger for this will be a daily schedule at 10
o'clock in the morning like so.
What I can then do is set the principal or the security
account that needs to run this task, which will be WIN2022 and trainer.
I can then also go through and say settings,
anything that I want to set,
such as run only if the network is available or wake it up to run.
And then my last piece of this is to actually go through
and register that task with a task name using all of the
properties that we created.
So I'm going to press Enter.
And sure enough, it's created me the actual task.
So let's first press the Start menu here,
and we'll just say Task Scheduler, and we'll click into Schedule Library.
And sure enough, right here, you can see my Query Remote Server Logs.
Of I open this, it's got the right name,
it's got the right account, my trigger for 10 AM,
and then, of course, my actions are all sat there.
So,
what we're going to do is I'm actually going to go
in and delete my three CSV files, and then we'll go back to schedule task.
I'm going to right‑click here and say Run.
It's going to say Run.
I'm going to F5 this here just to refresh,
and we'll see if our scheduled task completes.
Now if we keep refreshing here, you can see it just seems to be running.
And we know that when we executed the PowerShell,
it actually ran really quickly.
So let's check out our file directory.
Sure enough, nothing in there too.
So what we'll do is we'll right‑click here,
and we'll just say End and stop that from running.
Now what do we think the problem is?
Well, it's pretty much down to the configuration.
So if we click Properties here and go to our actions,
you'll notice that what we did is we said start a program.
Now, what we also learned is that we can't just execute a PS1 file.
We actually need to tell it to run PowerShell.
So we're going to change this slightly.
I could just type PowerShell.
And then in my arguments here, I can just say File.
And then in the file, I can specify that location.
So now what's going to happen is it's going to start a program,
which will be PowerShell and call that specific one.
So let's press OK here,
and then we'll say Run. And you'll see PowerShell appeared and then went away.
And when we go back, nothing happened here.
So, obviously,
we need to do something with our configuration to make sure that it
launches PowerShell and then executes that command.
So let's go back into our configuration again, Properties, Actions.
And this time, what we can do is browse to the PowerShell options,
so into PowerShell 7 because that's what we're using.
And what you'll find is that it's actually called pwsh.exe,
and I'm going to click Open.
So that's the executable.
I'm not just going to type PowerShell because remember on Windows,
PowerShell, the previous version, so PowerShell 6 and 5,
etc., depending on the version of Windows,
runs on there, and then you have PowerShell 7.
So depending on which one you have installed,
it will dictate which one is going to execute.
So I'm going to say start, pwsh, so the new version, and then still use my path.
And just to be safe,
I'm going to put it in quotes just to make sure there's
nothing strange in the name and click OK.
So now that we've made the change for PowerShell 7,
let's right‑click here and choose Run.
It's going to prompt, and then it disappears, and then it looks like it ends.
So let's open it again, and we'll go to the PSFolder,
and nothing's been created.
So something is still causing the problem.
Now actually, if we go back to the code, we can understand why.
And I mentioned this earlier.
This is a critical key when building PowerShell scripts.
I'm trying to call something called Invoke‑RemoteSession,
but I'm calling it before the function has actually been registered.
So I'm going to take this code in my file.
Now it's all good and well when we're writing it out and testing it locally.
But once we put it into a PowerShell script,
we want it to be formed in the right order.
So the logical process is set your variables,
set your functions, and then call the functions after they've been registered.
So I'm going to click Save here.
That's going to update my file.
So now I should be able to go back into here and choose Run,
and it's now going to run.
You'll see it was a bit slower, the error connections that were there.
And this time, my CSV files have been created.
So, when you're creating PowerShell scripts,
specifically for scheduled tasks,
you need to make sure that everything is written in the
right order and the right version of PowerShell and the
right permissions,etc., as well.