I hope you are as excited about the release of PrimalForms as I am. In the past creating a Windows form in PowerShell was a very tedious task and one I rarely used except for the most simplest of forms. No more. The free PrimalForms tool lets me create a very rich Windows form using a WYSIWYG editor. I can export the form to a file, add my PowerShell code and call it a day.
Start:
The first time you launch the tool, I strongly encourage you to also click the Getting Started and spend a few minutes going through the Getting Started guide. It will walk you through PrimalForms as well as creating a PowerShell script. I’ve also provided several sample forms and associated scripts. While you could use them in a production environment (after testing of course), they are primarily intended as samples.
Remember, PrimalForms only generates PowerShell code to present the form. If you associate an event with a control, like Click with a button control, the generated PowerShell code will define script blocks. All you have to do is add your PowerShell code. Windows PowerShell v1.0: TFM 2nd Edition has additional information on creating and using Windows Forms with PowerShell.
If you have issues using the tool itself, there is a free tools support forum at SAPIEN.com. If you need help developing a PowerShell script from your form, please use the PowerShell forum at ScriptingAnswers.com.
Sample:
To get you started and perhaps whet your appetite, here is another PrimalForms-generated script. The script gets all the logical disks for a specified computer using WMI and displays useful information. A progress bar will give you a graphical representation of how much free space is left on the drive.
1: #DriveInfo.ps1
2: #v1.0 11/3/2008
3: #Jeffery Hicks jhicks@sapien.com
4: #http://www.scriptingAnswers.com
5:
6: #USAGE: .\driveinfo.ps1
7:
8: # ****************************************************************
9: # * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
10: # * IN A SECURED LAB ENVIRONMENT. USE AT YOUR OWN RISK. *
11: # ****************************************************************
12:
13: Function Get-Drives {
14: Param([string]$computername=$env:computername)
15:
16: #don't display any error messages
17: $drives=Get-WmiObject Win32_logicaldisk -computername $computername `
18: -filter "drivetype=3" -ea "SilentlyContinue"
19:
20: foreach ($drive in $drives) {
21: write $drive.deviceID
22: }
23:
24: }
25:
26: Function Get-DriveInfo {
27: Param([string]$computername=$env:computername,
28: [string]$drive="c:"
29: )
30:
31: $logical=get-wmiobject win32_logicaldisk -computername $computername -filter "deviceid='$drive'"
32: $partition= get-wmiobject -computername $computername `
33: -query "associators of {win32_logicaldisk.deviceid='$drive'} where resultclass=win32_diskpartition"
34:
35: $obj=New-Object PSObject
36: $obj | Add-Member Noteproperty "DeviceId" $logical.DeviceID
37: $obj | Add-Member Noteproperty "VolumeName" $logical.VolumeName
38: $obj | Add-Member Noteproperty "VolumeSerialNumber" $logical.VolumeSerialNumber
39: $obj | Add-Member Noteproperty "PrimaryPartition" $partition.PrimaryPartition
40: $obj | Add-Member Noteproperty "NumberOfBlocks" $partition.NumberofBlocks
41: $obj | Add-Member Noteproperty "BlockSize" $partition.blocksize
42: $obj | Add-Member Noteproperty "BootPartition" $partition.BootPartition
43: $obj | Add-Member Noteproperty "Compressed" $logical.Compressed
44: $obj | Add-Member Noteproperty "Filesystem" $logical.FileSystem
45: $obj | Add-Member Noteproperty "Size(MB)" ($logical.Size/1MB -as [int])
46: $obj | Add-Member Noteproperty "Freespace(MB)" ($logical.Freespace/1MB -as [int])
47: $obj | Add-Member Noteproperty "PercentFree" (([double]$logical.freespace/[double]$logical.size)*100 -as [int])
48: $obj | Add-Member Noteproperty "PartitionSize(MB)" ($partition.size/1MB -as [int])
49:
50: write $obj
51: }
52:
53: ########################################################################
54: # Code Generated By: SAPIEN Technologies PrimalForms 2009 v1.0.0.0
55: # Generated On: 11/3/2008 10:39 AM
56: # Generated By: Jeffery Hicks
57: ########################################################################
58:
59: #region Import the Assembles
60: [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
61: [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
62: #endregion
63:
64: #region Generated Form Objects
65: $form1 = New-Object System.Windows.Forms.Form
66: $linkLabel1 = New-Object System.Windows.Forms.LinkLabel
67: $btnGetInfo = New-Object System.Windows.Forms.Button
68: $richTextBox1 = New-Object System.Windows.Forms.RichTextBox
69: $btnClose = New-Object System.Windows.Forms.Button
70: $comboDrives = New-Object System.Windows.Forms.ComboBox
71: $statusBar = New-Object System.Windows.Forms.StatusBar
72: $lblDrive = New-Object System.Windows.Forms.Label
73: $progUsage = New-Object System.Windows.Forms.ProgressBar
74: $txtComputerName = New-Object System.Windows.Forms.TextBox
75: #endregion Generated Form Objects
76:
77: #----------------------------------------------
78: #Generated Event Script Blocks
79: #----------------------------------------------
80: #Provide Custom Code for events specified in PrimalForms.
81: $CloseForm=
82: {
83: $form1.close()
84: }
85:
86: $OpenDrive=
87: {
88: [system.Diagnostics.Process]::start("Explorer",$linkLabel1.text)
89: }
90:
91: $GetDriveInfo=
92: {
93: $statusBar.Text=("Getting drive details for {0} on {1}" -f $comboDrives.SelectedItem,$txtComputerName.text)
94:
95: $driveData=Get-DriveInfo -computername $txtComputerName.Text -drive $comboDrives.SelectedItem
96:
97: #set drive label to selected DeviceID
98: $lblDrive.text=$driveData.DeviceID
99:
100: #build report data and convert to string
101: $report=$driveData | Format-List |Out-String
102:
103: #set richtext box text to report data
104: $richTextBox1.Text=$report.Trim()
105:
106: $progUsage.Value=$driveData.PercentFree
107:
108: $linkLabel1.text="\\{0}\{1}" -f $txtComputerName.Text.ToUpper(),$driveData.DeviceID.Replace(":","$")
109:
110: $statusBar.Text="Ready"
111:
112: }
113:
114: $GetDrives=
115: {
116: $statusBar.Text=("Getting fixed logical drives for {0}" -f $txtComputername.text.toUpper())
117:
118: #clear richTextBox
119: $richTextBox1.text=$Null
120:
121: $collDrives=Get-Drives $txtComputerName.Text
122: if ($collDrives) {
123: #only proceed if a connection was made to the computer
124: #clear the drive dropdown of any existing values
125: $comboDrives.Items.Clear()
126:
127: #populate the drive dropdown
128: foreach ($drive in $collDrives) {
129: $comboDrives.Items.add($drive)
130: }
131: $comboDrives.SelectedIndex=0
132: $comboDrives.Enabled=$True
133:
134: &$GetDriveInfo
135: }
136: else
137: {
138: $richTextBox1.text=("Failed to get drives for {0}" -f $txtComputerName.Text.ToUpper())
139: $comboDrives.Items.Clear()
140: $comboDrives.Text="N/A"
141: $progUsage.value=0
142: $lblDrive="N/A"
143: $linkLabel1.text="N/A"
144: }
145:
146: $statusBar.Text="Ready"
147:
148: }
149:
150: #----------------------------------------------
151: #region Generated Form Code
152: $form1.Name = 'form1'
153: $form1.Text = 'Drive Report'
154: $form1.DataBindings.DefaultDataSourceUpdateMode = 0
155: $form1.FormBorderStyle = 1
156: $System_Drawing_Size = New-Object System.Drawing.Size
157: $System_Drawing_Size.Width = 284
158: $System_Drawing_Size.Height = 333
159: $form1.ClientSize = $System_Drawing_Size
160: $form1.add_Load($GetDrives)
161:
162: $linkLabel1.TabIndex = 7
163: $linkLabel1.Text = 'open'
164: $linkLabel1.TabStop = $True
165: $linkLabel1.Name = 'linkLabel1'
166: $System_Drawing_Point = New-Object System.Drawing.Point
167: $System_Drawing_Point.X = 151
168: $System_Drawing_Point.Y = 48
169: $linkLabel1.Location = $System_Drawing_Point
170: $linkLabel1.TextAlign = 32
171: $System_Drawing_Size = New-Object System.Drawing.Size
172: $System_Drawing_Size.Width = 100
173: $System_Drawing_Size.Height = 23
174: $linkLabel1.Size = $System_Drawing_Size
175: $linkLabel1.DataBindings.DefaultDataSourceUpdateMode = 0
176: $linkLabel1.add_Click($OpenDrive)
177:
178: $form1.Controls.Add($linkLabel1)
179:
180: $btnGetInfo.UseVisualStyleBackColor = $True
181: $btnGetInfo.Text = 'Get Drives'
182: $btnGetInfo.DataBindings.DefaultDataSourceUpdateMode = 0
183: $btnGetInfo.TabIndex = 1
184: $btnGetInfo.Name = 'btnGetInfo'
185: $System_Drawing_Size = New-Object System.Drawing.Size
186: $System_Drawing_Size.Width = 75
187: $System_Drawing_Size.Height = 23
188: $btnGetInfo.Size = $System_Drawing_Size
189: $System_Drawing_Point = New-Object System.Drawing.Point
190: $System_Drawing_Point.X = 197
191: $System_Drawing_Point.Y = 13
192: $btnGetInfo.Location = $System_Drawing_Point
193: $btnGetInfo.add_Click($GetDrives)
194:
195: $form1.Controls.Add($btnGetInfo)
196:
197: $richTextBox1.Text = ''
198: $richTextBox1.TabIndex = 6
199: $richTextBox1.Name = 'richTextBox1'
200: $richTextBox1.Font = New-Object System.Drawing.Font("Lucida Console",8.25,0,3,1)
201: $richTextBox1.BackColor = [System.Drawing.Color]::FromArgb(255,240,240,240)
202: $richTextBox1.ReadOnly = $True
203: $richTextBox1.BorderStyle = 0
204: $System_Drawing_Size = New-Object System.Drawing.Size
205: $System_Drawing_Size.Width = 259
206: $System_Drawing_Size.Height = 159
207: $richTextBox1.Size = $System_Drawing_Size
208: $richTextBox1.DataBindings.DefaultDataSourceUpdateMode = 0
209: $System_Drawing_Point = New-Object System.Drawing.Point
210: $System_Drawing_Point.X = 13
211: $System_Drawing_Point.Y = 78
212: $richTextBox1.Location = $System_Drawing_Point
213:
214: $form1.Controls.Add($richTextBox1)
215:
216: $btnClose.UseVisualStyleBackColor = $True
217: $btnClose.Text = 'Close'
218: $btnClose.DataBindings.DefaultDataSourceUpdateMode = 0
219: $btnClose.TabIndex = 3
220: $btnClose.Name = 'btnClose'
221: $System_Drawing_Size = New-Object System.Drawing.Size
222: $System_Drawing_Size.Width = 75
223: $System_Drawing_Size.Height = 23
224: $btnClose.Size = $System_Drawing_Size
225: $System_Drawing_Point = New-Object System.Drawing.Point
226: $System_Drawing_Point.X = 102
227: $System_Drawing_Point.Y = 282
228: $btnClose.Location = $System_Drawing_Point
229: $btnClose.add_Click($CloseForm)
230:
231: $form1.Controls.Add($btnClose)
232:
233: $comboDrives.Name = 'comboDrives'
234: $System_Drawing_Size = New-Object System.Drawing.Size
235: $System_Drawing_Size.Width = 121
236: $System_Drawing_Size.Height = 21
237: $comboDrives.Size = $System_Drawing_Size
238: $comboDrives.FormattingEnabled = $True
239: $comboDrives.Enabled = $False
240: $comboDrives.TabIndex = 2
241: $System_Drawing_Point = New-Object System.Drawing.Point
242: $System_Drawing_Point.X = 13
243: $System_Drawing_Point.Y = 50
244: $comboDrives.Location = $System_Drawing_Point
245: $comboDrives.DataBindings.DefaultDataSourceUpdateMode = 0
246: $comboDrives.add_SelectedIndexChanged($GetDriveInfo)
247:
248: $form1.Controls.Add($comboDrives)
249:
250: $statusBar.Name = 'statusBar'
251: $statusBar.DataBindings.DefaultDataSourceUpdateMode = 0
252: $statusBar.TabIndex = 3
253: $System_Drawing_Size = New-Object System.Drawing.Size
254: $System_Drawing_Size.Width = 284
255: $System_Drawing_Size.Height = 22
256: $statusBar.Size = $System_Drawing_Size
257: $System_Drawing_Point = New-Object System.Drawing.Point
258: $System_Drawing_Point.X = 0
259: $System_Drawing_Point.Y = 311
260: $statusBar.Location = $System_Drawing_Point
261: $statusBar.Text = 'Ready'
262:
263: $form1.Controls.Add($statusBar)
264:
265: $lblDrive.Text = 'C:'
266: $lblDrive.DataBindings.DefaultDataSourceUpdateMode = 0
267: $lblDrive.TabIndex = 2
268: $lblDrive.TextAlign = 64
269: $lblDrive.Name = 'lblDrive'
270: $System_Drawing_Size = New-Object System.Drawing.Size
271: $System_Drawing_Size.Width = 32
272: $System_Drawing_Size.Height = 23
273: $lblDrive.Size = $System_Drawing_Size
274: $System_Drawing_Point = New-Object System.Drawing.Point
275: $System_Drawing_Point.X = 0
276: $System_Drawing_Point.Y = 243
277: $lblDrive.Location = $System_Drawing_Point
278:
279: $form1.Controls.Add($lblDrive)
280:
281: $progUsage.DataBindings.DefaultDataSourceUpdateMode = 0
282: $progUsage.Style = 1
283: $progUsage.TabIndex = 1
284: $progUsage.Name = 'progUsage'
285: $System_Drawing_Size = New-Object System.Drawing.Size
286: $System_Drawing_Size.Width = 234
287: $System_Drawing_Size.Height = 23
288: $progUsage.Size = $System_Drawing_Size
289: $progUsage.ForeColor = [System.Drawing.Color]::FromArgb(255,0,255,0)
290: $progUsage.BackColor = [System.Drawing.Color]::FromArgb(255,255,0,0)
291: $System_Drawing_Point = New-Object System.Drawing.Point
292: $System_Drawing_Point.X = 29
293: $System_Drawing_Point.Y = 243
294: $progUsage.Location = $System_Drawing_Point
295:
296: $form1.Controls.Add($progUsage)
297:
298: $txtComputerName.Text = $env:computername
299: $txtComputerName.Name = 'txtComputerName'
300: $txtComputerName.TabIndex = 0
301: $System_Drawing_Size = New-Object System.Drawing.Size
302: $System_Drawing_Size.Width = 178
303: $System_Drawing_Size.Height = 20
304: $txtComputerName.Size = $System_Drawing_Size
305: $System_Drawing_Point = New-Object System.Drawing.Point
306: $System_Drawing_Point.X = 13
307: $System_Drawing_Point.Y = 13
308: $txtComputerName.Location = $System_Drawing_Point
309: $txtComputerName.DataBindings.DefaultDataSourceUpdateMode = 0
310:
311: $form1.Controls.Add($txtComputerName)
312:
313: #endregion Generated Form Code
314:
315: #Show the Form
316: $form1.ShowDialog()| Out-Null
317:
The script defaults to the C: drive on the local host. Enter a new computername, and click the Get Drives button. This will populate the drop down list with all logical drives on that computer. The default drive will be C:\. An error will be displayed if the remote computer can’t be reached. The script assumes you have administrative shares enabled so you can click on the link to the right and connect to the corresponding share.
You can download a zip file with the form and script here.
Share:
Once you finish your PowerShell forms script, I hope you’ll share it. Not only might other administrators need your tool, they might find it helpful as a template or starting point for there own projects.
Hi, after a test I created for me a form which has the basic functionality of SMS Client’s Run advertised Programs snapin. I really like PrimalForms 🙂
Available at http://www.powershell.cz, direct link: http://powershell-cz.blogspot.com/2008/11/primalforms-prvn-formul-first-form.html
David
This is a huge deal – looks great and works great.