Some time ago I started a project to host a JavaScript engine within PowerShell. I initially called it PowerChakra because, well the engine was IE’s Chakra engine, however I’ve renamed it PowerShellJS and I have semi-plans to also support the V8 engine that Node.JS uses as well. I just added initial support for TypeScript to PowerShellJS now that TypeScript 1.0 has landed.
So what can this do?
- Create MULTIPLE Javascript instances and run things in them. Interact with them with the *Session* metaphor like PSSession.
- Invoke Javascript with or without Results.
- Get base types back as their equivalent PowerShell/.Net Types
- Get JSON results (which can easily be turned into PSObjects with ConvertFrom-Json
Why on earth would I want to do this?
- To experiment with Javascript and/or TypeScript.
- Do some stuff in JavaScript because its just faster than PowerShell (burn)
- PowerShell is a “Glue” language, and this provides glue to what has become one of the language programming languages in the world, allowing you to use a lot of code and algorithms written in JavaScript.
- Some of my other Secret Sauce i’m not telling you about.
Where can I get this?
- On Github at https://github.com/klumsy/powershelljs
- In the future i’ll put the Package on Chocolatey and MS’s new OneGet.
So how do I use it?
Once the module is loaded you can simply
Invoke-JS "function y(x) { return x + x};y(20)"
But that will create an instance of the engine, run the code, return the results and get rid of the engine. Often you want to create a JavaScript engine, keep it around for a while, and do a bunch of things in it.
Import-Module PowerShellJS New-JSSession -Name test #invoke an expression, in a session, and DON'T RETURN RESULTS Invoke-JS -Name test -Script "var x = 5; function add(y){return y+y}" -NoResults #reuse the session, running a function previously applied AND return results. Invoke-JS -Name test -Script "add(x,10)"
And sometimes you’ll be dealing with complex JavaScript Objects, which won’t translate automatically into a base dot net object, so you can convert it to a JSON String, and then from there convert it to a PowerShell Object if you desire..
#create a nested PS object invoke-JS -Name test -Script "var ourobj = {name : 'PowerChakra', numbers : [1,2,3] , something: { x:1} }" -NoResults #get object as JSON, then convert to PS object $objectasJSON = invoke-JS -Name test -Script "JSON.stringify(ourobj)" $objectasJSON $objectasPSobj = ConvertFrom-Json $objectasJSON $objectasPSobj | fl
In a future release I plan something like Get-JSVariable -AsJSONString and Get-JSVariable -AsPSObject
In the next blog post, I cover Running TypeScript in PowerShell with PowerShellJS