简体   繁体   中英

XAML GUI to Powershell with variables

A fellow member on Superuser got me onto this guide on creating a GUI to a powershell script however I am new to this area so I need a little guidance on the coding.

This is the XAML code generated by Visual Studio 2015;

<Window x:Name="Title" x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="New Mailbox" Height="400" Width="420">
<Grid>
    <Image x:Name="image" HorizontalAlignment="Left" Height="100" Margin="14,10,0,0" VerticalAlignment="Top" Width="386" Source="C:\Users\Daniel Neocleous\Documents\Visual Studio 2015\Projects\WpfApplication1\WpfApplication1\Images\SibelcoLogo.png"/>
    <RadioButton x:Name="radioButton" Content="Step 1" HorizontalAlignment="Left" Margin="150,125,0,0" VerticalAlignment="Top"/>
    <RadioButton x:Name="radioButton_Copy" Content="Step 2" HorizontalAlignment="Left" Margin="217,125,0,0" VerticalAlignment="Top"/>
    <Button x:Name="button" Content="Create Mailbox" HorizontalAlignment="Left" Margin="150,152,0,0" VerticalAlignment="Top" Width="119" Height="35"/>
    <GroupBox x:Name="groupBox" Header="Output" HorizontalAlignment="Left" Height="169" Margin="10,192,0,0" VerticalAlignment="Top" Width="394">
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="147" Margin="0,0,-1.143,-0.714" TextWrapping="Wrap" VerticalAlignment="Top" Width="384"/>
    </GroupBox>

</Grid>

Now from what I have understood I have to modify this code by removing the x's and the x:Class="WpfApplication1.MainWindow" string and add the following to the end;

#Read XAML
    $reader=(New-Object System.Xml.XmlNodeReader $xaml) 
    try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
    catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}
    #===========================================================================
    # Store Form Objects In PowerShell
    #===========================================================================
    $xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
    #===========================================================================
    # Shows the form
    #===========================================================================
    $Form.ShowDialog() | out-null

I am a little stuck from here though assuming what I have out above is correct. How do I tie all this to the Gui?

GUI

There are two Radio buttons and depending which one is selected I want a different script to run and the Powershell output to be displayed in the text box at the bottom but how can I accomplish this?

The Powershell I want to run on Step 1

$credentials = get-credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri URL -Credential $credentials –AllowRedirection
Import-PSSession $Session
set-ADServerSettings -ViewEntireForest $true
Enable-RemoteMailbox -Identity test@test.com -RemoteRoutingAddress test@test.com.onmicrosoft.com
Enable-RemoteMailbox -Identity test@test.com -Archive

Step 2

$msolcred = get-credential
connect-msolservice -credential $msolcred
Set-MsolUser -UserPrincipalName test@test.com -UsageLocation GB
$LicOpt = New-MsolLicenseOptions -AccountSkuId company:STANDARDPACK -DisabledPlans MCOSTANDARD
Set-MsolUserLicense -UserPrincipalName test@test.com -AddLicenses company:STANDARDPACK -LicenseOptions $LicOpt
Remove-PSSession $Session

Thanks for the advice guys.

Your $Form should be a Window object and thus support all its methods, so to react to certain events you have to read the state of the controls.

As this is script based, i would just name all the relevant parts and search for them using FindName (your script apparently already creates powershell variables for all named controls). You then can access the properties like IsChecked to differentiate which RadioButton is selected. To listen to a button click you probably need Register-ObjectEvent . As you use ShowDialog you have a blocking call that returns when the DialogResult is set, so you should set that in your event listener.

Edit: I just played around with this and here's a small sample that shows the basic process.

ScriptWindow.xaml

<Window x:Name="Title"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <ListBox x:Name="selection" SelectionMode="Single">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <RadioButton IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                                 Content="{Binding}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <sys:String>Step 1</sys:String>
            <sys:String>Step 2</sys:String>
        </ListBox>
        <Button x:Name="run">Run</Button>
        <GroupBox Header="Output">
            <TextBox x:Name="output" IsReadOnly="True"/>
        </GroupBox>
    </StackPanel>
</Window>

ScriptWindow.ps1

Add-Type –assemblyName PresentationFramework
Add-Type –assemblyName PresentationCore
Add-Type –assemblyName WindowsBase

$xaml="ScriptWindow.xaml"
$xmlReader=(New-Object System.Xml.XmlTextReader $xaml)
$app=(New-Object System.Windows.Application)
$form=[Windows.Markup.XamlReader]::Load( $xmlReader )
$doc=(New-Object System.Xml.XmlDocument)
$doc.Load($xaml)
$run = $form.FindName("run")
$selection = $form.FindName("selection")
$output = $form.FindName("output")
$run.Add_Click({ $output.Text = $selection.SelectedItem })
$app.Run($form)

Apparently you can also add event listeners via Add_* , Register-ObjectEvent did not work for me. In the callback i just assign the selected option to the TextBox , you will want to do a case distinction on the selected value and execute your respective actions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM