2018. március 8., csütörtök

Powershell applet form

It's a little known fact that it is possible to build a complete application form with pure Powershell. (Being based on .NET.). Here is an awesome example, called login.ps1. This is an applet starts a window that cannot be closed with the regular control buttons (as they are disabled) and asks two data from the user. Then it validates the data and if the data found to be invalid, flashes the input fields with red and returns to the initial state. Yeah, this was the hardest part of the development. If the data are all OK, it flashes the input fields with green color and pushes the data to the event log. This is a very very very special use case and only useful for me, but may help someone out who is just looking for a similar data input solution and gets here with google.

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Long Change Answer File Information"
$objForm.Size = New-Object System.Drawing.Size(455,265)
$objForm.StartPosition = "CenterScreen"

# set this to $True to enable "close" button
$objForm.ControlBox = $false
$objForm.KeyPreview = $True

# Add Ok Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(180,185)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({
    # some tricky regex to validate our very custom input data
    If( $ChangeTextBox.Text -match "\b([Cc][0-9a-zA-Z]{9}|OST#?[0-9]{6})\b" -And $LoginTextBox.Text -match "\b[a-zA-Z]\w{2,19}\b") # Valid -match "^\d{0,10}$"
    {
        $LoginTextBox.BackColor = "lime";
        $ChangeTextBox.BackColor = "lime";
        Start-Sleep -Milliseconds 600;

        $objForm.Close()
    }
    # we have two input fields and both are required to be validated
    ElseIf (-Not ($LoginTextBox.Text -match "\b[a-zA-Z]\w{2,19}\b") -And ($ChangeTextBox.Text -match "\b([Cc][0-9a-zA-Z]{9}|OST#?[0-9]{6})\b"))   # Invalid
    {
        #$ErrorProvider.SetError($LoginTextBox, "Please enter valid name");
        $LoginTextBox.BackColor = "pink";
        $ChangeTextBox.BackColor = "lime";
    }
    # strange logic but this is the simpliest way in this case, here we get back to reset the form
    ElseIf (-Not ($ChangeTextBox.Text -match "\b([Cc][0-9a-zA-Z]{9}|(OST|ost)#?[0-9]{6})\b") -And ($LoginTextBox.Text -match "\b[a-zA-Z]\w{2,19}\b"))
    {
        $ChangeTextBox.BackColor = "pink";
        $LoginTextBox.BackColor = "lime";
    }
    Else
    {
        # visual warning to the user
        $ChangeTextBox.BackColor = "pink";
        $LoginTextBox.BackColor = "pink";
    }
})
$objForm.Controls.Add($OKButton)   

# Add Textbox Label
$FontBold = new-object System.Drawing.Font("Arial",8,[Drawing.FontStyle]'Bold' )

#UserID label
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(425,20)
$objLabel.Font = $fontBold
$objLabel.text = "Please enter Your UserID"
$objForm.Controls.Add($objLabel)

$objLabel1 = New-Object System.Windows.Forms.Label
$objLabel1.Location = New-Object System.Drawing.Size(30,47)
$objLabel1.Size = New-Object System.Drawing.Size(65,50)
$objLabel1.Text = "UserName:"
$objForm.Controls.Add($objLabel1)

#UserID textbox
$LoginTextBox = New-Object System.Windows.Forms.TextBox
$LoginTextBox.Location = New-Object System.Drawing.Size(120,45)
$LoginTextBox.Size = New-Object System.Drawing.Size(260,20)
#$LoginTextBox.BackColor = "green"
$objForm.Controls.Add($LoginTextBox)

#CH label
$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,100)
$objLabel2.Size = New-Object System.Drawing.Size(425,20)
$objLabel2.Font = $fontBold
$objLabel2.Text = "Please enter change number"
$objForm.Controls.Add($objLabel2)

$objLabel3 = New-Object System.Windows.Forms.Label
$objLabel3.Location = New-Object System.Drawing.Size(30,120)
$objLabel3.Size = New-Object System.Drawing.Size(65,40)
$objLabel3.Text = "CH number:"
$objForm.Controls.Add($objLabel3)

#CH textbox
$ChangeTextBox = New-Object System.Windows.Forms.TextBox
$ChangeTextBox.Location = New-Object System.Drawing.Size(120,120)
$ChangeTextBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($ChangeTextBox)

# Add Validation Control
$ErrorProvider = New-Object System.Windows.Forms.ErrorProvider

$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

$change= $ChangeTextBox.TEXT
$login = $LoginTextBox.TEXT

Write-EventLog -Source "Winlogon" -LogName "Application" -EventId 666 -Message "Impersonated user logged as $login for $change implementation"

Nincsenek megjegyzések:

Megjegyzés küldése