NOTE: This blog article has been sponsored by Pulseway.

So you've got an awesome PowerShell script that is going to save you loads of time. You've hit Save in your editor and you pat yourself on the back. This script is meant to run against multiple servers so you sit down to make it happen to then find out it's not as easy as you'd anticipated.

Running PowerShell scripts against remote systems can lead to problems around targeting systems, dealing with remote connectivity issues and increasing performance by running them in parallel. Luckily, I've been working with a tool lately called Pulseway that eases this issue.

In this article, I'm going to show you how to execute your PowerShell scripts against a group of remote systems using the Pulseway product.

We've got a couple of persistent issues in the TechSnips server environment at the moment. The first is that we need to restart the print spooler service on all of our servers every night. And secondly, our contributors keep leaving their PowerShell ISE sessions open 24/7. I've already written some scripts to deal with these issues, and I'm going to use Pulseway to automatically run them against multiple systems.

So within Pulseway, head over to Automation, and then start in Scripts.

By default, you'll have a built-in category here, and you'll want to create your own category to file your scripts into.

I'll create my own category and call it Custom. Once the category is created, we can click into that category and choose Create Script. Give your script a name. My first one will be Restart Print Spooler Service.

Then I'll head over to the Windows tab, toggle to Enabled, and then I can select my script type. This defaults to PowerShell, which is what I want to use. However, if you need a VBScript or batch file, you switch the script type.

I'll leave that on PowerShell and enter my script. The script I'm using here is stopping the service, waiting for a couple of seconds, and then starting the service back up again.

When I'm happy with everything here, I'll click Save Script

Start-Sleep -Seconds 5
Stop-Service -Name 'spooler'
Start-Sleep -Seconds 3
Start-Service -Name 'spooler'

With that saved, I'll head back to Scripts, and I'm going to add my second script to cover my second issue. This one is going to kill PowerShell ISE sessions. However, there's a caveat on this, where I don't want to kill any PowerShell ISE processes that are owned by admin users; I'll make a note of that in the description.

Again, I'll head over to the Windows tab, ensure I'm on PowerShell and add my script.

Start-Sleep -Seconds 5
$PsProcs = Get-CimInstance Win32_Process -Filter "name = 'powershell_ise.exe'"

foreach ($Proc in $PsProcs) {
	$Owner = Invoke-CimMethod -InputObject $Proc -MethodName GetOwner
    if ($Owner.User -notlike 'admin*') {
    	Stop-Process -Id $Proc.ProcessId -Force

This script's going to get all the PowerShell ISE processes, look through them, checking for the owner using the GetOwner method, and then if the owner doesn't start with the word "admin," it's going to stop that process. I'll click Save Script to confirm.

With both of my scripts created, we now need to combine them into a task. So under Automation, choose Tasks and Create Task.

There are some extra options we can pick here before going ahead and adding our actual scripts. For instance, I do want to be kept informed about whether or not this task is running successfully, so I'll turn on notification for if the task fails. And I'll leave that as elevated, although you can adjust the level as needed.

And I also want to get a notification if the task completes successfully. However, I'm not going to leave this at normal, because I don't want my phone to make noise when this works successfully, and I have my low notifications silent, so I'll just set it to low.

The default scope is All Systems, and if you've already got another scope created, you can select it here to limit the systems that this will run on. And if you haven't already got a scope, but you'd like to create one now, there's a handy button, Create Scope, where you can get one set up now.

I'm all right with my task targeting all systems, so I'm not going to create a scope here.

But I do want to enable scheduling, as I want this to happen every night. I'll change the Repeats option to Daily, and it will happen every once a day. I want this running at about 1:00 AM, so I'll change the date to tomorrow, and I'll change the time to 1:00 AM.

In the Summary, I can confirm that my schedule is what I want, daily, starting tomorrow at 1:00 AM.

Once I'm happy with this, I'll click Save and scroll back up to the top and choose Scripts.

From here, choose your category; mine was called Custom. I'll add both of the scripts that we've defined at the start. I'll start with my print spooler service and then my ISE processes termination script.

Now, these do run sequentially, so if the order is important, make sure you've put them in the right order. And when you're happy with it, save the task.

So let's head back to Tasks, and you can see the little alarm clock icon within the cog showing you that this is a scheduled job. However, we can run this on demand so we can see a little bit closer at what's happening. I'll go into View...

...and then click Start. We can see the status of it as it runs. So we can see it's targeting four systems, and it's currently completed zero of them, and the status of the job is running.

If I pull up my ISE, I'm currently checking my print spooler service, and you can see that it was automatically stopped and then restarted.

So we know that this job has successfully run against my machine. If we check the execution history, we can see that the entire job was successful, meaning it successfully ran on the other three servers in the TechSnips server environment. I can drill into this and have a look at the systems, and I can see that each individual system successfully completed.

And if there were any failures, I could drill in deeper and have a look at the output for each individual job. As these were all successful, I expect the output to be blank, but if there were any errors, you would see them listed here.

This was a great example of how we can leverage Pulseway to help out with distributing PowerShell scripts.

If you'd like to learn more about Pulseway and give it a spin, it is available at