VMware Cloud Community
admin
Immortal
Immortal
Jump to solution

Package PowerCLI script into Windows executable file / install

What are the options for packaging / embedding a PowerCLI script into a Windows .EXE file? I'd like for several departments to be able to run and collect details from the script without having direct access to the code. This would ensure the code was run correctly without modifications.

I know that PowerCLI will be available on these systems, so checking for PowerCLI is not necessary.

I've read that Primal Script has this capability, but I'd like a free and easily manageable solution, if possible.

If not an executable file, maybe even an encoded file that makes it difficult for a laymen to make modifications.

Thanks in advance for the help!

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I used a similar function from Johan Akerstrom in the past (since I don't have the Community Extensions installed).

See his Powershell script to generate an executable from a powershell script post.

For this one I know there are no problems with passing parameters.

Take this sample script

param(
[parameter(Mandatory = $true)][string[]]$server)

[void][system.reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
Add-PSSnapin -Name VMware.VimAutomation.Core

Connect-VIServer
-Server $server
[windows.forms.messagebox]::Show("Connected to " + $defaultViServer.Name)
$VM
= Get-VM
[windows.forms.messagebox]::Show("I counted " + $VM.Count + " guests") Disconnect-VIServer -Confirm:$false

Notice that the script uses Windows Forms to output data.

You create the EXE as follows. I saved the sample script as DoExeTest.ps1

PS C:\Scripts> New-PSExecutable .\DoExeTest.ps1
Source script file: C:\Scripts\DoExeTest.ps1
Output executable : C:\Scripts\doexetest.exe

And when you run this, it will display 2 message boxes, one with the name of the vCenter and one with number of guests the script found in the vCenter.

C:\Scripts>doexetest.exe "MyVC"

EXE-vcenter.png               EXE-count.png


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
15 Replies
LucD
Leadership
Leadership
Jump to solution

Try Keith Hill's Make-PS1ExeWrapper.

It requires the PowerShell Community Extension but both are free 🙂

Note that there is another commercial product that can do this beside Primal Script, it's called PowerWF Studio.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

DSTAVERT
Immortal
Immortal
Jump to solution

Just a though. Would it be possible to take powerGUI source code and remove the components that would allow direct access to the script.

-- David -- VMware Communities Moderator
Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD wrote:

Try Keith Hill's Make-PS1ExeWrapper.

Thanks for the quick reply. I tried Make-PS1ExeWrapper and it does indeed create an executable file. However, it doesn't seem to handle arguments at all. The following test script runs with zero output, regardless of if a parameter was passed in or not

param(
      [parameter(Mandatory = $true)][string[]]$test
)

Write-Output $test

I'd like to have parameters to be able to pass in the vCenter server, username, and password as this will change and cannot be hard-coded.

Have you used the wrapper before? Do you know of any other way to have such dynamic values in the EXE?

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

David Stavert wrote:

Just a though. Would it be possible to take powerGUI source code and remove the components that would allow direct access to the script.

I'm not sure I understand. Are you suggesting modifying the source code of PowerGUI (the program) so that it can execute scripts without the option to edit them? If so, that's probably beyond my skill level and will probably make distributing a little tougher.

Please let me know if I misunderstood.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I used a similar function from Johan Akerstrom in the past (since I don't have the Community Extensions installed).

See his Powershell script to generate an executable from a powershell script post.

For this one I know there are no problems with passing parameters.

Take this sample script

param(
[parameter(Mandatory = $true)][string[]]$server)

[void][system.reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
Add-PSSnapin -Name VMware.VimAutomation.Core

Connect-VIServer
-Server $server
[windows.forms.messagebox]::Show("Connected to " + $defaultViServer.Name)
$VM
= Get-VM
[windows.forms.messagebox]::Show("I counted " + $VM.Count + " guests") Disconnect-VIServer -Confirm:$false

Notice that the script uses Windows Forms to output data.

You create the EXE as follows. I saved the sample script as DoExeTest.ps1

PS C:\Scripts> New-PSExecutable .\DoExeTest.ps1
Source script file: C:\Scripts\DoExeTest.ps1
Output executable : C:\Scripts\doexetest.exe

And when you run this, it will display 2 message boxes, one with the name of the vCenter and one with number of guests the script found in the vCenter.

C:\Scripts>doexetest.exe "MyVC"

EXE-vcenter.png               EXE-count.png


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD wrote:

I used a similar function from Johan Akerstrom in the past (since I don't have the Community Extensions installed).

See his Powershell script to generate an executable from a powershell script post.

I'm having problems using that script. An EXE is generated but running it via double-click, through the CMD prompt, etc. shows no output or seemingly any process.

I've tried copying / pasting the function into a PowerCLI console directly against your test script (Test1.ps1 attached):

[vSphere PowerCLI] C:\Scripts\> New-PSExecutable .\Test1.ps1
Source script file:   C:\Scripts\Test1.ps1
Output executable :   C:\Scripts\test1.exe

I've tried commenting out the first and last lines to save it as a script itself:

[vSphere PowerCLI] C:\Scripts\> .\New-PSExecutable.ps1 .\Test1.ps1
Source script file:   C:\Scripts\Test1.ps1
Output executable :   C:\Scripts\test1.exe

I've also tried the above using a "Hello World" script (Test2.ps1 attached).

I'm assuming the script is working since Test1.ps1 and Test2.ps1 produce different size executables. But I'm not sure what I'm doing wrong when trying to execute the script.

FYI, both test scripts run as expected in the PowerGUI Script Editor or the PowerCLI console.

adfljaflj
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

For Test1.ps1 the problem is most probably due to the "mandatory" parameter you specified.

When you double-click there will be no parameter and the script will exit with an error (that you don't see of course).

The script Test2.ps1 should work without a problem.

I assume you are using PowerShell v2.

Which client platform are you using for testing ? 32- or 64-bit ?

I did all my tests on a 32-bit platform.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Just did the test on a 64-bit platform (W2k8 R2) and the EXE works without a problem.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD wrote:

I assume you are using PowerShell v2.

Which client platform are you using for testing ? 32- or 64-bit ?

I did all my tests on a 32-bit platform.

I'm using PowerShell 2.0:

[vSphere PowerCLI] C:\Scripts> $Host.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
2      0      -1     -1

My client is Windows 2003 SP2 32-bit.

I'm having problems with Get-PowerCLIVersion, even though I've confirmed it's 4.1.1 in Windows' Add / Remove Programs (SS attached).

[vSphere PowerCLI] C:\Scripts> Get-PowerCLIVersion
Get-PowerCLIVersion : Object reference not set to an instance of an object.
At line:1 char:20
+ Get-PowerCLIVersion <<<<
+ CategoryInfo          : NotSpecified: (:) [Get-PowerCLIVersion], NullRef
erenceException
+ FullyQualifiedErrorId : System.NullReferenceException,VMware.VimAutomati
on.ViCore.Cmdlets.Commands.GetViToolkitVersion

To resolve the above problem, I've tried repairing PowerCLI and uninstalling / installing it.

I'm assuming something is wrong with my client environment, but I'm not sure how to proceed. Do you mind sending me an executable that you've created in your environment for testing?

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

Syed N. Ahmad wrote:

Do you mind sending me an executable that you've created in your environment for testing?

Thanks for sending me the files. I was able to run both EXEs in the same environment that's having problems with Get-PowerCLIVersion.

FYI, the EXEs that I generated in my environment do start but immediately stop. I verified this using Task Manager.

I'm wondering if there is a dependency that is missing in my environment. Do I need to worry about this on line 17: namespace CosmosKey.Powershell.Utils? Do I need to worry about signing the EXE or some security requirement?

Message was edited by: n81acc

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The namespace value is something the author of the script defined.

It can be any name, the namespace is used to isolate the classes and functions.

Btw the resulting .EXE is not signed. With sufficient knowledge it is possible to reverse-engineer the .EXE back to the .ps1.

It looks indeed as if there is something wrong with your platform.

Can't you install PowerCLI on another client to make sure that the problem is indeed related to something on your platform ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD wrote:

Can't you install PowerCLI on another client to make sure that the problem is indeed related to something on your platform ?

I've setup a new Windows 2003 SP2 32-bit VM and installed PowerShell 2.0 and PowerCLI 4.1.1. I'm seeing the same issue in this new environnment. One area that's improved is that I can now see the PowerCLI version information.

[vSphere PowerCLI] C:\Scripts> Get-PowerCLIVersion

PowerCLI Version
----------------
VMware vSphere PowerCLI 4.1 U1 build 332441
---------------
Snapin Versions
---------------
VMWare vSphere PowerCLI 4.1 U1 build 332441

I am at a loss.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

So am I.

One more thing to check, you are sure you are running the PowerShell v2 RTM and not a Community Preview version ?

Have a look at Are you using the correct PowerShell version?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

LucD wrote:

you are sure you are running the PowerShell v2 RTM and not a Community Preview version ?

Have a look at Are you using the correct PowerShell version?

I am running RTM, especially in this new environment since I downloaded and installed PowerShell earlier today. Here are the details from both of my environments.

[vSphere PowerCLI] C:\Scripts> $PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.1433
BuildVersion                   6.0.6002.18111
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1
Reply
0 Kudos
admin
Immortal
Immortal
Jump to solution

I've found an environment (third) that runs the test scripts fine. I'll continue testing the packaging of my actual scripts and then work backwards to see what that new, third environment has that my two fresh environments didn't. Either way, I really appreciate your help, as always, LucD.

Reply
0 Kudos