Advanced Windows PowerShell Scripting Video Training

Thursday, June 16, 2016

In last week’s PowerShell class, we had a question about not
only running a scheduled job, but how to unregister it after it finishes. Good question. The answer is actually very simple.

The code below is a very simple job. The problem with it is that after it
executes, it will stay in memory until you unregister it.

$Trigger=New-ScheduledTaskTrigger-Once-At (Get-Date).AddMinutes(1)

Register-ScheduledJob-Trigger$Trigger
`

-Name"Test1" `

-ScriptBlock
{Get-CimInstance-ClassNameWin32_Bios}

In the Task Scheduler, we can see that the job completed,
but it still in memory.

The cmdlet Unregister-ScheduledJob must be run to remove
this object from memory.

PS C:\> Unregister-ScheduledJob -Name Test1

Now we will re-code the script to automatically remove the
job after it completes.

$Trigger=New-ScheduledTaskTrigger-Once-At (Get-Date).AddMinutes(1)

Register-ScheduledJob-Trigger$Trigger
`

-Name"Test1" `

-ScriptBlock
{

Get-CimInstance-ClassNameWin32_Bios

Unregister-ScheduledJob-Name"Test1"

}

Notice that the final cmdlet in the script block is
Unregister-ScheduledJob. This removal
will take effect immediately in the Task Scheduler once the job completes. If you are still in the same PowerShell
session as the one you used to create the job, you will see the following error
for a few minutes after the job is unregistered.

PS C:\> Get-ScheduledJob

Get-ScheduledJob : Cannot get the Test1 scheduled job because it is
corrupted or in an irresolvable state. Because it cannot run,

Windows PowerShell has deleted Test1 and its results from the
computer. To recreate the scheduled job, use the Register-ScheduledJob

cmdlet. For more information about corrupted scheduled jobs, see
about_Scheduled_Jobs_Troubleshooting.

This method is only appropriate if you do not intent on recovering
data from the script later on. One of
the benefits of a scheduled job is that the objects returned are serialized and
written to disk for you to consume later.
If you un-register the job, that stored data is removed from this. For this reason, you should ether explicitly
commit the objects to disk before the Unregister-Scheduled job cmdlet is executed
or only use this procedure for scripts that perform actions. In any case, I would consider a little extra
code to at least email you to let you know if the task was successful or not.

Wednesday, June 8, 2016

Yesterday in my PowerShell class we were doing a lab on object
enumeration. I took a few minutes to
take a look at the forums on PowerShell.com and found a question that related
directly to our lab content. Here is the
scenario.

This individual
needed to close an instance of Internet Explorer. The problem is that there were multiple
instances open. He needed a way to
select a specific instance. Using the Get-Process cmdlet, you can grab each
instance, but the process object does not contain anything useful to isolate a
particular instance. So I tried a different approached.

I opened an IE instance and went to PowerShell.com. I then executed the code below.

Tuesday, June 7, 2016

One of the questions that I often get is “How do I know if a
client is online?” Traditionally we would PING the client. PowerShell has a cmdlet called
Test-Connection. It essentially is the
PING command, but gives you an object as the output. Let’s see the difference.

PS C:\> Ping 8.8.8.8

Pinging 8.8.8.8 with 32 bytes of data:

Reply from 8.8.8.8: bytes=32 time=19ms TTL=56

Reply from 8.8.8.8: bytes=32 time=20ms TTL=56

Reply from 8.8.8.8: bytes=32 time=20ms TTL=56

Reply from 8.8.8.8: bytes=32 time=20ms TTL=56

Ping statistics for 8.8.8.8:

Packets: Sent = 4,
Received = 4, Lost = 0 (0% loss),

Approximate round trip times in milli-seconds:

Minimum = 19ms,
Maximum = 20ms, Average = 19ms

This is what most IT Pros are seeing. Let’s try to use this information.

Now we are talking.
This give us an object that we can use.
There is just one problem, we are relying on ICMP Echo Requests. If you have PowerShell remoting turned on,
you can actually use it to verify if a client is online. Take a look at the code.

For every node that we pass to this cmdlet, a custom object
is created. We provide the value on the
ComputerName and the DateTime that we are testing. We also set the value for Online to be $False. Next, we attempt to create a PowerShell
Session to this remote client. If the
connection is made, we set the value of Online to $True and close the session. We then place the object in the
pipeline. If the session does not get established,
then the object is placed in the pipeline with the Online value still set to $False.

PowerShell remoting is already enabled on all Windows Server
2012 and newer. Why not enable it on
your clients? This allows your remote
connections to use WS-MAN as the remoting protocol as opposed to the older
DCOM.