Hello
Can someone please help me with the following query
I am creating a PowerShell/WPF script and as I do not want the UI to hang will the script of off doing it stuff in the back ground I am using a thread safe synced hash table.
I have started to build the UI and it works fine, but I cannot get the syntax right for adding an event handler to a radial button (e.g. do stuff then radial button checked)
here is the basic UI elements of my code so far.
#Sync'd hash table to work between runspaces
$Global:syncHash = [hashtable]::Synchronized(@{})
# Invoke STA Runspace (WPF works in single thread apartment)
$threadSTA = [RunspaceFactory]::CreateRunspace()
$threadSTA.ApartmentState = "STA"
$threadSTA.ThreadOptions = "ReuseThread"
$threadSTA.Open()
$threadSTA.SessionStateProxy.SetVariable("syncHash",$syncHash)
# Load WPF assemblies to STA Runspace
$psShell = {Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase}.GetPowerShell()
$psShell.Runspace = $threadSTA
$psShell.Invoke()
$psShell.Commands.Clear()
[void]$psShell.AddScript({
$string = @'
<Window Name="PKICertUtil"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PKI Creation and Renewal Utility. Author Ernest Brant (last updated 5 July 2014)" Height="448" Width="719" ToolTip="This script was written by Ernest Brant to faciliate TechOps
in Creating or Renewing PKI related Certificates.">
<Canvas HorizontalAlignment="Left" Width="711" Margin="0,0,0,4">
<TextBlock x:Name="txtNewOrRenew" Canvas.Left="10" TextWrapping="Wrap" Text="New or Renew Certificate" Canvas.Top="10" ToolTip="Select weather you want a Brand
New Certificate or to Renew and Existing Certificate" FontWeight="Bold" TextDecorations="Underline"/>
<RadioButton x:Name="rdlRenewCert" Content="Renew Existing Certificate" Canvas.Left="10" Canvas.Top="31" GroupName="NewOrRenewCert" IsChecked="True" ToolTip="Select
this option if you want to renew an existing certificate (e.g. one coming up to expiry)"/>
<RadioButton x:Name="rdlNewCert" Content="New Certificate (first time creation)" Canvas.Left="10" Canvas.Top="52" GroupName="NewOrRenewCert" ToolTip="Select
this option if you want to create a 'brand new' certificate (e.g. never issued before)"/>
<TextBlock x:Name="txtLoggingOptions" Canvas.Left="10" TextWrapping="Wrap" Text="Script Output Logging Options" Canvas.Top="75" FontWeight="Bold" TextDecorations="Underline"/>
<RadioButton x:Name="rdlStandardLogging" Content="Standard Logging" Canvas.Left="10" Canvas.Top="96" GroupName="StandardOrVerboseLogging" IsChecked="True"
ToolTip="This option provides standard logging output (e.g. not too verbose)"/>
<RadioButton x:Name="rdlVerboseLogging" Content="Verbose Logging" Canvas.Left="10" Canvas.Top="117" GroupName="StandardOrVerboseLogging" ToolTip="This option
provides more verbose output loggin (recommended when troubleshooting)"/>
<TextBlock Canvas.Left="10" TextWrapping="Wrap" Canvas.Top="138" Width="200" FontWeight="Bold" TextDecorations="Underline"><Run Language="en-gb"
Text="Saved Log to Folder"/></TextBlock>
<TextBox x:Name="txtboxLogsDir" Height="24" Canvas.Left="10" TextWrapping="Wrap" Text="C:\Logs" Canvas.Top="159" Width="152" Cursor="IBeam"
BorderThickness="2" Background="White" ToolTip="Location for where Logs generated by the Script will be stored. If the path does not exist it will be created."/>
<TextBox Height="26" Canvas.Left="10" TextWrapping="Wrap" Text="<Enter ComputerName>" Canvas.Top="209" Width="152" BorderThickness="2"
Cursor="IBeam" ToolTip="Please Enter the Name of the Computer containing the Certificate the be Renewed or for which you want to create a New Certificate"/>
<TextBlock x:Name="txtComputerName" Canvas.Left="10" TextWrapping="Wrap" Canvas.Top="188" Width="120"><Run Language="en-gb" Text="ComputerName"
FontWeight="Bold" TextDecorations="Underline" /></TextBlock>
<TextBlock x:Name="txtCertSubName" Canvas.Left="10" TextWrapping="Wrap" Canvas.Top="240" Width="152" Height="22" FontWeight="Bold" TextDecorations="Underline"
Visibility='Hidden'><Run Language="en-gb" Text="Certificate Subject Name"/></TextBlock>
<TextBox x:Name="txtboxSubjectName" Height="26" Canvas.Left="10" TextWrapping="Wrap" Text="<Enter Subject Name>" Canvas.Top="262" Width="152"
BorderThickness="2" Cursor="IBeam" ToolTip="Enter the Subject Name (aka Common Name) of the Certificate e.g.www.MyWebSite.Com" Panel.ZIndex="0" Visibility="Hidden"/>
<CheckBox x:Name="chkAddSANs" Content="Add Certificate Subject Alternate Name/s" Canvas.Left="10" Canvas.Top="293" ToolTip="Select the check box if you need to provide
more than one Subject Name for the certificate." Visibility="Hidden"/>
<TextBox x:Name="txtboxEnterSANs" Height="23" Canvas.Left="10" TextWrapping="Wrap" Text="<Enter SANs>" Canvas.Top="314" Width="152"
BorderThickness="2" ToolTip="Enter the additional Subject Names (aka SANs) as a comma seperated list." Visibility="Hidden"/>
<TextBox x:Name="txtboxOuputWindow" Height="299" Canvas.Left="258" TextWrapping="Wrap" Text="Script output will be displayed here." Canvas.Top="10" Width="434"
BorderThickness="2" ToolTip="Output from the script will be shown in this windows and also logged to a file in the 'Saved Log tp Folder."/>
<Button x:Name="btnCancel" Content="Cancel" Canvas.Left="617" Canvas.Top="315" Width="75" Cursor="Hand" ToolTip="Click this Button to 'Cancel Execution'
of the script." BorderThickness="2"/>
<Button x:Name="btnExecute" Content="Execute" Canvas.Left="537" Canvas.Top="315" Width="75" ToolTip="Click this button to 'Execute' the script." Cursor="Hand"/>
<ListBox x:Name="lstboxListCerts" Height="48" Canvas.Left="10" Canvas.Top="356" Width="682" BorderThickness="2" ToolTip="Select a Certificate to Renew
from the list." Visibility="Hidden"/>
</Canvas>
</Window>
'@
[xml]$xaml = ($String -replace "x:")
$reader=(New-Object System.Xml.XmlNodeReader $xAML)
$syncHash.Form=[Windows.Markup.XamlReader]::Load( $reader )
$XAML.SelectNodes("//*[@Name]")| % {$syncHash."$($_.Name)" = $syncHash.Form.FindName("$($_.Name)")}
[void]$syncHash.Form.ShowDialog()
}).BeginInvoke()
Now if you look at the variable $SyncHash you will see the following
PS C:\Scripts\PowerShell> $syncHash
Name Value
---- -----
btnExecute System.Windows.Controls.Button: Execute
txtLoggingOptions System.Windows.Controls.TextBlock
txtboxSubjectName System.Windows.Controls.TextBox: <Enter Subject Name>
txtboxEnterSANs System.Windows.Controls.TextBox: <Enter SANs>
btnCancel System.Windows.Controls.Button: Cancel
PKICertUtil System.Windows.Window
Form System.Windows.Window
rdlRenewCert System.Windows.Controls.RadioButton Content:Renew Existing Certificate IsChecked:True
rdlNewCert System.Windows.Controls.RadioButton Content:New Certificate (first time creation) IsChecked:False
lstboxListCerts
chkAddSANs System.Windows.Controls.CheckBox Content:Add Certificate Subject Alternate Name/s IsChecked:False
txtboxOuputWindow System.Windows.Controls.TextBox: Script output will be displayed here.
txtComputerName System.Windows.Controls.TextBlock
txtCertSubName System.Windows.Controls.TextBlock
rdlStandardLogging System.Windows.Controls.RadioButton Content:Standard Logging IsChecked:True
txtboxLogsDir System.Windows.Controls.TextBox: C:\Logs
rdlVerboseLogging System.Windows.Controls.RadioButton Content:Verbose Logging IsChecked:False
txtNewOrRenew System.Windows.Controls.TextBlock
PS C:\Scripts\PowerShell>
OK so far, so I can do the following manually from the open Powershell console (which the UI is also displayed)
$syncHash.txtCertSubName.Dispatcher.invoke("Normal", [action]{$syncHash.txtCertSubName.Visibility='Visible'})
and the element will appear in real time on the UI (e.g. unhide it).
Now what I want to do it add this to an event on the rdlNewCert radial button, so when the button is checked the above code executes to make the element visible
I have tired several syntaxes but no Cigar, I am new to this and borrowing/learning for examples, I understand the above concepts/ideas (at least at a high level), but can not get he above working.
Please advise, thanks all
Ernie