Wednesday, July 31, 2013

Building GUI for PowerShell Scripts using PowerShell Studio 2012

Why a GUI ?

A GUI can often make a task easier and more constrained for less experienced users for example our "Service Desk" Folks.

PowerShell is built on the .NET framework which has entire set of capabilities for building GUI's.

These capabilities are accessible to powershell but require quite lengthy and complicated coding.

To avoid this complications i recommend using a Nice Tool from Sapien, PowerShell Studio 2012.

PowerShell Studio gives you the tools you need to bring your PowerShell tasks to successful completion.

PowerShell Studio Enables you to package your script into executables (.exe) and share it with others who have relatively less scripting experience.

You can download the free trial from

After the Trial Expires you can extend the functionality by procuring a license key from sapien.

You can also use  Primal Forms Community Edition, No Export to Executable option in Primal Forms Community Edition.

However You can export to ps1 and integrate it in your script :)

PowerShell Studio 2012 - Key Features

  • PowerShell Console - Not just one, but two hot-swappable consoles: 32-bit and 64-bit
  • PowerShell Script Editor - Awesome Script Editor, But now PowerShell v3-v4 script editor also turn out be a good option.
  • PowerShell Forms Designer -An easy Drag and Drop way of creating PowerShell Scripts, saves lots of time and error by doing it the manual way.

Don't expect that You Cannot build a New Version of Microsoft Word or Excel with this Tool :), Complicated Multi-Window applications are possible but very complex, Stick with Simple Forms for collecting and displaying data, also don't forget 

Out-GridView - An easy way to turn output to graphical view.

"Lets See a Practical Example, We Will create a very simple Tool to extract System Properties for a Server.

This tool when run would as the user to input a server name and based on the server name it would display its BIOS,Computer System and Processor Information."

Here a look at the Final Tool and also its .exe file (with a custom icon).

So let me illustrate the steps on how you can build this nice tool

1) Open PowerShell Studio 2012 and Click on New, New Form Project, Feed in the Project Name in my example its "System Information" and click on Create.

You would see a similar screen as below, Double click on "Main Form.pff"

2) Next  we need to add controls to the main form, Click on Object Browser on the left pane and append the appropriate control objects to the form, below i have shown a screen cap of which all controls need to be appended from the object browser.

Once you append the controls to the MainForm, next you need to change certain properties for the control objects.

Here is a list of changes which you would need to make on each control.

  • Label - Change the text property to "Server Name" and "Select System Property".
  • ComboBox - Change the Drop down style to Dropdown list so that users cannot manipulate its values.
  • Button - Change the text property to "Reset Server Name" and "Go!!".
  • MainForm -  Change the text property to "System Information"
Next we will start with the actual coding, Double click on the Form in GUI which would open up the Script view of the form $OnloadFormEvent. Inside it we would initialize the Array of objects and also add the same to the combobox.


#TODO: Initialize Form Controls here

# Create an Array for List of Properties which the user sees

$array = @("Bios_Information","Computer_System_Information","Processor_Information")

# Appending the list of items in $array to combobox

$array | ForEach-Object {Load-ComboBox -ComboBox $combobox1 -Append -Items $_ }


Next we again go back to the designer view and double click on the "Reset Server Name" Button which would take us to its "Click" event.

When a user clicks on this button it would call a clear method on textbox1 which would result in clearing its contents.


 #TODO: Place custom script here


Next we again go back to the designer view and double click on the "Go!!" Button which would take us to its "Click" event.

This is what the script is all about, When a user types in the server name in textbox and selects one of the system property of his interests and clicks this button an Out-Grid view form would pop up which would show a detailed report for the system for that particular system property .

Also note i have illustrated a small sample of how we can use the Try/catch block to trap errors. 

For example if the user types in a wrong system name which is not reachable over network or is shutdown an appropriate warning error message box would pop up.

Also note that with the PowerShell Studio Snippet view has a message box snippet which when dragged into the script drops in a scriptblock for "MessageBox" without the need for any additional coding.

Here's the Script which we need to type in to the "Go" Button Event.


#TODO: Place custom script here

# Work only if Textbox1.text input is Not Null.

if ($textbox1.Text -ne $null)

# Selected index is greater than -1 (0,1,2), Iterate for each selected item  generate bios info and Out-grid view

 if ($combobox1.SelectedIndex -gt -1 -and $combobox1.SelectedItem -eq "Bios_Information")


$servername = $textbox1.Text

 Get-WmiObject -Class win32_bios -ComputerName $servername -ea 'Stop' |

 Out-GridView -Title "$($combobox1.SelectedItem) for $servername"


# Selected index is greater than -1 (0,1,2), Iterate for each selected item  generate bios info and Out-grid view

 elseif ($combobox1.SelectedIndex -gt -1 -and $combobox1.SelectedItem -eq "Computer_System_Information")


$servername = $textbox1.Text

Get-WmiObject -Class Win32_ComputerSystem -ComputerName $servername -ea 'Stop' |

 Out-GridView -Title "$($combobox1.SelectedItem) for $servername"


 <# Selected index is greater than -1 (0,1,2), Iterate for each selected item  generate processor info and Out-grid view, error action stop

 so that we can trap the error in try catch block #>

 elseif ($combobox1.SelectedIndex -gt -1 -and $combobox1.SelectedItem -eq "Processor_Information")


$servername = $textbox1.Text

 Get-WmiObject -Class Win32_Processor -ComputerName $servername -ea 'Stop' |

 Out-GridView -Title "$($combobox1.SelectedItem) for $servername"




 # Pop up a windows message box indicating the type of error.

 catch {
 [void][System.Windows.Forms.MessageBox]::Show(" $($servername) is ShutDown or not Reachable over the Network","Information")

Once you are set with the scripting part, Hit "Ctrl + F4" or the "Run Project Button" on the Home Ribbon to test out the tool

Once you feel that the script and the UI work as per your requirement, Package and convert the tool to an exe using the 'Package Button" located on the Export Ribbon

Here i have illustrated a small demo of how the Final Execution of the Tool Would Look.

Here i enter the server name and from the dropdown box i select BIOS information and Click on Go!!, an Out-Grid window would pop up with the details

Similarly we would test out the same for CPU information by selecting CPUInformation from drop down box

Nice, so you can see our tool works perfectly fine.

Next lets take the last use case where in i enter a systemname which doesnot exists or is not reachable over network, here our try catch block would kick in and throw an error message that the system does not exists or is not reachable over network

Note that you can dig more into the try-catch block and trap each unique error with its unique catch block.

I hope this blog post helps you in paving the stepping stone for you PowerShell Script GUI's.

Friday, June 14, 2013

Perform Multiple Parallel Live Migrations of Virtual Machines Across Hyper-V Host using New Workflow Feature in PowerShell V3

Here's my part 2 of blog on how you can use PowerShell Workflow in PowerShell v3 to perform Multiple Parallel Live Migrations of Virtual Machines Across Hyper-V Host.

This was part 2 of my presentation i took at the PSBUG event

If you missed my part 1 here's the link which shows Parallel Provision of Virtual Machines

Here's a little overview on Live Migration.

  • Live Migrations are widely used in production environment during Patch Tuesday's when Microsoft release several series of updates for their products.
  • It is widely used for Hyper-V Host patching to move around resources across Hosts while ensuring almost zero downtime.
  • Hyper-V live migration moves running virtual machines from one physical server to another with no impact on virtual machine availability to users. By pre-copying the memory of the migrating virtual machine to the destination server, live migration minimizes the transfer time of the virtual machine. 
  • A live migration is deterministic, which means that the administrator, or script, that initiates the live migration determines which computer is used as the destination for the live migration. The guest operating system of the migrating virtual machine is not aware that the migration is happening, so no special configuration for the guest operating system is needed

Live migration of virtual machines is a key Hyper-V feature in Windows Server 2008 R2. 
Hyper-V in Windows Server 2012 introduces the following live migration improvements:
Faster and simultaneous migration. Live migrations are now able to utilize higher network bandwidths (up to 10 Gigabit) to complete migrations faster. You can also perform multiple simultaneous live migrations to enable you to move many virtual machines in a cluster quickly. These changes allow you to implement high levels of mobility and flexibility in private cloud solutions.
Here's the PowerShell Workflow Script which does this awesome stuff.
workflow Move-LiveVM




$vminfo = Get-ClusterGroup -cluster $clustername | Where-Object -filterscript  {$_.grouptype -match "VirtualMachine" -and $_.ownernode -match $SourceHyperVhost} 

Foreach -parallel  ($vm in $vminfo)

Move-ClusterVirtualMachineRole $vm -Node $DestinationHyperVhost -MigrationType live  -Cluster $clustername



Also note that i can specify which kind of Migration should be used to move around VM's, here's a snap for the same from the new ise which auto-completes with intelligence.

Below you can see that i invoked this workflow in my Powershell ISE and it invokes Multiple Live Migrations in parallel.

Move-LiveVM -SourceHyperVhost HyperV1 -DestinationHyperVhost HyperV2 -ClusterName sarcinfracluster

Here's a view of My VM migration in process in FCM.

Hope these set of posts helped you out in your datacenter automation.

Thursday, June 13, 2013

Presenting at PowerShell Bangalore User Group Meeting, June 1st 2013

Had a good time at PSBUG event organised at Microsoft Bangalore, here's a snap from my presentation.

Here are the details of the event

And here's the topic which i presented

Provision Virtual Machines in Parallel using New Workflow Feature in PowerShell V3

PowerShell Workflow is one heavy duty feature which comes bundled with PowerShell v3, From my personal experiences i feel that its best used when you need to sequence you tasks, the best example being to run your tasks in parallel.

Here's a an example of how you can use a powershell workflow to automate VM provisioning using Hyper-V cmdlets and Failover Cluster Cmdlets using differential disks.

To start off i need a csv file which contains the list of VM's which i need to be created along with their specs (VMName,Memory,VMPath,Hyper-V Host Name, Virtual Switch Name).

So here you can see that im creating 9 VM's with above specs.

Also note in PSv3 i don't need to import my modules anymore, powershell does it by itself and all cmdlets are exposed.

workflow Create-VMS
# Import the list of VM's from csv file
$vminfo = Import-Csv -path C:\Virtualmachines.csv
# Using Foreach loop in parallel to start each thread in parallel

Foreach -parallel  ($vm in $vminfo)

$VMName = $vm.VMName
[int64]$Memory = $vm.Memory   
$Vmpath     = $vm.VMpath
$HyperV_Host = $vm.'HyperV_host'    
$VMSwitchName = $vm.VMSwitchName

# Create VHD's based on Differencing disk
New-VHD -Path "$Vmpath\$VMName\$VMName.vhdx" -ParentPath "C:\ClusterStorage\Volume1\win2012-fixed-diff.vhdx" -Differencing

# Create VM based on parameters obtained from csv file
New-VM -Path "$Vmpath\$VMName" -Name $VMName -VHDPath "$Vmpath\$VMName\$VMName.vhdx" -MemoryStartupBytes ([int64]$memory*1024*1024*1024) -ComputerName $HyperV_Host

# Connecting the Virtual Switch to the VM
Connect-VMNetworkAdapter -VMName $VMName -SwitchName $VMSwitchName  -ComputerName $HyperV_Host

# Make the VM highly available by adding it as clustered resource
Add-ClusterVirtualMachineRole -VirtualMachine $VMName

# Power On the VM
Start-VM $VMName -ComputerName $HyperV_Host



Below you can see that i invoked this workflow in my Powershell ISE and it invokes the tasks in parallel.


And here's the end result, VM's showing up in Hyper-V Manager and also made Highly Available.

Hope this post helps you out in your Datacenter Automation.

Hyper-V Manager

Failover Cluster Manager

Wednesday, December 19, 2012

Running SharePoint 2010 PowerShell cmdlets on Windows Server 2012

As per Microsoft we cannot install SP2010 on a Windows Server 2012 Box.

Here's the KB article which states this

When we try and run the prerequisites installer before installing SP2010 it states that it has a compatibility issue and it fails.

But there is a workaround we can follow and get the job done. contains a link to an 'Emulated' ServerManagerCMD.exe which we need to copy over to C:\Windows\System32 for the prerequisites installer to work correctly.

Now once we get the sharepoint server farm / standalone install done on the server and try using the sharepoint management shell to manage our sharepoint environment we get an error which states

"The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered."

This is because Microsoft SharePoint is not supported with version 4.0.30319.17929 of the Microsoft .Net Runtime for PowerShell 3.0

If we need to get the commands working once again, we just need to shift our PowerShell version from 3.0 back to 2.0 and we see that the cmdlets start functioning again.
PS C:\Windows\system32> powershell -v 2

Sunday, December 2, 2012

Convert a Windows Server 2012 Server to iSCSI Target Server And Offer Low-Cost Storage

Today i will share some of my practical experiences with the New Role in Windows Server 2012 which allows us to convert a Windows Server 2012 Box to an iSCSI Target Server And Offer Low-Cost Storage.

Using iSCSI Target in Windows Server 2012, we can create a unified server to add all storage and allow other servers, which can be either physical or virtual to connect to them.

In production environments, storage such as NAS and SAN are most common, but for test and development scenarios, we can also use the local disk on the server to create iSCSI virtual disks, facilitating low-cost lab and test environments.

Windows Server 2012 consists of a PowerShell Module called as IscsiTarget which helps us in implementing this role.

I was just going through the cmdlets available to us with this module and i was happy to see we have a good number of them bundled with this module to automate entire manual tasks.

iSCSI Target Server module is loaded by default in Windows Server 2012. However, the cmdlets cannot be run successfully without the iSCSI Target Server role service installed. 

To install it, run: Add-WindowsFeature FS-iSCSTarget-Server

Now i will show you some basic cmdlets which could be used to convert a Windows Server 2012 Box to an iSCSI Target Server. For test purposes i will create a 1GB virtual disk and map it to iSCSITargetServer and later when other hosts connect to the iSCSITargetServer they would be able to see the 1GB LUN listed in their disk topology, which they ca further use for their requirements.

1) Check Status of iSCSI Service -   We should make sure that the iSCSI service is in running state and we should set up its startup type to automatic, if its not none of our cmdlets would work to configure storage.

PS C:\Windows\system32> start-service msiscsi
PS C:\Windows\system32> Set-Service msiscsi –StartupType “Automatic”

2) Create a New LUN -   I used New-iSCSIVirtualDisk cmdlet to create a new LUN, we need to enter a default path where the LUN would get created and also mention its Size, we would be creating a  fixed disk.

The New-IscsiVirtualDisk cmdlet creates a new iSCSI Virtual Hard Disk (VHD) object with the specified file path and size. After the iSCSI VHD object has been created, the virtual disk can be assigned to an iSCSI target. Once a virtual disk has been assigned to a target, and an initiator connects to that target, the iSCSI initiator can then access the virtual disk after the initiator connects to the target.

PS C:\Windows\system32> New-IscsiVirtualDisk c:\test\2.vhd –size 1GB

If the VHD file path exists, then the server will return an error. 
We can then use Import-IscsiVirtualDisk cmdlet to import existing VHDs.

PS C:\Windows\system32> Import-IscsiVirtualDisk c:\test\3.vhd

Now i can get a list of all imported/newly created iscsi virtual disks using Get-IscsiVirtualDisk cmdlet.

PS C:\Windows\system32> Get-IscsiVirtualDisk

3) Creates a new iSCSI Target object  -   Next i used New-IscsiServerTarget cmdlet to create a new iscsitarget object. 

The New-IscsiServerTarget cmdlet creates a new iSCSI Target object with the specified name. After creating a new iSCSI Target object, the target can be assigned to an iSCSI initiator, and a virtual disk can be associated with the target.

PS C:\Windows\system32> New-IscsiServerTarget PowerShellEnth -InitiatorIds "IQN:

Here we do not need to do some powershell magic to generate the ginormous initiatorid IQN, we can get it simple by running iscsicli from a powershell prompt :).

Now i can also list out all the iscsiserver targets available on my server using 

Get-IscsiServerTarget cmdlet.

The Get-IscsiServerTarget cmdlet obtains iSCSI targets and their associated properties from the local server or specified computer.

4) Assign a virtual disk to an iSCSI target -We can use Add-iscsiVirtualDiskTargetMapping cmdlet to map virtual disk's to an iscsi target. 

The Add-IscsiVirtualDiskTargetMapping cmdlet assigns a virtual disk to an iSCSI target. Once a virtual disk has been assigned to a target, and after the iSCSi initiator connects to that target, the iSCSI initiator can access the virtual disk. All of the virtual disks assigned to the same iSCSI target will be accessible by the connected iSCSI initiator.

PS C:\Windows\system32> Add-IscsiVirtualDiskTargetMapping PowerShellEnth c:\test\3.vhd

5) Configure iSCSI initiator to Logon to target -   Next we need to configure iscsi initiator on the client server to Logon on the created target in the server.

I would have illustrated the steps which we need to perform on client server to access the iSCSI LUN's in a different blog

The steps which need to be followed from this blog start from. 

1) Check Status of iSCSI Service -  ...

Now in order to remove all the configurations which we have made we can easily achieve them with a few cmdlets.

If i pipe output of Get-IscsiServerTarget to Remove-IscsiServerTarget it would remove/delete all iSCSItargets available on a server.

PS C:\Windows\system32> Get-IscsiServerTarget | Remove-IscsiServerTarget

If i pipe output of Get-IscsiVirtualDisk to Remove-IscsiVirtualDisk it would remove all iSCSI Virtual Disk objects. The virtual hard disk (VHD) file is not deleted.

PS C:\Windows\system32> Get-IscsiVirtualDisk | Remove-IscsiVirtualDisk

If i use Remove-IscsiVirtualDiskTargetMapping cmdlet it would removes the assignment between a virtual disk and an iSCSI target.The virtual disk will no longer be accessible by an iSCSI initiator once the assignment is removed.

PS C:\Windows\system32> Remove-IscsiVirtualDiskTargetMapping -TargetName "PowerShellEnth" –Path "c:\test\3.vhd"

"So now i guess you should have understood how easy is with powershell and windows server 2012 to create and assign low cost storage to client servers for test and development environment without using any additional third party vendor software for emulation"

Thursday, November 29, 2012

PowerShell Script to Check if Windows 8 PC is complaint to run Hyper-V V-3

In Windows 8, Microsoft has replaced its previous virtualization solution, Windows Virtual PC, with a more powerful, scalable, and capable solution called Hyper-V.

Hyper-V client is present only in the Windows 8 Pro or Enterprise version.

To Install Hyper-V version 3 role in Windows 8 PC, Your system should meet a set of requirements which comprise of the System Type and some core processor requirements.

Hyper-V requires a 64-bit system with minimum of 4GB RAM and requires a CPU that has the
following features enabled.

  • Second Level Address Translation (SLAT)
  • VirtualizationFirmwareEnabled
  • VMMonitorModeExtensions
  • DataExecutionPrevention

Windows admins like us can easily know whether Windows 8 that we have currently running  is an 64 bit and also installed physical memory (RAM) meets the minimum requirement of 4GB via system properties

But for Checking Second Level Address Translation (SLAT) technology on CPU we would need to use a tool called as coreinfo.

SLAT feature is optional for Windows Server 2012, but necessary for installing Hyper-V on Windows 8 machines. 

It is a feature which  provides better performance by reducing the CPU time and improving the memory usage in virtual environments.

But now we have powershell to our rescue to check SLAT.

Below i have illustrated an example with a very simple function on how we can use CIM cmdlet to extract this information.

Function Test-HyperVRole {

$osinfo = Get-CimInstance win32_operatingsystem

$procinfo = Get-CimInstance Win32_Processor

$info = [ordered]@{

'OSArchitecture' = $osinfo.OSArchitecture

'TotalPhysicalMemory'=[math]::Round((Get-CimInstance win32_computersystem).TotalPhysicalMemory/1gb)

'SecondLevelAddressTranslationExtensions' = $procinfo.SecondLevelAddressTranslationExtensions;

'VirtualizationFirmwareEnabled' = $procinfo.SecondLevelAddressTranslationExtensions;

'VMMonitorModeExtensions' = $procinfo.SecondLevelAddressTranslationExtensions;

'DataExecutionPrevention'= (Get-CimInstance Win32_OperatingSystem).DataExecutionPrevention_available


$obj = New-Object -TypeName psobject -Property $info

Write-Output $obj | fl *