Making your (Powershell) job work for you

Jobs are a in many ways the key to Powershell multithreading. Having jobs running in the background not only allows you to keep working in your console while your script is silently churning away in the background, but it also lets you run multiple commands or scripts simultaneously executed from console.

When to use jobs

Whenever you’d like to run a command or a scriptblock without locking up your console, or when you’d like to run multiple commands simultaneously. Jobs are “fire and forget” tasks that you don’t review until they’ve completed or failed.

When not to use jobs

When running basic administration tasks where you’re reviewing output or the result of command continuously, or when working with result sets in variables where you’d like to keep reviewing the current value of the variable.

Ways to use jobs

There are two ways of using jobs in Powershell. First of all, many cmdlets have the parameter “-AsJob” to allow them run in the background directly. Alternatively you can use the cmdlet Start-Job to initiate a job with any cmdlet of combination of commands.

-AsJob

Some cmdlets that has the -AsJob parameter are:
Get-WmiObject
Invoke-Command
Invoke-WmiMethod
Remove-WmiObject
Restart-Computer
Set-WmiInstance
Stop-Computer
Test-Connection

If you like to find a more complete list, use the following command.

NB. Keep in mind that you need to load the modules your looking for commands in, in advance. Module autoloading doesn’t work when looking for parameters (Tested with Powershell 5.0 in Windows 10 Technical Preview)

Cmdlets

There are 4 cmdlets that are key to using Powershell jobs:

Start-Job

Starts a background job to execute one or more Powershell commands.

 Get-Job

Collects and lists the running and completed jobs currently in memory

 Receive-Job

Presents the result of a job to screen, or otherwise lets you collect or manipulate the result

 Remove-Job

Removes one or more jobs from memory

 Other useful cmdlets:

Suspend-Job: Pauses a job.
Resume-Job: Resumes a paused job.
Stop-Job: Stops a job.
Wait-Job: Suspends the command prompt until a job is finished, preventing you from making the input.

Powershell Port Scanner

Would you like to know what ports are open on a host? With the introduction of Powershell 4.0 there’s a new cmdlet called Test-Netconnection which in it’s simples form basically is ping. It does, however, have some more advanced features, like scanning towards ports on a host.

Here’s a quick and dirty script to scan a single host for single port, or a sequential range of ports.

I have to admit that I miss the -Source switch in “Test-Connection” that allows you to choose where the connection request should originate, but perhaps we’ll see that in Powershell/WMF 5.0?

Techtip: One-liner to get free space

Say you’d like to copy an exuberant amount of data from one server to another and you’re unsure if the target disk has sufficient space. Perhaps you’d simply like to know how much space you’ve got.  There are several way to check this, but here’s one more, and in my opinion the fastest:

Run this one-liner from any computer, and as long as you run it a user context where you have user rights on the server, you will get the amount of free space in GB.

You can also use this a basis for a script listing out renaming space on several computers or several disks on a single server, but that might be the subject for another article!

Solving ReFS integrity bit issues when working with Hyper-V

I was working with Hyper-V and I got the following error:

Export failed for virtual machine ‘webtest01’ (16CED29C-F6B2-4D86-91D1-DDBD635D24C2) with error ‘The requested operation could not be completed due to a virtual disk system limitation. On NTFS, virtual hard disk files must be uncompressed and unencrypted. On ReFS, virtual hard disk files must not have the integrity bit set.’ (0xC03A001A).

The volume I’m working on was an ReFS volume on a Storage Pool located on my test environment. I tried troubleshooting this issue, but there is hardly any good help online. Googling the issue gav me a few obscure Technet references and some rather incomplete blog posts, so this article is a concatenation of the information I found.

List out the files in your “Virtual Hard Disks” folder using this command:

Change the integrity bit on files using this command:

Or, use this one-liner:

I hope this helps shed some light on this issue.

Using Powershell to identify Child Processes

I got a challenge yesterday on how to identify child processes, and googling it led to the conclusion that this is either not a common issue or no one knows the answer.

My issue was this: if a child process locks up or needs to be killed, how do we identify the process using powershell. The thing about finding child processes is that you need to know who their parents are. In fact, you need to use the parent process id (PID) to identify the child.

How does it work?

First choose how to identify the parent process in Powershell. You can usually use ProcessName, Description, Path etc. Then you need to find any process which has the ParentProcessId of it’s parent (obviously)!

Here’s my solution:

$procid = (Get-WmiObject win32_process | where {$_.ProcessName -eq ‘Powershell.exe’} | select processid)
Get-WmiObject win32_process | where {$_.ParentProcessId -eq $id}

This only identifies the child process, what you’d like to do with it afterwards is your call. Nonetheless, this could help you automate some of the tasks you’ve been using Process Explorer to solve until now.

Techtip: Connecting to iSCSI targets via Powershell

Imagine wanting to set up two or more nodes in a file cluster and wanting to avoid configuration mismatches creating a troubleshooting nightmare even before putting your solution into production! How would you best go about doing that? Script it, and run the script throughout your nodes!

In this article I’d like to focus only on a very simple iSCSI target scenario. Two commands letting you create a persistent connection to an iSCSI target using Powershell. This in turn will let you do the exact same on every server you’d like to remain identical. You could even run it in a foreach loop letting you execute the same command set across a number of nodes without even having to log into them, and I’ll get to that in a later article.

First, connect to your iSCSI server:

Second you need to find your iSCSI target and connect to it. If there’s only one target on your server then you’ve got an easy time, but in case there are several, you should filter by it’s name, like this:

Replace fileshare1 with the name of your iSCSI target. You might want to test your filter before running the command and if so, simply omit the “Connect…” command after the pipe above and make sure the result set only contains the targets you’d like to connect to.

Of course there’s more, and if you’d like to delve deeper, please check out this blog: