Thursday, February 12, 2015

#44 : Display Inputbox with Powershell

Hi All,

Powershell does not support InputBox itself. We might have to do some effort to achieve it. I did some research and found two methods can be used :

Below is the complete demonstration:



DEPLOYMENT STEPS

This method is extremely flexible and requires little more effort. If you COPY+PASTE, there is not much effort, but while developing I did some more effort.

Let's have look into the code.

I have created a function CustomInputBox which will create all the GUI interface and will return the user input.




function CustomInputBox([string] $title, [string] $message, [string] $defaultText) 
 {
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

    $userForm = New-Object System.Windows.Forms.Form
    $userForm.Text = "$title"
    $userForm.Size = New-Object System.Drawing.Size(290,150)
    $userForm.StartPosition = "CenterScreen"
        $userForm.AutoSize = $False
        $userForm.MinimizeBox = $False
        $userForm.MaximizeBox = $False
        $userForm.SizeGripStyle= "Hide"
        $userForm.WindowState = "Normal"
        $userForm.FormBorderStyle="Fixed3D"
     
    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Size(115,80)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = "OK"
    $OKButton.Add_Click({$value=$objTextBox.Text;$userForm.Close()})
    $userForm.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Size(195,80)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = "Cancel"
    $CancelButton.Add_Click({$userForm.Close()})
    $userForm.Controls.Add($CancelButton)

    $userLabel = New-Object System.Windows.Forms.Label
    $userLabel.Location = New-Object System.Drawing.Size(10,20)
    $userLabel.Size = New-Object System.Drawing.Size(280,20)
    $userLabel.Text = "$message"
    $userForm.Controls.Add($userLabel) 

    $objTextBox = New-Object System.Windows.Forms.TextBox
    $objTextBox.Location = New-Object System.Drawing.Size(10,40)
    $objTextBox.Size = New-Object System.Drawing.Size(260,20)
    $objTextBox.Text="$defaultText"
    $userForm.Controls.Add($objTextBox) 

    $userForm.Topmost = $True
    $userForm.Opacity = 0.91
        $userForm.ShowIcon = $False

    $userForm.Add_Shown({$userForm.Activate()})
    [void] $userForm.ShowDialog()

    $value=$objTextBox.Text 

    return $value

 }


$userInput = CustomInputBox "User Name" "Please enter your name." ""
 if ( $userInput -ne $null ) 
 {
  echo "Input was [$userInput]"
 }
 else
 {
  echo "User cancelled the form!"
}





CONCLUSION

You may try any of the merthod described above. I would suggest Method#2 is more flexible and you have much more scope to improve. But again, if users are used to have the same inputbox which was famous in previous years, Method#1 is for you.
Happy scripting !

19 comments:

  1. The function doesn't seem to return the $value varaible, unless defined as global.

    ReplyDelete
  2. Hi Bart P,

    You may declare as global, but if the function is returning data, you don't need to have global variable. Please run it without making any changes, it should work for sure.

    Thanks for your response.

    ReplyDelete
  3. the famous MSScriptControl.ScriptControl issue :: problem is it doesn't work in 64 bit OS's unless you run it in a 32bit window who wants to keep doing that, best to learn option 2 and move forward rather than back

    ReplyDelete
  4. Doesn't return any value but "Cancel"

    ReplyDelete
  5. ok, i got it now. you do have to declare $value as global.

    ReplyDelete
  6. What changes did you guys make in order for this to work? i created $value as global and it still doesn't work.

    ReplyDelete
  7. Change lines 20 and 43 to:

    20: $OKButton.Add_Click({$global:value=$objTextBox.Text;$userForm.Close()})

    43: return $global:value

    ReplyDelete
  8. scripts works perfect. no issue... once you input, it will show the output of the name
    good.
    sri

    ReplyDelete
  9. I changed line 43 to: return $objTextBox.Text

    ReplyDelete
  10. That helped a lot
    > I changed line 43 to: return $objTextBox.Text

    ReplyDelete
  11. Line 47 "[void] $userForm.ShowDialog()" invalidates Line 49 "return $value". Removing "[void]" from Line 47 allowed the return to work as expected.

    ReplyDelete
  12. I'm not sure why there is a CANCEL button. I haven't figured out how to determine which button was clicked. Any ideas?

    ReplyDelete
  13. Doesnt work for me, says class is not registred.

    ReplyDelete
  14. okay addition, its not working on x64 ISE. great...

    ReplyDelete
  15. Hello,

    If you want to use the Chancel Button, you have to Change Line 28 in this way:

    $CancelButton.Add_Click({$global:value='';$userForm.Close()})

    and line 56

    if ( $userInput -ne '' )

    then it works.

    ReplyDelete
  16. If you change line 28 to
    $CancelButton.Add_Click({$global:value=$NULL;$userForm.Close()})
    Then you do not need to change line 56

    ReplyDelete
  17. For reference, Powershell does have a far easier method for what you are looking for:

    Below code should be familiar to some, but for clarity I will explain. The script setups up visual basic for the InputBox and then follows the parameters of Message, Title, and Default entry. Default can be omitted, if you want it to be blank. Below also follows up with writing (aka echoing) back what was assigned to the variable handing the input.

    ---- Code Below ----

    [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
    $varUsername = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter your name", "Username", "John.Doe")

    Write-Host $varUsername

    ReplyDelete
    Replies
    1. Yes, but how to remove the cancel button from that if you need to?

      Delete
  18. I just want to thank you for sharing your information and your site or blog this is simple but nice Information I’ve ever seen i like it i learn something today. Curso Avanzado de Excel: Tablas DinĂ¡micas y Simulaciones

    ReplyDelete

#112: How to handle xml document in Powershell?

 In PowerShell, you can handle XML data using various cmdlets and methods provided by the .NET Framework. Here's a basic guide on how to...