Introduction
It has been no secret that you can do amazing feats of integration when coupling ServiceNow with a local MID Server. MID Servers give us the ability to launch remote commands, load custom JAR files, etc.
One little-known fact about ServiceNow MID-Servers is that they can also leverage PowerShell v2.0 on compatible Microsoft Windows devices. This has started to gain traction in the Runbook Automation product for ServiceNow, but you can also leverage this power for your custom integrations to third party Windows products that have API’s that are compatible with PowerShell.
I have created a Powershell library, and an accompanying utility, that can be uploaded to your ServiceNow instance to make your life easier when it comes to either PowerShell integrations or Runbook development with PowerShell workflow steps.
Pre-Requisites
You must have a MID Server installed on a Microsoft Windows machine with PowerShell v. 2.0 setup. Also, if you have Enhanced Windows Security enabled, you must unblock the Powershell modules in the MID Server. See this link: Unblocking the MID Server Powershell Modules
You must also set “Powershell” as a capability on the MID Server.
For remote powershell execution (executing powershell scripts on a Windows computer that is NOT the one hosting the MID Server) you will need to have the Runbook Automation product from ServiceNow and set up the credentials for the remote device.
PowershellProbe Library
The Update Set provided here will create a Script Include called “PowershellProbe”. This library allows you to quickly and easily generate PowerShell commands through the MID Server.
PowerShellProbe( midserver, psServer )
The Class Constructor
- midserver (optional) – The name of the MID Server that will process the command
- psServer (optional) – The IP Address of the computer that the Powershell Script will execute against. The localhost ip address (127.0.0.1) indicates that the Powershell script will run on the same machine as the MID Server. If you have Runbook Automation enabled on your instance, you can execute the powershell script on a remote computer. The remote computer must be a Windows devices in the domain that trusts the Windows box hosting the MID Server. Runbook Automation allows you to store Windows Credentials that can be used to authenticate against the remote machine to execute the desired script.
setPSServer( psServer )
Sets the PowerShell device IP Address. This is typically used if you did not specify the address in the constructor when you instantiated the class.
- psServer – The IP Address to the windows device that will execute the Powershell Script
setMIDServer( midserver )
Sets the name of the MID Server that will process the Powershell Request. This method is typically used if you do not specify the MID Server in the constructor when you instantiated the class.
- midserver – Name of the MID Server (eg. WinMid1)
setScript( script )
Stores the PowerShell script that will be executed remotely
- script – The script string
setMaxWait( seconds )
Set the maximum number of seconds that you will wait for a response from the MID Server on this request before you move on. If you don’t call this method, the default max wait time is 60 seconds.
- seconds – Maximum number of seconds to wait for a response from the MID Server on this request (if you choose to wait at all).
execute( waitForResponse )
Sends the request to the ECC Queue for processing. If you choose to wait for the reponse, the method will return an object that contains an “output” variable and and “error” variable. The output variable will contain the text from the Stdout buffer. The error variable will contain the text from the StdErr buffer.
- waitForResponse (boolean) – Optional. The value of true will hold the script until the MID Server has responded, or until the maxWait period has expired.
Code Example
Here is a snippet of code that we can use to test our setup:
1 2 3 4 5 6 7 8 9 10 | var pb = new PowershellProbe("EC2WINMID1", "127.0.0.1"); var script = "$myVarName = 'John Andersen'\n" + "Write-Host $myVarName\n"; pb.setScript(script); var response = pb.execute(true); gs.log("OUTPUT: " + response.output); gs.log("ERROR: " + response.error); |
When executed, we get the following response:
*** Script: OUTPUT: John Andersen *** Script: ERROR: null
The Powershell Utility
Sometimes we need to test out our PowerShell scripts before we actually put them into code. Additionally, it is often common that the person developing the ServiceNow scripts does not have easy access to the Windows device that will be executing the commands. This update set provides a GUI Utility that allows you to experiment with Powershell scripts against the target machine from within your ServiceNow instance.
To get to the utility, simply browse to: “MID Server->PowerShell Utility”.
Once you get there, you will be present with the GUI PowerShell utility. Enter in a valid, running, MID Server. Then type in the remote Windows device IP Address that will execute your PowerShell script. The IP Address of 127.0.0.1 tells the MID Server to execute the script on the same box that is hosting the MID Server.
Once you type in your script, click the “Submit” button. The utility will wait for the response to complete and then it will pop up a dialog box with the result and any errors.
The default Max Wait time for the utility remains at the default time for the PowershellProbe library. However, you can change the default max wait time by setting the following System Property:
com.snc.integration.powershellprobe.maxWaitTime
Provide an integer value that represents the maximum number of seconds that the probe will wait for a response from the MID Server.
Download the Update Set
use at your own risk.
Hi John,
Good job it’s help me.
I have one question.
I have a powershell script abc.ps1.I want to execute same. Please let me know.
1. Where we put this script (On MID Server) ?
2. How can I execute this ?
3. How to pass some parameter to this script ?
Thanks,
Sanjeev Kumar
So I won’t see that “PowerShell Utility” under Mid-Server without this Update Set? Forgive me, but I’m really new to SN, and I’m having issues getting my PS to work with Runbook.
I’m curious if I need to work on our Runbook server too. It doesn’t seem to have the Powershell ISE installed, and only has .net 2.0 enabled on a 2008 R2 environment. To add ISE, it seems to require .net 3.5.1 at least.
@Tom. Correct, you will not have this utility without the update set. It is not required for Powershell activities to work with Runbook Automation / Orchestration, but it can be a handy tool. If you are having issues right now without my update set, and you have Runbook installed on your instance, then this update set will not solve your problem.
Will this only work with v2 or can it work with later versions as well?
@CJ – I haven’t had a chance to check it out. YMMV. If you do try it out, let me know what you find.
@John – I was able to get v3 to work but had to uninstall the dotnet and reinstall it to get everything flowing correctly. I think that was an issue on my end though rather than a step in the install.
So in short, yes, it does work with v3.
@John – I’m having trouble figuring out how I would pass Variables to the script.
For example, how would I get current.assigned_to to evaluate to its value and have that value get passed to the Midserver for execution in a PS script?
Any ideas?
NM – My mistake. Comes from not knowing Javascript well enough. Just had to break the string down and let the variable evaluate outside of it and put it all back together again.
Thanks John!
I only needed the PowershellProbe Library for my purposes, and it worked well.
However, I had to perform a couple extra steps in my environment to get it working:
For the Calgary version, I had to replace the following functions:
Replace Packages.com.glide.ui.SysAttachment with GlideSysAttachment
Replace Packages.com.glide.util.StringUtil with GlideStringUtil
I also had to unblock all of the PowerShell scripts in the \agent\lib folder.
Thanks for sharing Brett! I haven’t modified it for calgary yet, so we’ll let people follow your instructions here until I get time to update it.
Hi John,
Thanks very much for this. I have it working perfect with on my windows 8.1 Pro MID server (home PC) but I get this error on 2008 R2, when running simple command like “dir”:
AuthorizationManager check failed.At line:1 char:5+
Hi John,
I recently upgraded to Eureka, and the first time I attempted to run a powershell script I received the following error. “The term ‘scripts\PowerShell\PSScript.ps1′ is not recognized as the name of a cmdlet, function, script file, or operable program..’
Is there a property or something that I can check to see what working directory I’m using, or any other troubleshooting steps that you would recommend?
Thanks!
Download link is down.
@william @tommy – the link has been restored…sorry for the inconvenience.
Hi John,
I want to thank you for making this post, this really help me.
Hi John.
I hope all is well with you.
Great Article you have here! I was wondering if you ever managed to have this working with encrypted parameters, on the payload? And if So would you mind sharing what was your approach?
Thank you.
Sincerely,
Marcio Silva
Thanks for restoring the link!
So beautiful !
Initially it doen’t work with Kingston.
But I just need to change Packages.com.glide.util.StringUtil to GlideStringUtil from UI pages and Script includes.
Thanks a lot !
Interesting topic, your writing skill is really very appreciative. I love when you share your views through the best articles. Keep sharing and posting articles like these.
When I executed below script on background script i am getting below error
“Illegal attempt to access class ‘com.glide.util’ via script”
var pb = new PowershellProbe(“Powershell”, “192.168.1.103”);
var script = “$myVarName = ‘John Andersen’\n” +
“Write-Host $myVarName\n”;
pb.setScript(script);
var response = pb.execute(true);
gs.log(“OUTPUT: ” + response.output);
gs.log(“ERROR: ” + response.error);
Hi John,
Even i am trying to run powershell script on mid server. However, i get the following error in the input message of ecc queue:
The error is:
error=”Unable to find script(s) specified in parameters. Make sure the script(s) associated with probe are passed down properly.” probe_time=”0″ result_code=”82″
Can you please help me understand what the issue might be and how do i fix it.
Hi John,
Set-ADUser command is not working from service now.I’m using your update set.whereas other ps commands like get-aduser,get-date,writehost works good.What may be the issue.
When I executed below script on background script i am getting below error
“Illegal attempt to access class ‘com.glide.util’ via scriptâ€
var pb = new PowershellProbe(“xxxxxxxxâ€, “xxxxxxxxâ€);
var script = “$myVarName = ‘John Andersen’\n†+
“Write-Host $myVarName\nâ€;
pb.setScript(script);
var response = pb.execute(true);
gs.log(“OUTPUT: †+ response.output);
gs.log(“ERROR: †+ response.error);
Cheers to John first,
Then to try to assist on a couple of topics.
You can encrypt anything in SN via OOB GlideEncryptor(). Note that Base64 is usually doing hex, but once in a millenia you need binary data. I done it with adding JS lib. So yea, you can pass and read crypted data.
For the AD – folks are kind of mistaken AD wiyh Azure. Both are very different guys. For Azure you use web calls (although there is an addon for Azure to have PS as well). Even if your SSO might work ypu reach to ADFS server hence read only and restricted one.
A question to John – @John I think we do not need Orchestration pack to achieve this. Just a custom activity or only backend would suffice, aint it? As I dont want to force my customers to pay extra only for that. Havent tested it yet, so wanted to get your opinion on this one 🙂
Cheers,
George – Joro
@Karl,
If you use custom application, you must call every script include with ‘global’ appended infont. If you call for ex StringUtils it would become global.StringUtils. Otherwise no access to the scipe. Similar thing happens with custom scoped tables. You must define in the table definiton if its accessible from other scopes and so on (third tab in the table def form)
Hope that helps. Let us know if you done it or not.
Cheers,
George – Joro
Hello All,
I am getting the “Illegal attempt to access class ‘com.glide.util’ via script” error when trying to execute the below statement.
Get-ADUser -Filter * -SearchBase “CN=Users,DC=xxxxxxx,DC=com”
I have my midserver installed and i am able to execute the above statement from my midserver that returns all the AD users.
I tried this using the Kingston version and also modified the script includes and UI Pages to use “GlideStringUtil” instead of “Packages.com.glide.util.StringUtil” as mentioned by Sébastien L. I even activated the plugin com.glide.script.packages_call_removal as mentioned in post https://community.servicenow.com/community?id=community_question&sys_id=e8adcf2ddb9cdbc01dcaf3231f961996 , still no luck. Any help would be appreciated.
hi john,
any one knows then please help me out am new to sn
i retrieved this update set in my personal instance …….but am confused the script which is inside the PowershellProbe is different and the xml code is different and i want to test my set up…..can anyone please tell me where do i have to put this code:
var pb = new PowershellProbe(“EC2WINMID1”, “127.0.0.1”);
var script = “$myVarName = ‘John Andersen’\n” +
“Write-Host $myVarName\n”;
pb.setScript(script);
var response = pb.execute(true);
gs.log(“OUTPUT: ” + response.output);
gs.log(“ERROR: ” + response.error);
thanks in advance!!
On our DEV instance, we have one mid server and two ldap connection strings, one is connecting to our DEV AD & another is connecting to our PROD AD to pull users and groups from DEV & PROD respectively.
The utility is always picking up PROD connection details and running the powershell CMDLET against our PROD AD. I would like to run it against our DEV AD. Any help would be appreciated.
For us, installing the Packages Call Removal Tool and the fixing the script allowed us to get rid of the “Illegal attempt to access class ‘com.glide.util’ via script†error when trying to execute the below statement.
I installed the Packages Call Removal Tool, but now getting the following, not sure how to fix.
& { [Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8; Write-Output SNC_PowerShell_PID=7008; & ‘scripts\PowerShell\PSScript.ps1’ -computer ‘127.0.0.1’ -script ‘C:\Windows\TEMP\script2235188592611274846.PS1’ -useCred False -ismid True -isDiscovery True -debug False -logInfo False -skipTest False -executeRemote False -copyScriptToTarget False; exit }
The payload retrieval doesn’t work if it gets returned as attachment in the ecc_queue. Please update code to use this instead:
_getPayload: function(ecc) {
if (ecc.payload != “”) {
return ecc.payload;
}
var SysAttachment = Packages.com.glide.ui.SysAttachment;
var sa = new SysAttachment();
var payload = sa.get(ecc, “payload”) + “”;
return payload;
},
Hi John
I’ve used this utility, loads and it really helps.
I have this suggestion for the response ui page (remove the packages calls)
<—
var rString = RP.getWindowProperties().get(‘powershell_response’);
var xmldoc = new XMLDocument(GlideStringUtil.unEscapeHTML(rString));
var output = xmldoc.getNodeText(“//response/output”);
output = GlideStringUtil.base64Decode(output);
output;
var rString = RP.getWindowProperties().get(‘powershell_response’);
var xmldoc = new XMLDocument(GlideStringUtil.unEscapeHTML(rString));
var error = xmldoc.getNodeText(“//response/error”);
error = GlideStringUtil.base64Decode(error);
error;
<–