Im testing a script I found on https://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/. It is about PowerShell and WPF: Writing Data to a UI From a Different Runspace.
I copied the whole code and saved it to a test.ps1 file:
$syncHash = [hashtable]::Synchronized(@{})
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
$psCmd = [PowerShell]::Create().AddScript({
Add-Type -AssemblyName presentationframework
[xml]$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="Initial Window" WindowStartupLocation = "CenterScreen"
Width = "600" Height = "800" ShowInTaskbar = "True">
<TextBox x:Name = "textbox" Height = "400" Width = "600"/>
</Window>
"@
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$syncHash.Window=[Windows.Markup.XamlReader]::Load( $reader )
$syncHash.TextBox = $syncHash.window.FindName("textbox")
$syncHash.Window.ShowDialog() | Out-Null
$syncHash.Error = $Error
})
$psCmd.Runspace = $newRunspace
$data = $psCmd.BeginInvoke()
The only thing I added was the line "Add-Type -AssemblyName presentationframework" over the xaml. It is working in both the console and in ISE. The Form pops up and the console is responding. However, when I check the $synchhash in the console I get no result, its a Null variable. When I check it in ISE I get the desired response:
PS C:\Windows\System32\WindowsPowerShell\v1.0> $syncHash
Name Value
---- -----
TextBox System.Windows.Controls.TextBox
Window System.Windows.Window
Im running Powershell 5 / 1 / 17763 / 3770, same user on same machine. I checked for admin privileges with this:
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
Both cases false. I have another script witch is way bigger and there it is the opposite way round i cant get it to start up in ISE, but in console it works fine. I need to know whats going on here!
I tried to run the script with forced STA in the console but it wont come up.
powershell.exe -Sta -File MyScript.ps1
The ISE implicitly and invariably dot-sources scripts run in it, so that any variables, function definitions, ... inside the script become available in the caller's scope.
This behavior - which is especially treacherous when you run scripts repeatedly, because state lingering from previous runs can affect subsequent ones - is one of the reasons to avoid (bottom section) the obsolescent Windows PowerShell ISE.
The actively developed, cross-platform editor that offers the best PowerShell development experience is Visual Studio Code with its PowerShell extension; you can configure the latter to start a new, temporary session for every debugging run, which avoids the lingering-state problem while still giving you access to the script's variables, ... while inside the temporary session.
Therefore, if you want to inspect the $syncHash
variable defined inside your script after running your script in a regular console window or Windows Terminal, you must explicitly invoke it dot-sourced:
. .\test.ps1
If you invoke your script as just .\test.ps1
or with & .\test.ps1
(using &
, the call operator) it runs in a child scope, meaning that its variables, ... go out of scope when the script terminates and are not seen by the caller.