PowerShell In GUI Blog

PowerShell GUI Box Just In A Few Clicks

Archive for May 2011

PowerShell Wizard. Round 2. It works!

with one comment

After posting the wizard sample, I thought – why don’t finish it today? I added

  • the Finish and the Cancel buttons in a way that the Finish button asks the user whether one wishes to exit now or not. The Cancel is available on the first step and by clicking this the user quits immediately
  • scriptblocks, used as a code that is run on clicking the Next button
  • fixed bugs, added comments here and there and a bit of polishing

At first, I’d like to show what the sample does.

It starts the wizard, sets the second step as the first the user sees (just for example) and provides a label saying that the wizard is awaiting for a path to any directory.

After that the user presses the next button (it stays here if the text box field is empty. The wrong path won’t be accepted too) and goes to the next step called, just for example, the Progress step:

The step called in the sample as Output contains a list box filled with the files list:

After all, at the last step can be written something encouradging, or an error log to be shown, or something else. There comes the Finish button, as well as the Cancel button comes at the first step of the wizard:

Now, after we know what this does, I can post the code running the sample:

		# Step 1: Welcome
		New-WizardStep 'Welcome' `
			'This is the first step' `
			'Welcome to the PowerShell Wizard, the our dear customer!';
		# Add a label
		# Please note that we can use the enumeration $steps which is being created runtime
		# on a call of the New-WizardStep function
		Add-ControlToStep $steps.Welcome `
			System.Windows.Forms.Label `
			'lblWelcome' 20 10 50 300 `
			'This Wizard carries you through the steps you need to collect the files from a given path';

		# Step 2
		New-WizardStep 'Input' `
			'Step Two' `
			'Here you type some in controls, plz';
		# Add a label
		Add-ControlToStep $steps.Input `
			System.Windows.Forms.Label `
			'lblInput' 20 10 20 300 `
			'Please type the path to a catalog';
		# Add a text box
		Add-ControlToStep $steps.Input `
			System.Windows.Forms.TextBox `
			'txtInput' 40 10 20 300
		# Add the code which requires that text box was not empty
		Add-CodeToStep $steps.Input `
			-StepCode {
					[string]$private:path = `
						$wzdSteps[$steps.Input].Controls['txtInput'].Text;
					if ($private:path.Length -eq 0)
					{
						# stop the step
						throw;
					}
					if (-not [System.IO.Directory]::Exists($private:path))
					{
						# stop the step
						throw;
					}
				}

		# Step 3
		New-WizardStep 'Progress' `
			'The third one' `
			'Wait, please. Sip a coffee' ;
		# Add a progress bar
		Add-ControlToStep $steps.Progress `
			'System.Windows.Forms.ProgressBar' `
			'pbDir' 200 50 100 400
		Add-CodeToStep $steps.Progress `
			-StepCode {
					# set progress bar maximum
					$wzdSteps[$steps.Progress].Controls['pbDir'].Minimum = 0;
					$wzdSteps[$steps.Progress].Controls['pbDir'].Value = 0;
					$wzdSteps[$steps.Progress].Controls['pbDir'].Maximum = `
						(Get-ChildItem $wzdSteps[$steps.Input].Controls['txtInput'].Text).Length;
					# clear the list box (from the next step)
					$wzdSteps[$steps.Output].Controls['lbxFiles'].Items.Clear();
					# add file names to the list box
					Get-ChildItem $wzdSteps[$steps.Input].Controls['txtInput'].Text | %{
							$wzdSteps[$steps.Progress].Controls['pbDir'].Value++;
							$wzdSteps[$steps.Output].Controls['lbxFiles'].Items.Add($_.Name);
						}
				}

		# Step 4
		New-WizardStep 'Output' 'Fourth' `
			'Now awake and read the output';
		# Add a list box
		Add-ControlToStep $steps.Output `
			System.Windows.Forms.ListBox `
			lbxFiles 50 50 300 400

		# Step 5: Finish
        New-WizardStep 'Finish' 'Finish!' 'Bye!';

		Initialize-Wizard;
		# Set the second step as active
		Invoke-WizardStep -Forward $true;

		$script:frmWizard.ShowDialog() | Out-Null;

The full version is posted in the box at rigth and published on the PoshCode. Ask for a doc or more comments in the code if you need to.

Kindle for PowerShellers. Part 3. Reading your favorite blogs. Instapaper

leave a comment »

In the previous post of this series, we tested Amazon’s blog subscription. Now we must review an alternative solution, because it’s so common in the modern world to have free and/or open source counterparts of almost every application. I’d like to announce the Instapaper service review!

At first, let’s look at their version of how to publish blogs. The Contents is, in my opinion, better than the one Amazon compiles (but contents list of newspapers and magazines I like the most):

The View Articles List layout is exactly the very layout in Amazon’s subscriptions:

The following pictures display the article itself, the same one we tested earlier:

No pictures is added to an article, thus I’ll give only one screenshot to help you comprehend how much and, at the same time, how infinitesimal the difference between paid and free solutions.

The paid solution provides pictures, but the free one provides the better contents list. One thing to finish this comparison is to go the same way the user must go every time one wishes to download a new issue.

After registration on the Instapaper page, the registration is free, but you are given the possibility to pay $1 a month to support the project, you might begin collecting your articles list. Mine, used as an example for the subscription shown above, is today as follows:

The figure shows several noticeable things:

  • The ‘Add folders’ link to make the Contents of your issue organized in a manner you’d prefer
  • The ‘Read Later’ bookmarklet, the mechanism which you will use to gather pages you want to have in the issue
  • The Download options, where the central of them allows you to compile the issue right now and download it to a computer, whence you may sent it to a Kindle through wire or air.

I rarely use the first bullet owing to the perpetual lack of time, so that let’s immediately discuss the second one. After installing the bookmarklet, all the work you need to perform is to navigate to a page you want to add and to click the button. A monotonous, but not a very long and Amazon’s paiments-free task.

When your collection is replete with articles and you are ready to compile the issue (automated compilation and sending to a Kindle never worked for me), it’s about time to visit the ‘Account Settings’ section:

By clicking on the ‘Manage my Kindle settings’ link, you are in the very heart of your subscription:

Here you may set delivery settings and the address of your Kindle. Don’t forget to click on the ‘Save changes’ button. Also, here is one of the most interesting features of this service, the ‘Send now’ button, the button I used to demonstrate the issue.

Written by Alexander Petrovskiy

May 26, 2011 at 10:11 pm

Kindle for PowerShellers. Part 2. Reading your favorite blogs. The Amazon’s way

with one comment

The Kindle gives great possibilities to read blogs you accustomed to follow. The first way to do that is what Amazon offers – the blog subscription. The number of blogs you may choose to subscribe is significant, so that there are ratings, categorizing  and search helping you.

By today, the extent of quality of pictures and the usability of reading long lines of text and code are not what all the users agree to accept. Therefore, the two weeks’ trial is the time you may decide whether you need or needn’t to subscribe. No more restrictions here, even hundreds of blogs can be tested for two weeks.

To see what does a PowerShell blog on a Kindle  like, let’s take one of officials blogs, the PowerShell Guy blog. Below is today’s article:

As can be seen, pictures are now allowed in blogs as well as in newspapers (only several months ago pictures were almost prohibited here and there, in newspapers). Unfortunately, pictures are not of perfect quality due to the promise to deliver a blog in sixty seconds including the transmitting over 3G networks. On the other hand, technical blogs are not for seeing photos.

Amazon provides two options to see more on pictures: to increase on a click

and to visit the source by clicking on the small icon at the right side of a picture.

Articles are collected to a something like a newspaper (newspapers I like more because of their Contents style):

Even with the smallest available font size the contents is worse, to my mind, than those in a newspaper:

The contents in a newspaper or in a magazin is always of one page, whilst for the blog we took we see seven pages, what is sometimes even more than in some books of a thousand pages.

Owing to the discrepancy between text rendering in an HTML page and the Kindle screen, text and code are readable, but even with the smallest font the lines are longer than the width of a Kindle screen:

To conclude this review (and to turn to a review of alternative ways to read blogs), there’s time to say that you are usually charged to pay for this service from $0.99 to $1.99 a month. So that it’s your clue to choose blogs that to be updated daily or weekly, the more the blog is informative, the more often it gets updated, the more money Amazon ask for reading it.

Written by Alexander Petrovskiy

May 26, 2011 at 10:01 am

Hey, Scripting GUI! PowerShell wizard in a couple of minutes

with one comment

At the same time when many PowerShell glitteriti entertained the public at TechEd with some PowerShell tricks or new applications, we didn’t spend our time too. Today’s module is intended to help all who creates PowerShell scripts with conversion of these scripts to GUI tools.

Accordingly to Ravikanth’s survey results, the vast majority of scripts delivered to consumers or colleagues are wrapped into some GUI (the first chart). The second chart clearly shows that most respondents do it just because GUI tools are warmly accepted by consumers in opposite to bare commandline scripts, even with the richest system of parameters.

Discussing this topic further, we should conclude that the scriptwriting itself is not an easy work. Scripts need writing, debugging, testing, being more or less universal, its bugs should be found and fixed, in an ideal case. Traditionally, scripts are harder for us to debug than applications of compiled frameworks. The stranger seems the state of affairs that scripters are obliged to create forms in addition to their hard work.

At that point, we turn to the third chart to see that scripters prefer tools belonged to a big class called Rapid Application Development instruments, which includes Primal Forms, Visual Studio and SharpDevelop. Need to admit that a few chose WPK, a framework combining simplicity of its object model and complexity of commandline tools.

However, these RAD tools are not what does all the work instead of us. You need not only paint controls and write the behind code, what’s about doing something intricate like a wizard? Such non-standard in the PowerShell world tasks (which are common for a decade or more in the world of RAD) are laborious. RAD tools are often shipped with out-of-the-box templates allowing you to add some code without thinking how to make wizard’s panels rotating on the Next button clicking.

Templates! What is the answer to the problem! PowerShell scripters need templates.

The code below demonstrates how can the user modify a template aiming to construct a wizard. Please note, that

  • for now, this is only a concept having no actions. In other words, it’s only easily to play around with the template, but adding the real code is not easy yet
  • there is no Finish and Cancel buttons
  • there is no way to disable the Next or Back buttons
  • and other restrictions persist (Do I sugar the pills if I say that the graphical tool allowing you to paint a wizard in a few clicks is coming,? I’m planning to publish the module at the beginning of the next week or slightly later)
cls
Set-StrictMode -Version 2
#region host preparations
if ($Host.Name -eq 'ConsoleHost')
{
	Add-Type -AssemblyName System.Windows.Forms;
	Add-Type -AssemblyName System.Drawing;
}
#endregion host preparations
#region the resulting wizard
	#region adjustable settings
		#region controls settings
		# Form size and caption
		[string]$script:constWizardInitialCaption = `
			'This is a sample wizard';
		[int]$script:constWizardWidth = `
			[System.Windows.Forms.SystemInformation]::VirtualScreen.Width / 2;
		[int]$script:constWizardHeight = `
			[System.Windows.Forms.SystemInformation]::VirtualScreen.Height / 2;
		# Buttons Next, Back
		[int]$script:constButtonHeight = 23;
		[int]$script:constButtonWidth = 75;
		[int]$script:constButtonAreaHeight = `
			$script:constButtonHeight * 2;
		[string]$script:constButtonNextName = '&Next';
		[string]$script:constButtonBackName = '&Back';
		# Step display name and description
		[int]$script:constLabelStepDisplayNameLeft = 5;
		[int]$script:constLabelStepDisplayNameTop = 0;
		[float]$script:constLabelStepDisplayNameFontSize = 16;
		[int]$script:constLabelStepDescriptionLeft = 5;
		[int]$script:constLabelStepDescriptionTop = 30;
		# Form properties
		[bool]$script:constWizardRigthToLeft = $false;
		# Initial step number
		[int]$script:currentStep = 0;
		#endregion controls settings
	#endregion adjustable settings
	#region mandatory settings
		#region Initialization of the SplitContainer controls
		# The outer split container
		[System.Windows.Forms.SplitContainer]$script:splitOuter = `
			New-Object System.Windows.Forms.SplitContainer;
			$script:splitOuter.Dock = [System.Windows.Forms.DockStyle]::Fill;
			$script:splitOuter.IsSplitterFixed = $true;
			$script:splitOuter.Orientation = `
				[System.Windows.Forms.Orientation]::Horizontal;
			$script:splitOuter.SplitterWidth = 5;
		# The inner split container
		[System.Windows.Forms.SplitContainer]$script:splitInner = `
			New-Object System.Windows.Forms.SplitContainer;
			$script:splitInner.Dock = [System.Windows.Forms.DockStyle]::Fill;
			$script:splitInner.IsSplitterFixed = $true;
			$script:splitInner.Orientation = `
				[System.Windows.Forms.Orientation]::Horizontal;
			$script:splitInner.SplitterWidth = 5;
			$script:splitOuter.Panel1.Controls.Add($script:splitInner);
		# The labels for the curent step name and description
		[System.Windows.Forms.Label]$script:lblStepDisplayName = `
			New-Object System.Windows.Forms.Label;
			$script:lblStepDisplayName.Left = `
				$script:constLabelStepDisplayNameLeft;
			$script:lblStepDisplayName.Top = `
				$script:constLabelStepDisplayNameTop;
			[System.Drawing.Font]$private:font = `
				$script:lblStepDisplayName.Font;
			$private:font = `
				New-Object System.Drawing.Font($private:font.Name, `
						$script:constLabelStepDisplayNameFontsize, `
			            $private:font.Style, $private:font.Unit, `
			            $private:font.GdiCharSet, $private:font.GdiVerticalFont );
			$script:lblStepDisplayName.Font = $private:font;
		[System.Windows.Forms.Label]$script:lblStepDescription = `
			New-Object System.Windows.Forms.Label;
			$script:lblStepDescription.Left = `
				$script:constLabelStepDescriptionLeft;
			$script:lblStepDescription.Top = `
				$script:constLabelStepDescriptionTop;
		$script:splitInner.Panel1.Controls.AddRange(($script:lblStepDisplayName, `
			$script:lblStepDescription));
		#endregion Initialization of the SplitContainer controls
		#region the Next and Back buttons
		[System.Windows.Forms.Button]$script:btnNext = `
			New-Object System.Windows.Forms.Button;
		$script:btnNext.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnNext.Text = $script:constButtonNextName;
		[System.Windows.Forms.Button]$script:btnBack = `
			New-Object System.Windows.Forms.Button;
		$script:btnBack.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor `
			[System.Windows.Forms.AnchorStyles]::Right -bor `
			[System.Windows.Forms.AnchorStyles]::Top;
		$script:btnBack.Text = $script:constButtonBackName;
	    $script:btnBack.Enabled = $false;
		$script:splitOuter.Panel2.Controls.AddRange(($script:btnBack, $script:btnNext));
		#endregion the Next and Back buttons
		#region Initialization of the main form
		$script:frmWizard = $null;
		[System.Windows.Forms.Form]$script:frmWizard = `
			New-Object System.Windows.Forms.Form;
		$script:frmWizard.Controls.Add($script:splitOuter);

		if ($script:constWizardRigthToLeft)
		{
			$script:frmWizard.RightToLeft = `
				[System.Windows.Forms.RightToLeft]::Yes;
			$script:frmWizard.RightToLeftLayout = $true;
		}
		else
		{
			$script:frmWizard.RightToLeft = `
				[System.Windows.Forms.RightToLeft]::No;
			$script:frmWizard.RightToLeftLayout = $false;
		}
		$script:frmWizard.Text = $script:constWizardInitialCaption;
		#endregion Initialization of the main form
	#endregion mandatory settings
	#region the Wizard steps
	[System.Collections.ArrayList]$script:wzdSteps = `
		New-Object System.Collections.ArrayList;
		# Here we create an 'enumeration' (PSObject)
		# and begin filling ArrayList $script:wzdSteps with Panel controls
		[System.EventHandler]$script:hndlRunControlsAdd = `
			{try{$script:splitInner.Panel2.Controls.Add($script:wzdSteps[$script:currentStep]);}catch{Write-Debug $Error[0]; Write-Debug $global:Error[0];}};
			#region function New-WizardStep
		function New-WizardStep
		{
			param(
				  [string]$StepName,
				  [string]$StepDisplayName,
				  [string]$StepDescription = ''
				  )
			# Storing parameters in step arrays
			Add-Member -InputObject $script:steps -MemberType NoteProperty `
				-Name $StepName -Value $script:wzdSteps.Count;
			$null = $script:stepDisplayNames.Add($StepDisplayName);
			$null = $script:stepDescriptions.Add($StepDescription);
			# Create and add the new step's panel to the array
			[System.Windows.Forms.Panel]$private:panel = `
				New-Object System.Windows.Forms.Panel;
			$null = $script:wzdSteps.Add($private:panel);
			$script:currentStep = $script:wzdSteps.Count - 1;

			$script:splitInner.Panel2.Controls.Add($script:wzdSteps[$script:currentStep]);

			$script:wzdSteps[$script:currentStep].Dock = `
				[System.Windows.Forms.DockStyle]::Fill;
			# To restore initial state for this code running before the user accesses the wizard.
			$script:currentStep = 0;
		}
			#endregion function New-WizardStep
			#region function Add-ControlToStep
		function Add-ControlToStep
		{
			param(
				  [string]$StepNumber,
				  [string]$ControlType,
				  [string]$ControlName,
				  [int]$ControlTop,
				  [int]$ControlLeft,
				  [int]$ControlHeight,
				  [int]$ControlWidth,
				  [string]$ControlData
				 )
			$private:ctrl = $null;
			try{
				$private:ctrl = New-Object $ControlType;
			}catch{Write-Error "Unable to create a control of $($ControlType) type";}
			try{
				$private:ctrl.Name = $ControlName;
			}catch{Write-Error "Unable to set the Name property with value $($ControlName) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Top = $ControlTop;
			}catch{Write-Error "Unable to set the Top property with value $($ControlTop) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Left = $ControlLeft;
			}catch{Write-Error "Unable to set the Left property with value $($ControlLeft) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Height = $ControlHeight;
			}catch{Write-Error "Unable to set the Height property with value $($ControlHeight) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Width = $ControlWidth;
			}catch{Write-Error "Unable to set the Width property with value $($ControlWidth) to a control of the $($ControlType) type";}
			try{
				$private:ctrl.Text = $ControlData;
			}catch{Write-Error "Unable to set the Text property with value $($ControlData) to a control of the $($ControlType) type";}
			try{
				$wzdSteps[$StepNumber].Controls.Add($private:ctrl);
			}catch{Write-Error "Unable to add a control of $($ControlType) type to the step $($StepNumber)";}
		}
			#endregion function Add-ControlToStep
		# Step data arrays
		[psobject]$script:steps = New-Object psobject;
		[System.Collections.ArrayList]$script:stepDisplayNames = `
			New-Object System.Collections.ArrayList;
		[System.Collections.ArrayList]$script:stepDescriptions = `
			New-Object System.Collections.ArrayList;
	#endregion the Wizard steps
	#region events of the wizard controls
		#region resizing
			#region function Initialize-WizardControls
	function Initialize-WizardControls
	<#
		.SYNOPSIS
			The Initialize-WizardControls function sets the wizard common controls to predefined positions.

		.DESCRIPTION
			The Initialize-WizardControls function does the following:
			- sets Top, Left, Width and Height properties of the wizard buttons
			- positions of the step labels
			- sets the SplitterDistance property of both Splitcontainer controls

		.EXAMPLE
			PS C:\> Initialize-WizardControls
			This example shows how to step the wizard forward.

		.INPUTS
			No input

		.OUTPUTS
			No output
	#>
	{
		# Set sizes of buttons
		$script:btnNext.Height = $script:constButtonHeight;
		$script:btnNext.Width = $script:constButtonWidth;
		$script:btnBack.Height = $script:constButtonHeight;
		$script:btnBack.Width = $script:constButtonWidth;
		# SplitterDistance of the outer split container
		# in other words, the area where Next and Back buttons are placed
		$script:splitOuter.SplitterDistance = `
			$script:splitOuter.Height - `
			$script:constButtonAreaHeight;
		#if ($script:splitOuter.SplitterDistance -lt 0)
		#{$script:splitOuter.SplitterDistance = 10;}
		#$script:splitOuter.SplitterDistance = `
		#	$script:splitOuter.Height - `
		#	$script:constButtonAreaHeight;

		# Placements of the buttons
		if ($script:constWizardRigthToLeft)
		{
			$script:btnNext.Left = 10;
			$script:btnBack.Left = $script:constButtonWidth + 20;
		}
		else
		{
			$script:btnNext.Left = $script:splitOuter.Width - `
				$script:constButtonWidth - 10;
			$script:btnBack.Left = $script:splitOuter.Width - `
				$script:constButtonWidth - `
				$script:constButtonWidth - 20;
		}
		$script:btnNext.Top = `
			($script:constButtonAreaHeight - $script:constButtonHeight) / 2;
		$script:btnBack.Top = `
				($script:constButtonAreaHeight - $script:constButtonHeight) / 2;

		# SplitterDistance of the inner split container
		# this is the place where step name is placed
		$script:splitInner.SplitterDistance = `
			$script:constButtonAreaHeight * 1.5;
			#$script:splitOuter.Panel2.Height * 1.5;
		#if ($script:splitInner.SplitterDistance -lt 0)
		#{$script:splitInner.SplitterDistance = 10;}

		# Step Display Name and Description labels
		$script:lblStepDisplayName.Width = `
			$script:splitInner.Panel1.Width - `
			$script:constLabelStepDisplayNameLeft * 2;
		$script:lblStepDescription.Width = `
			$script:splitInner.Panel1.Width - `
			$script:constLabelStepDescriptionLeft * 2;

		# Refresh after we have changed placements of the controls
		[System.Windows.Forms.Application]::DoEvents();
	}
			#endregion function Initialize-WizardControls
	[System.EventHandler]$script:hndlFormResize = {Initialize-WizardControls;}
	[System.EventHandler]$script:hndlFormLoad = {Initialize-WizardControls;}
	#[System.Windows.Forms.MouseEventHandler]$script:hndlSplitMouseMove = `
	#	{Initialize-WizardControls;}
	# Initial arrange on Load form.
	$script:frmWizard.add_Load($script:hndlFormLoad);
	#$script:frmWizard.add_Resize($script:hndlFormResize);
	$script:splitOuter.add_Resize($script:hndlFormResize);
		#endregion resizing
		#region steps
			#region function Invoke-WizardStep
	function Invoke-WizardStep
	<#
		.SYNOPSIS
			The Invoke-WizardStep function sets active panel on the wizard form.

		.DESCRIPTION
			The Invoke-WizardStep function does the following:
			- changes internal variable $script:currentStep
			- sets/resets .Enabled property of btnNext and btnBack
			- changes .Dock and .Left properties of every panel

		.PARAMETER  Forward
			The optional parameter Forward is used to point out the direction the wizard goes.

		.EXAMPLE
			PS C:\> Invoke-WizardStep -Forward $true
			This example shows how to step the wizard forward.

		.INPUTS
			System.Boolean

		.OUTPUTS
			No output
	#>
	{
		[CmdletBinding()]
		param(
			  [Parameter(Mandatory=$false)]
			  [bool]$Forward = $true
			  )
		Begin{}
		Process{
		if ($Forward)
		{
			$script:btnBack.Enabled = $true;
			if ($script:currentStep -lt ($script:wzdSteps.Count - 1))
			{$script:currentStep++;}
			if ($script:currentStep -lt ($script:wzdSteps.Count - 1))
			{$script:btnNext.Enabled = $true;}
			else
			{$script:btnNext.Enabled = $false;}
		}
		else
		{
			$script:btnNext.Enabled = $true;
			if ($script:currentStep -gt 0)
			{$script:currentStep--;}
			if ($script:currentStep -gt 0)
			{$script:btnBack.Enabled = $true;}
			else
			{$script:btnBack.Enabled = $false;}
		}
		for($private:i = 0; $private:i -lt $script:wzdSteps.Count;
			$private:i++)
		{
			if ($private:i -ne $script:currentStep)
			{
				$script:wzdSteps[$private:i].Dock = `
					[System.Windows.Forms.DockStyle]::None;
				$script:wzdSteps[$private:i].Left = 10000;
			}
			else
			{
				$script:wzdSteps[$private:i].Dock = `
					[System.Windows.Forms.DockStyle]::Fill;
				$script:wzdSteps[$private:i].Left = 0;
			}
		}
		$script:lblStepDisplayName.Text = `
			$script:stepDisplayNames[$script:currentStep];
		$script:lblStepDescription.Text = `
			$script:stepDescriptions[$script:currentStep];
		}
		End{}
	}
			#endregion function Invoke-WizardStep
			#region function Initialize-WizardStep
	function Initialize-WizardStep
	# This is the selfsufficient function doing all the necessary
	# calculations for controls on each panel.
	# Also from the code can be seen how to address the panel you are interesting in
	# using the 'enumeration' created earlier
	# for example, $script:wzdSteps[$script:steps.Welcome]
	{
		$script:lblStepDisplayName.Text = `
			$script:stepDisplayNames[$script:currentStep];
		$script:lblStepDescription.Text = `
			$script:stepDescriptions[$script:currentStep];
	}
			#endregion function Initialize-WizardStep
	[System.EventHandler]$hndlStepForward = {
		# serve controls' data
		Initialize-WizardStep;
		# switch panels
		Invoke-WizardStep $true;
	}
	[System.EventHandler]$hndlStepBack = {
		# switch panels
		Invoke-WizardStep $false;
	}
	$script:btnNext.add_Click($script:hndlStepForward);
	$script:btnBack.add_Click($script:hndlStepBack);
		#endregion steps
	#endregion events of the wizard controls
	#region wizard initialization
		#region function Initialize-Wizard
	function Initialize-Wizard
	# This is one more selfsufficient function written to make
	# the latest preparations for the form run
	{
		#region control settings
		$script:frmWizard.Width = $script:constWizardWidth;
		$script:frmWizard.Height = $script:constWizardHeight;
		#endregion control settings
		Initialize-WizardStep;
	}
		#endregion function Initialize-Wizard
	#endregion wizard initialization
#endregion the resulting wizard

		# Step 1: Welcome
		New-WizardStep 'Welcome' 'This is the first step' 'Welcome to the PowerShell Wizard, the our dear customer!';
		# Add a label
		# Please note that we can use the enumeration $steps which is being created runtime
		# on a call of the New-WizardStep function
		Add-ControlToStep $steps.Welcome System.Windows.Forms.Label 'lblWelcome' 20 10 50 300 'This Wizard carries you through the steps you need to collect the files from a given path';

		# Step 2
		New-WizardStep 'Input' 'Step Two' 'Here you type some in controls, plz';
		# Add a label
		Add-ControlToStep $steps.Input System.Windows.Forms.Label 'lblInput' 20 10 20 300 'Please type the path to a catalog';
		# Add a text box
		Add-ControlToStep $steps.Input System.Windows.Forms.TextBox 'txtInput' 40 10 20 300

		# Unfortunately, there is no way right now to test the user input with ease
		# So we can disable the Next button manually (to be improved soon)
		# this code works wrong:
		#if ($wzdSteps[$steps.Input].Controls['txtInput'].Text.Length -eq 0)
		#{
		#	$btnNext.Enabled = $false;
		#}
		#else
		#{
		#	$btnNext.Enabled = $true;
		#}

		# Step 3
		New-WizardStep 'Progress' 'The third one' 'Wait, please. Sip a coffee' ;
		# Add a progress bar
		Add-ControlToStep $steps.Progress 'System.Windows.Forms.ProgressBar' 'pbDir' 200 50 100 400

		# Step 4
		New-WizardStep 'Output' 'Fourth' 'Now awake and read the output';
		# Add a list box
		Add-ControlToStep $steps.Output System.Windows.Forms.ListBox lbxFiles 50 50 300 400

		# Step 5: Finish
        New-WizardStep 'Finish' 'Finish!' 'Bye!';

		Initialize-Wizard;
		# Set the second step as active
		Invoke-WizardStep -Forward $true;

		$script:frmWizard.ShowDialog() | Out-Null;

Sorry for such a long output! The same code attached here.

Reign over your network with only a Kindle?

with 2 comments

Although any kind of advertisement is not the intent I am writing on these pages, the latest buzz motivated me too to drop a word on web powershell.

Have you ever thought about how to manage your network(s) laying languidly upon the beach, tanning and using the worldwide free Internet access? I have. Now I’ll be showing the facts and you the reader is the judge if it is possible to administer maximally remotely from a resort or not yet.

The check list of preparations is of three items (with exception of course sandals, towels and so forth):

  • a Kindle connected to a some network (Wi-Fi or GSM 3G is what is needed) from $114
  • a Mobile Shell box – from one 3G KIndle or two Wi-Fi special offer’s Kindles apiece
  • some scripts, especially changing security settings or touching the file system your boss’s host, to make the life breathtakingly sharper.

At first, buy and register a Kindle and download your copy of MobileShell here. While the latter can be downloaded on a monthly trial basis, the former needs defraying (you may try to use Amazon Return policy, though. If your test failed only). Go throught the text below if you have already checked all items above.

Install the software as said here (won’t you read the manual going to a beach?) and out, out to the beach. Any tests on a Kindle can be performed from there, for what else reason you sponsored the development of Pearl screens buying it?

Let’s connect to the MobileShell host. The only note here is that you need use strictly the mobile version by typing https://host_name_or_address/MobileShell/mobile , otherwise the Kindle bravely tries to swallow the desktop version, its browser got swollen and died until the device restarts.

After Kindle said you your rights, you are connected and may or may not see the choice if somebody knowing your login and password, you for example, was last night here:

We are leaving out the Favorites list

since we wanted to run a script or a piece of code. Probably unlike you, I forgot to write scripts and will run something useless. Meet the Kindle PowerShell Code Editor:

Of two colors, black and white, isn’t it? The very conservative design, easier than ‘vi’, though.

Some English IntelliSense helped us and our script is ready!

The first run is in a second, take a sip of what you drink on the sand and press the Run button!

Oops, the folder where I stored screenshots is where I’m sitting and I’m sitting not on the MobileShell host. But it would have found the folder if I’d written right, beyond the doubts.

Written by Alexander Petrovskiy

May 19, 2011 at 8:49 pm

Kindle for PowerShellers. Part 1. Notes and Highlighting

leave a comment »

This post is the first one of the small series regarding how to use a Kindle to be deeply involved in PowerShell. All the written in most cases are applicable to any technology or language, or environment, but since the theme of this blog is PowerShell, so that the series is named ‘Kindle for PowerShellers’.

The first idea to share is how to have with you your thoughts that came at the time you’ve been reading something PowerShell-ing. Kindle is a great instrument to do that. When I’m reading I often use highlighting to spare ideas, phrases, code samples and all I’ve found noticeable.

Since the version 3.1 got available on February, Amazon supports public highlighting. What’s it? If you wish, you might not only save your selections, but make them public by pressing Alt + Enter. The figure below demonstrates highlights done by the Kindle owner:

The following highlight is ready to be published:

At last, this one is how you can see others’ highlights:

The result of selecting the View popular Highlights menu item as well as what you see during the reading is a one or more underlined rows and the number of users which highlighted the excerpt.

In addition, there is a way to say something about you’ve read a moment ago by adding a note (I don’t like typing on a Kindle :), but somebody possibly does). Thus, there is also a way to see what others wrote by selecting the View Notes & Marks menu item. It brings to you not only your bookmarks, highlights and notes, but also others’.

The second amazing thing is that you might access all of these almost everywhere. Kindle for most popular platforms can be downloaded here.

That means that you are not obliged to buy a hardware Kindle (I sincerely advise to if you love reading comfortable for eyes and a half of pound is not a weight for you), instead you may use, for example, Kindle for PC (but not with every corporate proxy, though).

The last but not least, you may access your notes as well as other readers by using an Internet connection. To perform this, go to the Kindle page, log in and navigate to or search for books you are interesting in. The Your books section is a starting point for that. All your notes are available in a browser window! The direct link to the full collection is https://kindle.amazon.com/your_highlights .

From my point of view, the web access to your or other readers’ notes is the best way if you want to conspect the book or remember key points.

Also, there is the possibility to publish your notes and highlights in case that they are private yet. Not being a native speaker, I highlight much of the book (all the phrases I found sound or interesting) so that I almost never share mine:

The pleasant thing here is that you may add new notes at the web page, using your favorite full-size desktop keyboard or notebook’s one instead of Kindle keyboard approximately of a mobile phone size.

Having trouble with your head’s RAM? There is the Daily Review flashcards helping you scoop up the knowledge from the book currently in reading.

Finally, the experimental Kindle for the Web is available on this remarkable page – with this tool you are given the opportunity to eye into the books you are only licking your lips at:

Bringing this long panegyric to an end, can I omit the Sync to Furthest Page Read menu item? I can’t, this does the reading on several devices and desktops even more comfortable. Have I forgotten to say that with any Kindle application you are given (especially if you like me are not trueborn English speaker) with two Oxford English-to-English dictionaries and one Duden Wörterbuch as well?

Many thanks to the books starring in this post: 🙂

1. Layman’s Guide to PowerShell 2.0 remoting

2. PowerShell for Microsoft SharePoint 2010 Administrators

Written by Alexander Petrovskiy

May 16, 2011 at 3:53 pm

Mortal combat: Coloring Masters Cup 1/2 final

leave a comment »

Who is the winner? Give the answer at last, may ask the intrigued reader. Well, the testing is almost over and soon comes the final. Two fightings were conducted, the honesty and independence is kept by using the same test script.

The first is between PowerGUI 2.4 (Copy as HTML) and IsePack of PowerShellPack:

https://powershelldevtools.wordpress.com/2011/05/06/test-code-2-2/

Next, this is a note that IsePack of PowerShellPack works well with multi-string here-strings:

https://powershelldevtools.wordpress.com/2011/05/06/test-code-3-isepack-vs-here-string/

What? It spoils multi-string here-strings too? This is obviously the result of sequential savings of the post. The WordPress’s bug most likely.

At last, the bout between twins, SparkPlug for PowerGUI and SparkPlug for ISE:

https://powershelldevtools.wordpress.com/2011/05/06/test-code-4-sparkplug-for-powergui-2-4-vs-sparkplug-for-ise/

The twins are equally strong, but SparkPlug for PowerGUI was declared the winner on points due to the real mess-up in the ISE menu if you have previously installed and run IsePack.

All the post protected with the password 123 so as not to harm too young and too impressive powershellers, and to preserve the Google Environment from duplicated search spam too.

We have a leader! Currently the strongest fighter of all the desktop applications and the common candidate is SparkPlug of Script-Automating!

What’s about the final? I’d expect that the delegate of the WordPress web-services (grown up on the Internet users’ needs, please note) are trying and be fit to fight sooner or later. Really couln’t help waiting, the simplicity of copy-paste and sourcecode tag and the ability to highlight row against the embedded desktop heavyweight is tickling my nerves.

Written by Alexander Petrovskiy

May 6, 2011 at 7:49 am

Posted in Powershell

Tagged with