Wednesday 26 September 2007

Embed a Powershell Script in a Management Pack

- Updated -

OpsMgr R2 allows you to embed powershell scripts in a MP - See this MP for an example - http://derekhar.blogspot.com/2009/11/new-agent-maintenance-mode.html

----------

If you want to run powershell, perl or any other scripts not run by cscript.exe from a management pack then you invariably had to create the script and distribute it across all the servers where it needed to run. This could easily become quite complex maintaining all these scripts in multiple different locations. If you are in a situation where you have multiple management groups and none of them are quite the same then you could have multiple different versions of the script and the rule that would call the script.

To avoid this problem it is now possible to embed other scripts in a management pack, not just vbscript and jscript.

To explain how this is done we need to break in to the XML. Open the image below to view the full command. This would be executed using on a recurring basis using a System.Scheduler datasource.



The Write Action aboves enables proxying for all management servers. This check is quite easy to do using the command shell alias.

<ApplicationName>%systemroot%\System32\windowspowershell\v1.0\powershell.exe</ApplicationName>

This line launches the Powershell exe. Remember that Powershell must be installed on any server you are targeting the rule at. The same goes for any other script language that you wish to use.


<WorkingDirectory>%MOMROOT%
</WorkingDirectory>

The %MOMROOT% variable point to the Installation path of OpsMgr. This is useful when targeting Powershell scripts at the RMS or Management servers as it allows you to easily load the Command Shell Snap-in. This then gives access to all the Command Shell aliases.


<CommandLine>-Command "&amp; '$File/EnableProxy.ps1$'"</CommandLine>

The arguments being passed specifies to run the script $File/EnableProxy.ps1$. After this the file must be entered.


<Files>
<File>
<
Name>EnableProxy.ps1</Name>
<Contents>

The name of the script must match the command line name. While I have not tested this there appears to be the ability to embed multiple files here.

Now we drop into the script itself. This rule is targeted to run only on the RMS so $rootMS is set as localhost. The next 3 lines load the Command Shell snapin, and opens the connection to the local management group.

$rootMS="localhost"
add-pssnapin "Microsoft.EnterpriseManagement.OperationsManager.Client";
set-location "OperationsManagerMonitoring::";
new-managementGroupConnection -ConnectionString:$rootMS;


Here is an example Management Pack

21 comments:

Pete Zerger said...

Derek, I think is a topic worth expounding on in some detail when time allows.

Pete Zerger
http://systemcenterforum.org

Pete Zerger said...

And would you not want to use the CDATA designation to avoid potential misinterpretation of special characters contained within the script?

Derek Harkin said...

I will do another post on this in more detail.

I generally do not use CDATA as the authoring console and my XML editor (Notepad++ with the XML Tools plugin automatically escape the special charachters.

Tim McFadden said...

Derek is it possible to return state data back to SCOM such as good warning and bad. Simlar how we can do with vbscripts?

Derek Harkin said...

Timothy,

I have not tried it but I assume that returning the data back to OpsMgr would be performed using the MOM.ScriptAPI com object so if you are able to utilize the the object from the scripting language you are using then I don't think you would have a problem.

For example in Powershell you would use $momapi = new-object -comobject MOM.ScriptAPI.

Unknown said...

Is it possible to pass overridable parameters to the script from the SCOM rule?

Derek Harkin said...

I tried this out but could not get it to work.
What I did was create a write action module with overrides that contained the script.
I then created a rule taht used that module but I could not get the override passed in correctly.
I think it has something to do with the $ character being used for variables in powershell and for override parameters. There may be an escape sequence but I do not have th etime right now to look at this right now.

I have posted the currrent MP at http://cid-397bb61b75cc76c5.skydrive.live.com/self.aspx/Public/PowershellScriptOverrides.xml if you want to give it a shot.

DavidClapp said...

I was able to use your MP. However, now I have rule that collects information based on what values my powershell script outputs to the MOMScript.API.

Now I imagine I need a monitor to assess this output that is being collected. Any thoughts on how this would be done? I just need an example of a monitor and how it would relate to the rule running a powershell script.

Thank you,
David Clapp

Anonymous said...

Great information.

I have tried your script embedded in recovery section.
However, it did not work.

Is there any thing specifically needs to be done for executing from recovery section of management pack?

Derek Harkin said...

The script as written will only work on the RMS.

Where is the recovery action running?I would assume that it is running on the system that generated the alert.

Anonymous said...

Thank you Derek.


Where is the recovery action running?I would assume that it is running on the system that generated the alert.

Answer: Yes you are right. The recovery action is running on the system that generated alert.

What changes I need to make so that the script will work?
Could you suggest please?

Anonymous said...

Just wanted to add more info to my previous questions.
1. I made sure that system that generates alerts has all required snapins.
2. Instead of localhost , I changed to my managementnode serverin the script.
3.I also run the script lines manually from(powershell v1.0) the system that is generating alert.

The script run successfully.

I am stuck at this point , I would appreciate any of your comments.

Here is the embedded script in recovery section.

$rootMs = "MSmgmtnode.Jpack.lab";add-pssnapin -name Microsoft.EnterpriseManagement.OperationsManager.Client;set-location "OperationsManagerMonitoring::";new-managementGroupConnection -ConnectionString:$rootMs;set-location $rootMs;$ms = get-managementserver; foreach($agent in $ms){ if($agent -ne $null){$agent.ProxyingEnabled = $true;$agent.ApplyChanges()}}
--RV

Derek Harkin said...

It is likely a permissions issue. The script will be running using the Local System Account of the server where it runs so will not have access to make these changes

Anonymous said...

Thanks Derek for the quick response.

I made it unrestricted policy at run time.Still did not work.

Any suggestion to have script access to make these changes at run time?Is there any other way to set permission.?

RV

Derek Harkin said...

the permissions I was referring to was the account being used time run the script. I think to make this change the user running the script must be a member of the operations manager administrators group.

By default in opsmgr the default action account for an agent is the local system account. You could workarpund this using a run as account in the mp

Anonymous said...

Thank you Derek Harkin .

Now I could do recovery action remotedly for SCOM.

Now, I am trying to run some SCVMM commands remotedly from recovery section.
I have installed Adminconsole of SCVMM.I can launch the powershell which comes with SCVMM and execute scripts remotedly successfuly.

The problem I have is, I launch the powershell (installed from windows2008 server )and try adding VMM snapin. But I receive the message VMM snap in not found.

Not, sure what I am missing to execute SCVMM commands from recovery section.

Any help is highly apprecaited.

RV

Anonymous said...

Thank you Derek Harkin .

Now I could do recovery action remotedly for SCOM.

Now, I am trying to run some SCVMM commands remotedly from recovery section.
I have installed Adminconsole of SCVMM.I can launch the powershell which comes with SCVMM and execute scripts remotedly successfuly.

The problem I have is, I launch the powershell (installed from windows2008 server )and try adding VMM snapin. But I receive the message VMM snap in not found.

Not, sure what I am missing to execute SCVMM commands from recovery section.

Any help is highly apprecaited.

RV

Anonymous said...

Derek,
I fixed the issue.
Thank you .

RV

Anonymous said...

Hi Derek,
Do you have any example for Recovery action posted ?
I am not able to get hostname and PRO tip in Recovery section of MP.

Any help is highly appreciated.

Thanks in advance.

RV

Anonymous said...

Derek,
Happy Christmas!!

Have a quick Question.

Hi All,

I see this error when I implement the PRO tip in SCVMM.

===============
Complete Error Text:
===============
You Cannot contact the virtual Machine Manager server.The Credentials provided have insufficient privilages on "servername"(Error ID 1605). Ensure that your account has access to the virtual machine manager server "servername" , and then try the operation again.

More info about my setup

1. I have a SCVMM , SCOM on a single management node server.
2.Have a cluster with 5 hosts , server1,server2,server3,server4 etc in the cluster(Hyper v enabled)

3. On selecting implement button on PRO tip window in SCVMM, The powershell started executing on server2 server but it failed to connect to SCVMM server remotely and hence failed.


I could successfully connect remotely to SCVMM server from server2 by manually executing powershell commands.

Note: I have SCVMM admin console on server 2 and snap in is also present.

Questions
1. Why does powershell executing on server2?
2. Why not it is running on Management server(SCVMM)?
3. What should be done to make power shell scripts to execute on management server regardless of which host server is expereincing problems.
4. how do I fix this problem.?

Thank you, appreciate your help.

Anonymous said...

Derek,
What if Powershell exection needs more than 180 seconds?

Can this "TimeoutSeconds" of 180 be configurable?

Can we override this value through MP?