PowerShell – Using Windows Script Component

Windows Script Component (WSC) goes a long way back. This technique is almost 15 years old, dating from Windows 2000.

But you can still use it, even by the latest Powershell version. Smile

Find here more information about what WSC is.

In short WSC gives you the possibility to create COM objects on the fly. Which you can register as normal COM objects exposing you methods and properties.

image

As you can see the WSC files show up with different Icon. If you right click it you see extra shortcut menu’s.

image

Register will register you COM object in the registry if you filled up the WSC file with the proper XML sections. The same as you would use the regsvr32.exe command line tool.

Or you can just run functions as is, without registering.

WSC supports VBScript / JScript and PerlScript.

Let’s give an example on how to access the object from within PS.

1. Create a simple WSC file.

image

<?xml version=”1.0″?>
<component id=”mywsc”>
<public>
<method name=”test”/>
</public>

</component>

 

This simple example will display a Message Box with a text as parameter, when invoked using PS.

image

You need to use the .Net [system.runtime.interopservices.marshal]::BindToMoniker to connect to the WSC object.

As you can see I use the following prefix syntax “script:…” in order to call the WSC object on the fly.

This will avoid you to register the COM object on your system. Which makes it extremely flexible. You can now adjust the WSC code on the fly and run it. As well as copy it on multiple machines without any admin overhead.

The InvokeMember has 5 parameters, which explain themselves :

1. “Test” is the name of the WSC VBScript function to call.

2. $im holds the BindingFlags method

3. Not used

4. Variable that holds the references to the WSC Object

5. Used to send across the Parameter(s) to the WSC function.

Here is the full code with some helper calls in between.

 

CLS

$test = [system.runtime.interopservices.marshal]::BindToMoniker("script:C:\_\Apps\_PowerShell\_Advanced Examples\_WSC Examples\Test.wsc")

$isObj = [system.runtime.interopservices.marshal]::IsComObject($test)

write-host $isObj

Write-host " "

Write-host "Get-Type" 

$test.GetType()

$param = "Hello World ! -&gt; From PowerShell to WSC"

$im = [System.Reflection.BindingFlags]::InvokeMethod

$test.GetType().psobject.BaseObject.InvokeMember("test", $im, $null, $test, $param)

$ret1 = [System.Runtime.InteropServices.Marshal]::GetIDispatchForObject($test)

$ret2 = [System.Runtime.InteropServices.Marshal]::GetIUnknownForObject($test)

$uObj = [System.Runtime.InteropServices.Marshal]::GetUniqueObjectForIUnknown($ret2)

$Obj = [System.Runtime.InteropServices.Marshal]::GetObjectForIUnknown($ret2) # refers back to $WSC COM object returns the GUID

write-host " "

#[System.Runtime.InteropServices.Marshal]::Release($test)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($test)

write-host "5. "  $ret1 $ret2 $uObj $obj

write-host " "

[System.Runtime.InteropServices.Marshal]::AreComObjectsAvailableForCleanup()

write-host " "

[System.Runtime.InteropServices.Marshal]::GetLastWin32Error()

rv test, im, param, isObj, ret1, ret2, uobj, obj

[System.GC]::Collect()

Enjoy!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: