Generic Tasks in Operations Manager

A while back I’ve created two quick scripts which allows you to execute ANY command (batch or PowerShell) on one or more remote agent(s). In this post I will share those two scripts, the ready to use management pack and a quick guide on how to use it.  The goal for this management pack is to provide a way to not only execute a command on the agents but also capture the output and pass it back to the console.

Caution!

Needless to say that this can be very dangerous. Executing the “wrong” command can potentially harm your remote machine(s) so you have to be very careful with not only what you are sending to the remote agent but also whom you give access to this task. Always do extensive testing in a lab or test environment before you execute tasks in production!

Using the Generic Tasks

The target for the tasks is Windows Computer, so you can execute those tasks from any view you see Windows Computers (or descendants).

Note: by default, the console limits the number of selection to 10. You can, of course, select more than 10 objects in the console but you will not see any task to execute. You can remove this limitation by tweaking the registry. Read Cameron Fuller’s article on how to do it.

In this example, we open the Windows Computer state view and select an agent to execute the task for. Then we click on the Custom Command task:

As you would expect from any agent task, you are provided with the Run Task dialog. You can run the task with the default action account or provide specific credentials for the task. In order to correctly execute our task, we need to click on the Override button to specify the command we want to execute:

In the above example we override the Arguments task parameter and enter the command we want to execute (e.g ipconfig /all). We will see later in the script that our script will expect the command in the Arguments and process the passed on command. Click on Override and run the task with the command specified. Next, SCOM will show the Task Status window:

As soon as the task is finished, you’ll see the output of the command in the status window. Alternatively you can also use the Task Status view in the Console to see the output but also see who has executed the task and when:

This is very important as it allows you to somehow audit those custom tasks – in case something went wrong. As you can see, generic tasks are quite handy. You don’t have to do any configuration in SCOM to just execute a simple command. As mentioned before, it’s also dangerous and needs to be handled with care! The PowerShell task works exactly the same. Just override the task argument value with something like get-executionpolicy or some other powershell command.

How does the Custom Command Task work?

Here’s the script which is used by the task:

' Parameter: "dir c: /s"
Option Explicit
Dim oAPI, oArgs, WshShell, Exec
Set oArgs = WScript.Arguments
Set oAPI = CreateObject("MOM.ScriptAPI")

Set WshShell = CreateObject("Wscript.Shell")

Set Exec = WshShell.Exec("%comspec% /c """ & oArgs(0) & """")

WScript.Echo Exec.StdOut.ReadAll

Set WshShell = Nothing
Set oArgs = Nothing
Set oAPI = Nothing
Set Exec = Nothing

As you can see the script is very simple. We need to use the WScript.Shell object in order to capture the standard output of the command. We pass in the command to the %comspec% (cmd.exe) /c from the arguments (hence the need for overriding the Arguments in the Run Task dialog). In the end we “Echo” out all the captured standard output. The agent will then transfer the output back to the console. In case you are wondering about the MOM.ScriptAPI: this script is just the prototype. If you want to have better error handling, alerting if something goes wrong, etc. you should extend the script and do some logging. With a couple of rules, you can easily create alerts in case someone executes a script or executes it with no arguments, and so on.

How does the Custom PowerShell Task work?

Here’s the script used by the task:

' Parameter: "get-executionpolicy"
Option Explicit
Const FOR_READING = 1
Const FOR_WRITING = 2
Const TEMP_FOLDER = 2
Dim oAPI, oArgs, WshShell, oFS, TempFolder, TempFile
Dim Exec, Output, TempFileName

Set oArgs = WScript.Arguments
Set oAPI = CreateObject("MOM.ScriptAPI")
Set WshShell = CreateObject("Wscript.Shell")
Set oFS = CreateObject("Scripting.FileSystemObject")

Set TempFolder = oFS.GetSpecialFolder(TEMP_FOLDER)
TempFileName = TempFolder.Path & "" & oFS.GetTempName
Set TempFolder = Nothing

Exec = "%comspec% /c ""%windir%system32windowspowershellv1.0powershell.exe -noninteractive -command ""&{" & oArgs(0) & "}"""" >" & TempFileName

WScript.Echo Exec

WshShell.Run Exec, 0, True

Set WshShell = Nothing

Set TempFile = oFS.OpenTextFile(TempFileName, FOR_READING)

While Not TempFile.AtEndOfStream
Output = Output & TempFile.ReadLine & vbCrLf
Wend

WScript.Echo Output

TempFile.Close

Set TempFile = Nothing
oFS.DeleteFile TempFileName
Set oArgs = Nothing
Set oAPI = Nothing

As you can see, this one is a bit tricky. Back when I wrote the script for this task, we still used PowerShell v1.0 (yes, I am that old!). Somehow, PowerShell behaved differently and didn’t let me capture the output very easily. You might expect it should work just as the Custom Command Task, but it doesn’t – at least not with v1.0. Maybe it’s now different with the newer PowerShell versions but I didn’t check that yet…

Anyway, in order to get the output of the PowerShell task, we redirect it to a temporary file. We then wait until the script has finished. Once that happened we open the file with the redirected output and “Echo” it out, just like before. Afterwards we clean up and delete the temporary file.

Download

You can download the management pack and the scripts in a zip file from here.

I hope this is as useful to you as it is to me. If you have any questions, comments, suggestions or any other feedback, let me know.

cheers,
Stefan

Leave a Reply