1

I have a PowerShell script with a WPF GUI that allows the users to enter values and choose from drop-down lists. It works great, but some users want to bypass it and run the script manually (enter their own values directly into the script).

Right now the structure is:

#A bunch of XML and PowerShell that generates the GUI

$WPFbutton.Add_Click({

#Variables that get populated by the GUI

#The rest of the script

})

I want to add something like:

$UseGUI = $true

at the top of the script that they can change to false, which will cause the script to ignore the XML and button click line.

I was thinking I could surround the XML stuff in an if statement based on $UseGUI but that doesn't help with the button click part.

One thing I know would work is copy and pasting the entire script to another if statement based on $UseGUI. The issue there is it would double the script size, and it's already 2000 lines.

jdope
  • 115
  • 2
  • 14
  • you should try add optional params, and then check if they are null before prompting with the GUI, you'll need to re-write a good chunk of your code from the sounds of it though. – colsw Jun 06 '17 at 22:07

1 Answers1

1

One idea would be to use a function and parameters to identify if the person using the script wants to use the GUI or has supplied the correct information by themselves:

param
(
    [Parameter(ParameterSetName = 'Interface',
               Mandatory = $true,
               Position = 0)]
    [switch]
    $UseGUI,

    [Parameter(ParameterSetName = 'CommandLine',
               Mandatory = $true,
               Position = 0)]
    [ValidateNotNullOrEmpty()]
    [string]
    $Person
)

function SayHelloTo ($User)
{
    Write-Output "Hello $User"
}

if ($UseGUI)
{
    #A bunch of XML and PowerShell that generates the GUI

    $WPFbutton.Add_Click({

        #Variables that get populated by the GUI

        #The rest of the script

        $variable = "jdope"

        SayHello -User $variable

    })
}
else
{
    SayHello -User $Person
}

The parameter sets will prevent the script from being called with both options so when you check if UseGUI is $True you will know to show the GUI (and get the input to call the function) or call the function with the input.

To use the GUI call the script with -UseGUI

.\MyPowerShellWpfScript -UseGUI

To supply the Person information and bypass the GUI use

.\MyPowerShellWpfScript -Person "jdope"
Bluecakes
  • 2,069
  • 17
  • 23
  • 1
    I like the approach in principle, but please, please don't use `Write-Host` unless there's a good reason to do so (and there are few). Why would `-UseGUI` need to support _pipeline_ input? If anything, it should be `-Person`, though you'd need a `process` block in either case. From the quibbles department: _interface_ is not the same as _interactive_. – mklement0 Jun 06 '17 at 23:59
  • @mklement0 What's wrong with Write-Host? I use it quite a bit for output to give the status of the script. – jdope Jun 07 '17 at 15:16
  • 1
    The danger is that it may mislead beginners to think that `Write-Host` is the way to output _data_ in PowerShell (analogous to `echo` in traditional shells), whereas it _bypasses_ the (success) output stream. This confusion is very common and, I think, worth avoiding. – mklement0 Jun 07 '17 at 15:18
  • 1
    Some background info in [this blog post](http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/) and in [this answer](http://stackoverflow.com/a/40034706/45375) of mine. – mklement0 Jun 07 '17 at 15:24
  • 1
    Ah, yes agreed, i've been doing quite a lot of form work lately with PowerShell and the only way to pass information to the console from the form is to use `Write-Host`. I'll update the answer :) – Bluecakes Jun 07 '17 at 22:03
  • Thank you for updating. A final thought: While `Write-Output` does write to the success stream, its use is rarely necessary, because anything not explicitly captured or redirected writes to the output stream _by default_, so the idiomatic PowerShell way would be to just use `"Hello `$User"` by itself. – mklement0 Jun 08 '17 at 18:01