I am working on a PowerShell script that creates a GUI, using classes from Windows.Forms. The script runs fine in the PowerShell ISE, but when I select "Run with PowerShell" from the context menu in File Explorer, it fails and doesn't find the functions defined in the script.
Digging a bit further into the problem, I found that the "Run with PowerShell" invocation more or less executes a command line like
powershell.exe -Command "script.ps1"
while running the script within the ISE is equivalent to
powershell.exe -File "script.ps1"
Running these two commands from a cmd window exactly reproduce what I observed: The -File version works well and the -Command version fails.
I am including a stripped-down version of the script. It creates a GUI with the buttons "Save configuration" and "Exit". The "Exit" button does what you expect, and "Save configuration" calls the functions Get-Configuration-Data-from-GUI and Save-Configuration (which both do nothing). When you launch the script in the ISE or via the -File parameter, all is well, but when you try "Run with PowerShell" or the -Command parameter, you see these errors when you click "Save configuration":
Get-Configuration-Data-from-GUI : The term 'Get-Configuration-Data-from-GUI' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Projects\Internal\Tools\VersionInventoryTool\trunk\source\VersionInventory.ps1:54 char:9
...
Save-Configuration : The term 'Save-Configuration' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Projects\Internal\Tools\VersionInventoryTool\trunk\source\VersionInventory.ps1:55 char:9
...
This is what's left of my script after removing all unnecessary parts; the error is reported from the script block that is the argument to $save_button.Add_Click:
using namespace System.Windows.Forms
using namespace System.Drawing
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
function Save-Configuration()
{
}
function Get-Configuration-Data-from-GUI($gui)
{
}
function New-Element
{
param(
[parameter()] [string] $class,
[parameter()] [int] $x,
[parameter()] [int] $y,
[parameter()] [int] $width,
[parameter()] [int] $height,
[parameter()] [string] $text,
[parameter(Mandatory = $false)] [Form] $parent
)
$ret = New-Object $class
if ($width -gt 0)
{
$ret.Width = $width
}
if ($height -gt 0)
{
$ret.Height = $height
}
$ret.Location = New-Object System.Drawing.Point($x, $y)
$ret.Text = $text
if ($parent -ne $null)
{
$parent.Controls.Add($ret)
}
return $ret
}
function Create-GUI()
{
$main_form = New-Element Form -x 100 -y 100 -width 600 -height 500 -text "My tool"
$border = 10
$width = $main_form.ClientRectangle.Width - 2 * $border
$save_button = New-Element Button -text "Save configuration" -x $border -width 120 -parent $main_form
$save_button.Top = $main_form.ClientRectangle.Bottom - $border - $save_button.Height
$save_button.Add_Click({
Get-Configuration-Data-from-GUI $main_form
Save-Configuration
}.GetNewClosure())
$exit_button = New-Element Button -text Exit -y $save_button.Top -parent $main_form
$exit_button.Left = $main_form.ClientRectangle.Right - $border - $exit_button.Width
$exit_button.DialogResult = [DialogResult]::OK
return $main_form
}
$gui = Create-Gui
$gui.ShowDialog()
Hoping for insights...
Greetings Hans
.GetNewClosure()