PowerShell – Form – Input, Enter, Escape, OK Button

email me

This is the third example of a PowerShell form. In this version, I have added event handling for the ENTER and ESCAPE keys, created a single OK button (rather than Yes No), and have tied the ENTER key event to a Perform Click; it will access the button action $handler_OK_Button_Click. Something else you will notice, the previous example would close immediately once you selected Yes. This form is persistent.

What the form looks like

 

The Code

# Call Function 
CreateForm

function CreateForm { 

#Import Assemblies 
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$Form1 = New-Object System.Windows.Forms.Form 
$OKButton = New-Object System.Windows.Forms.Button 
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState 
$Label1 = New-Object System.Windows.Forms.Label
$textBox1 = New-Object System.Windows.Forms.TextBox
$Field1 = ""

# Check for ENTER and ESC presses
$Form1.KeyPreview = $True
$Form1.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
    {
	# if enter, perform click
	$OKButton.PerformClick()
	}
})
$Form1.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
   	{
	# if escape, exit
	$Form1.Close()
	}
})

# The action on the button
$handler_OK_Button_Click= 
{ 
	$Field1 = $textBox1.Text
	$Field1
	
	# Returns a message of no data
	if ($Field1 -eq "") {[System.Windows.Forms.MessageBox]::Show("You didn't enter anything!", "Data")}
	
	# Returns what they types. You could add your code here
	else {[System.Windows.Forms.MessageBox]::Show($Field1, "Data")}	 
}

$OnLoadForm_StateCorrection= 
{
$Form1.WindowState = $InitialFormWindowState 
}


# Form Code 
$Form1.Name = "Data_Form"
$Form1.Text = "Data Form" 
$Form1.MaximizeBox = $false #lock form
$Form1.FormBorderStyle = 'Fixed3D'
# None,FixedDialog,FixedSingle,FixedToolWindow,Sizable,SizableToolWindow

# Icon
$Form1.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)
# $NotifyIcon.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)

$Form1.DataBindings.DefaultDataSourceUpdateMode = 0 
$Form1.StartPosition = "CenterScreen"# moves form to center of screen
$System_Drawing_Size = New-Object System.Drawing.Size 
$System_Drawing_Size.Width = 300 # sets X
$System_Drawing_Size.Height = 150 # sets Y
$Form1.ClientSize = $System_Drawing_Size

$OKButton.Name = "OK_Button" 
$System_Drawing_Size = New-Object System.Drawing.Size 
$System_Drawing_Size.Width = 45
$System_Drawing_Size.Height = 23

$OKButton.Size = $System_Drawing_Size 
$OKButton.UseVisualStyleBackColor = $True
$OKButton.Text = "OK"
$System_Drawing_Point = New-Object System.Drawing.Point 
$System_Drawing_Point.X = 30 
$System_Drawing_Point.Y = 113

$OKButton.Location = $System_Drawing_Point 
$OKButton.DataBindings.DefaultDataSourceUpdateMode = 0 
$OKButton.add_Click($handler_OK_Button_Click)
$Form1.Controls.Add($OKButton)

$InitialFormWindowState = $Form1.WindowState 
$Form1.add_Load($OnLoadForm_StateCorrection) 

$Label1.Location = New-Object System.Drawing.Point(10,20)
$Label1.Size = New-Object System.Drawing.Size(280,20)
$Label1.Text = "Enter data here:"
$Form1.Controls.Add($Label1)
 
$textBox1.TabIndex = 0 # Places cursor in field
$textBox1.Location = New-Object System.Drawing.Point(10,40)
$textBox1.Size = New-Object System.Drawing.Size(260,20)
$Form1.Controls.Add($textBox1)
$Form1.Topmost = $True # Moves form to top and stays on top
$Form1.Add_Shown({$textBox1.Select()})

# Show Form 
$Form1.ShowDialog()
}

 

PowerShell Form Input Field; GUI

email me

From our previous form example, we learned that GUI components can be created using PowerShell. Now, we add an input field, perform some logic on the input, and center our form on the screen.

What the form looks like

The pop up with data

The pop up without data

 

The Code

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$Form1 = New-Object System.Windows.Forms.Form
$Form1.Text = "Data Form"
$Form1.Size = New-Object System.Drawing.Size(300,200)
$Form1.StartPosition = "CenterScreen"
# Icon
$Form1.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$Form1.AcceptButton = $OKButton
$Form1.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$Form1.CancelButton = $CancelButton
$Form1.Controls.Add($CancelButton)

$Label1 = New-Object System.Windows.Forms.Label
$Label1.Location = New-Object System.Drawing.Point(10,20)
$Label1.Size = New-Object System.Drawing.Size(280,20)
$Label1.Text = "Enter data here:"
$Form1.Controls.Add($Label1)

$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,40)
$textBox.Size = New-Object System.Drawing.Size(260,20)
$Form1.Controls.Add($textBox)

$Form1.Topmost = $True

$Form1.Add_Shown({$textBox.Select()})
$result = $Form1.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $textBox.Text
$x

if ($x -eq "") {[System.Windows.Forms.MessageBox]::Show("You didn't enter anything!", "Test Title")}
else {[System.Windows.Forms.MessageBox]::Show($x, "Test Title")}}

PowerShell Form; GUI

email me

For all those that would like to extend their PowerShell scripting beyond the console and beyond just text-based scripts, you can add GUI components, such as things like buttons, drop down lists, radio buttons, etc. And, hey, no expensive software necessary; I did this in Notepad++.

In the example below, I have created a Form using only PowerShell, with an action behind the button.

What the form looks like

What the pop up looks like

 

The Code


function CreateForm {

# Import Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

$Form1 = New-Object System.Windows.Forms.Form
$Button1 = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState

$handler_Button1_Click=
{
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.MessageBox]::Show("Pop up." , "Test Title")

# Example with Yes and No
# [System.Windows.Forms.MessageBox]::Show("We are proceeding with next step." , "Status" , 4)
# $OUTPUT= [System.Windows.Forms.MessageBox]::Show("We are proceeding with next step." , "Status" , 4)
# if ($OUTPUT -eq "YES" )
# {
# ..do something
#
# }
# else
# {
# ..do something else
# }

# Types of message boxes
# 0: OK
# 1: OK Cancel
# 2: Abort Retry Ignore
# 3: Yes No Cancel
# 4: Yes No
# 5: Retry Cancel
}

$OnLoadForm_StateCorrection=
{
$Form1.WindowState = $InitialFormWindowState
}
# Form Code
$Form1.Text = "Test Form Text 1"
$Form1.Name = "Test Form Text 2"

$Form1.MaximizeBox = $false #lock form
$Form1.FormBorderStyle = 'Fixed3D'
# None,FixedDialog,FixedSingle,FixedToolWindow,Sizable,SizableToolWindow

# Icon
$Form1.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)
#$NotifyIcon.Icon = [Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)

$Form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 265
$System_Drawing_Size.Height = 55
$Form1.ClientSize = $System_Drawing_Size

$Button1.TabIndex = 0
$Button1.Name = "Button1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 240
$System_Drawing_Size.Height = 23
$Button1.Size = $System_Drawing_Size
$Button1.UseVisualStyleBackColor = $True

$Button1.Text = "Button Text Here"

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 13
$System_Drawing_Point.Y = 13
$Button1.Location = $System_Drawing_Point
$Button1.DataBindings.DefaultDataSourceUpdateMode = 0
$Button1.add_Click($handler_Button1_Click)

$Form1.Controls.Add($Button1)

$InitialFormWindowState = $Form1.WindowState
$Form1.add_Load($OnLoadForm_StateCorrection)

# Show Form
$Form1.ShowDialog()| Out-Null

}

# Call Function
CreateForm

References

https://msdn.microsoft.com/en-us/library/system.windows.forms.form.formborderstyle%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

https://msdn.microsoft.com/en-us/library/hw8kes41(v=vs.110).aspx

PowerShell – Install Pester

email me

Pester provides a framework for running unit tests to execute and validate PowerShell commands from within PowerShell. Pester consists of a simple set of functions that expose a testing domain-specific language (DSL) for isolating, running, evaluating and reporting the results of PowerShell commands.

Pester tests can execute any command or script that is accessible to a Pester test file. This can include functions, cmdlets, modules and scripts. Pester can be run in ad-hoc style in a console or it can be integrated into the build scripts of a continuous integration (CI) system.

Pester also contains a powerful set of mocking functions in which tests mimic any command functionality within the tested PowerShell code.

You can download the latest Pester version from GitHub and copy it to a folder in $env:PSModulePath – but it’s more convenient to use a packaging solution like PSGet or Chocolatey.

Here is an example how you can install Chocolatey, a software management solution (in case you haven’t done it yet – line 1), and then install Pester (line 2).

iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
choco install pester -y

 

Notes

Pester Framework

Chocolatey – Software Management for Windows

PowerShellGet Module


Upgrade Pester

Install-Module -Name Pester -Force

 

Upgrade Chocolately

choco upgrade all -y

PowerShell – Write to Computer Object Description

email me

This is how you write to the description field for a computer object in Active Directory.

Remember, set the Execution PolicySet-ExecutionPolicy RemoteSigned

Import-module ActiveDirectory
$strComputer = 'PC_Name1'
$strDescription = "The Description Here"
Set-ADComputer $strComputer -Description $strDescription

 

If you want to import data from a CSV

Import-module ActiveDirectory  
Import-CSV "C:\PowerShell\Data.csv" | % { 
$strComputer = $_.Computer 
$strDescription = $_.Description 
Set-ADComputer $strComputer -Description $strDescription
}

 

What the data.csv looks like

Computer,Description
PC_Name1,testing1
PC_Name2,testing2
PC_Name3,testing3

VBScript – Return IP and Gateway Addresses; Raw formats

email me

A simple way to return IP information is to use WMI.

On error resume next
'set computer name; uses local machine name
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each objItem In colItems
  IPAddress = Join(objItem.IPAddress, ",")
  GatewayAddress = Join(objItem.GatewayAddress, ",")
  'output information
  MsgBox "IP Address = " & IPAddress & vbCrLf & "Gateway Address = " & GatewayAddress
Next

VBScript – Return Gateway Address; Site-Aware

email me

This script returns the user’s gateway IP address, locates address in a text file, which then ties it to a location code or name. This is great for making site-aware scripts and packages.

ON ERROR RESUME NEXT

CONST ForReading = 1 

DIM lineInput, IP_Address, workingLine, IPGateway, SiteLocation
DIM objFSO, objFile, objOutput, dataLine, RegCommand, objShell

SET objShell = CreateObject("Wscript.Shell")
SET objFSO = createobject("Scripting.FileSystemObject")

'SETS CURRENT DIRECTORY TO VARIABLE
strCurrentDirectory = objShell.CurrentDirectory

'CLEAR SESSION
dataLine = "" 

'READ FROM GATEWAYS FILE. 
'opens gateways file for reading
SET objFile = objFSO.openTextFile(strCurrentDirectory & "\Gateways.txt", ForReading) 
'Example of text file: gateway address,site code or name
'0.0.0.0,VPN
'11.11.11.254,991
'12.11.11.254,992
'13.11.11.254,Florida

'RETURN GATEWAY ADDRESS USING A FUNCTION
IP_Address = ReturnGateway()

'RETURN LOCATION NUMBER
DO UNTIL objFile.atEndOfStream 	
ON ERROR RESUME NEXT
	dataLine = objFile.readLine & vbCrLf
	IF inStr(dataLine, IP_Address) THEN
	   lineInput = Split(dataLine, ",")
	   workingLine = dataLine	   
	   IPGateway = lineInput(0)	   
	   SiteLocation = lineInput(1)     	   
	   EXIT DO
	 END IF	 
LOOP
'close file for reading
objFile.Close


'IMPORT LOCATION INTO REG KEY
'Location
IF SiteLocation = "" THEN  SiteLocation = "Unknown"
RegCommand = "reg add hkcu\SOFTWARE\MYINFO /v SiteLocation /t REG_SZ /d " & SiteLocation & " /f /reg:64"
objShell.Run RegCommand,0,TRUE'applies reg key

'IP FUNCTION - WILL RETURN GATEWAY ADDRESS
FUNCTION ReturnGateway()
  ON ERROR RESUME NEXT
  DIM ws : SET ws = CreateObject("WScript.Shell")
  DIM fso : SET fso = CreateObject("Scripting.FileSystemObject")
  DIM TmpFile : TmpFile = fso.GetSpecialFolder(2) & "/ip.txt"
  DIM gatewayLine, IP, ReturnIPAddress
  IF ws.Environment("SYSTEM")("OS") <> "" THEN     
    ws.run "%comspec% /c ipconfig > " & TmpFile, 0, True
  END IF
  WITH fso.GetFile(TmpFile).OpenAsTextStream
    DO WHILE NOT .AtEndOfStream
      gatewayLine = .ReadLine
      IF InStr(gatewayLine, "Default Gateway") <> 0 THEN  IP = Mid(gatewayLine, InStr(gatewayLine, ":") + 2)
	  IF IP  <> "" THEN  
	     ReturnGateway = IP
		 EXIT FUNCTION'forces exit upon finding first gateway
	  END IF
    Loop
    .Close
  End WITH
  IF IP <> "::" Then
    IF Asc(Right(IP, 1)) = 13 THEN  IP = Left(IP, Len(IP) - 1)
  END IF
  ReturnGateway = IP  
  fso.GetFile(TmpFile).Delete  
  SET fso = Nothing
  SET ws = Nothing
End Function

Wscript.Quit(0)