Question concerning "creating responsive forms post"

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
whiggs2
Posts: 38
Joined: Sat Sep 23, 2017 11:59 pm

Question concerning "creating responsive forms post"

Post by whiggs2 »

Hello. I am trying to write a script that uses the "responsive form framework" that was posted at link below:
https://www.sapien.com/blog/2012/05/16/ ... ive-forms/
I am having a bit of time trying to retrieve an array variable which the background job populates while it is running. At first I tried declaring the array prior to the creation and execution of the background job, eg:

Code: Select all

$array = New-object system.collections.arraylist
Try
	{
		Add-JobTracker -Name ReloadList -JobScript {
# Code to process
$array
}`
-completedScript {
param ($job)
#do stuff with $array
}`
-UpdateScript {
			param ($Job)
			$results2 = Receive-Job -Job $Job | Select-Object -Last 1
		}
}
Catch
{
Write-Debug $_
}
I would have thought this method would have worked since the declaration of the array variable took place before the background was created and executed, however, one of the process that the "Completescript" block performs is using the values stored in the array in conjunction with "add-listviewitem" to populate a listview, but whenever I would run the code, it would process successfully up until the point where I called "Add-listviewitem", at which point I would get an error basically indicating that the values I was passing to the function were "null". So I re-wrote the function to (as closely as I could) mimic the progress bar example that you provide in your download section:

Code: Select all

Try
		{
			Add-JobTracker -Name ReloadList -JobScript {
				Get-AzureRmSubscription | % {
					If ($_.Name -like $combobox2.Text) { Set-AzureRmContext -Subscription $_.Id }
				}
				$resourcegr = Get-AzureRmResourceGroup
				$nic1 = Get-AzureRmNetworkInterface
				$currentvms = Get-azurermvm | Select-Object -property Name, ResourceGroupName, OSProfile, @{ name = 'VMSize'; expression = { $_.Hardwareprofile.VMsize } }, ProvisioningState
				$pubip = New-Object System.Collections.ArrayList
				Get-AzureRmPublicIpAddress | % { $pubip.Add($_) }
				foreach ($vm in $currentvms)
				{
					$inip = $null
					foreach ($ip in $pubip)
					{
						If ($ip.ResourceGroupName -like $vm.ResourceGroupName)
						{
							$inip = $ip.IpAddress
						}
					}
					Foreach ($nic in $nic1)
					{
						If ($nic.ResourceGroupName -like $vm.ResourceGroupName)
						{
							$privip = $nic.IpConfigurationstext | ConvertFrom-Json
						}
					}
					
					$os = $null
					If ($vm.osprofile.LinuxConfiguration -eq $null)
					{
						$os = "Windows"
					}
					Else
					{
						$os = "linux"
					}
					$custobj = New-Object -TypeName PSObject
					$custobj | Add-Member -MemberType NoteProperty -Name "VMName" -Value $vm.Name
					$custobj | Add-Member -MemberType NoteProperty -Name "VMResourceGroup" -Value $vm.ResourceGroupName
					$custobj | Add-Member -MemberType NoteProperty -Name "VMOS" -Value $os
					$custobj | Add-Member -MemberType NoteProperty -Name "VMType" -Value $vm.Vmsize
					$custobj | Add-Member -MemberType NoteProperty -Name "VMPublicIP" -Value $inip
					$custobj | Add-Member -MemberType NoteProperty -Name "VMprivateIP" -Value $privip.privateipaddress
					$custobj | Add-Member -MemberType NoteProperty -Name "VMStatus" -Value $vm.ProvisioningState
					$vmarray.Add($custobj)
				}
			$vmarray
			}`
						   -CompletedScript {
				param ($Job)
				$progressbaroverlay1.Visible = $false
				$results = Receive-Job -Job $job | Select-object -last 1
					foreach ($ob in $results)
					{
						Add-ListViewItem -ListView $listview1 -Items $ob.VMName -SubItems $ob.VMResourceGroup, $ob.VMOS, $ob.VMType, $ob.VMPublicIP, $ob.VMprivateIP, $ob.VMStatus
					}
				$listview1.Refresh()
				$combobox1.Enabled = $true
				$textbox1.Enabled = $true
			}`
						   -UpdateScript {
				param ($Job)
				$results2 = Receive-Job -Job $Job | Select-Object -Last 1
			}
		}
		Catch [Exception]
		{
			Write-Debug $_
		}
But still, again and again, no matter what I have tried, the "add-listviewitem" function errors out stating that the values I am passing it are Null values. Any advice on what I am doing wrong?

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

This line is incorrect.

$results = Receive-Job -Job $job | Select-object -last 1

It should be:

$results = Receive-Job -Job $job

Remove the update bits:

Code: Select all

        -UpdateScript { 
        param ($Job)
           # $results2 = Receive-Job -Job $Job | Select-Object -Last 1
       }

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

You cannot access any forms controls or variables in a job script. The following will not work.

Code: Select all

Get-AzureRmSubscription | 
    ForEach-Object {
        If ($_.Name -like $combobox2.Text) { Set-AzureRmContext -Subscription $_.Id }
    }
$combobox2.Text is not available in a job script. Pass these values as arguments in the "-ArgumentList" parameter.

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

Start by running this function at a PS CLI prompt. Open a new copy of PS CLI and paste in the code. This code must be able to run and any changes must be made inside of the function until it returns the objects you need.

I have modified the object generation to work correctly for a job.

When this works then use the body of the function as the jobscript.

Code: Select all

function MyJobScript{
    Param(
        $AzSubscriptionName
    )
    Get-AzureRmSubscription | 
        ForEach-Object {
            If ($_.Name -like $AzSubscriptionName) { Set-AzureRmContext -Subscription $_.Id }
        }

    $resourcegr = Get-AzureRmResourceGroup
    $nic1 = Get-AzureRmNetworkInterface
    $currentvms = Get-azurermvm
    $pubip = New-Object System.Collections.ArrayList
    Get-AzureRmPublicIpAddress | ForEach-Object { $pubip.Add($_) }

    foreach ($vm in $currentvms) {
        $inip = $null
        foreach ($ip in $pubip) {
            If ($ip.ResourceGroupName -like $vm.ResourceGroupName) {
                $inip = $ip.IpAddress
            }
        }
        Foreach ($nic in $nic1) {
            If ($nic.ResourceGroupName -like $vm.ResourceGroupName) {
                $privip = $nic.IpConfigurationstext | ConvertFrom-Json
            }
        }
        
       
        [pscustomobject]@{
            VMName = $vm.Name
            VMResourceGroup = $vm.ResourceGroupName
            VMOS = If ($vm.osprofile.LinuxConfiguration) { 'linux' }else{ 'Windows' }
            VMType = $vm.Hardwareprofile.VMsize
            VMPublicIP = $inip
            VMprivateIP = $privip.privateipaddress
            VMStatus = $vm.ProvisioningState
        }

    }
}
MyJobScript -AzSubscriptionName 'someazurename'

User avatar
whiggs2
Posts: 38
Joined: Sat Sep 23, 2017 11:59 pm

Re: Question concerning "creating responsive forms post"

Post by whiggs2 »

Holy crap it worked. Partially. Assigning a variable to the text of the combobox and passing that as a parameter into the -jobscript does not appear to be properly updating the azure subscription. By default, when the script starts, it sets the current azure subscription to a certain subscription, and no matter what subscription i indicate in the combobox, it only returns the vms from the initial subscription, which tells me the azure subscription is not being updated as it should. I see that there is an -argumentlist parameter which the add-jobtracker function accepts, which is probably what I will need to use to pass the value to the job, but (and I highly recommend Sapien adds this change) there is no example which actually demonstrates the proper way to use -Argumentlist. Would it look like this:
  1. -Argumentlist "-azsubscriptionname $azname"
or would argument list only contain the value that I want to pass to -azsubscriptionname:
  1. -Argumentlist $azname

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

Please do as I suggested and run the code as a function in a new PS command window. RUn and debug it until it does what you need. There are many more issues of running Azure code as a Job. You need to make the function independent of everything so it always works at a new prompt. By "new" I mean a freshly opened copy of PowerShell CLI. Until you can get this working using a job will just frustrate you.

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

Also note that to get a subscription by name you would do this:

Code: Select all

function MyJobScript{
    Param(
        [Parameter(Mandatory)]
        $AzSubscriptionName
    )
    if($azsub = Get-AzureRmSubscription -SubscriptionName $AzSubscriptionName){
        Write-Verbose 'Subscription found'
    }else{
        return
    }
}
MyJobScript -AzSubscriptionName 'Microsoft Partner Network' -Verbose
Run this and fix all issues until it works then add each line of your script until you get it working.

Note that this function must run with no other code outside of the function You are clearly missing some very important pieces which you will immediately see when this is run.

User avatar
whiggs2
Posts: 38
Joined: Sat Sep 23, 2017 11:59 pm

Re: Question concerning "creating responsive forms post"

Post by whiggs2 »

Ok. did as you asked and the entire script worked. I wonder if you had some kind of disconnect and just didn't understand what I was asking, and that is why you have not answered my question and made perform this exercise that has taught me nothing about what I asked. In the example you gave, you have a parameter in the function where the azure subscription can be plugged, and I am able to pass the appropriate value to the parameter when the function is called. So now do as I ASKED and let me know how I can translate the function call (which allows me to specify the azuresubscription) into the -jobscript?

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

Just pass it as one of the arguments.

jvierra
Posts: 14552
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Question concerning "creating responsive forms post"

Post by jvierra »

Example:

Code: Select all

$jobScript = {
    Param(
        [Parameter(Mandatory)]
        $AzSubscriptionName
    )
        
    if($azsub = Get-AzureRmSubscription -SubscriptionName $AzSubscriptionName){
        $azsub | Set-AzureRMContext
        Write-Verbose 'Subscription found'
    }else{
        Write-Warning 'Subscription not found'
        return
    }

    foreach ($vm in Get-AzureRmVm) {
        $vmPublicIp = $vm | Get-AzureRmPublicIPAddress
        [pscustomobject]@{
            VMName = $vm.Name
            VMResourceGroup = $vm.ResourceGroupName
            VMOS = If ($vm.osprofile.LinuxConfiguration) { 'linux' }else{ 'Windows' }
            VMType = $vm.Hardwareprofile.VMsize
            VMPublicIP = $vmPublicIp
            VMprivateIP = $vm.IPAddress
            VMStatus = $vm.ProvisioningState
        }

    }
}
$updateScript = { ... }
$completedScript = { ... }

Add-JobTracker -Name ReloadList -JobScript $jobScript -UpdateScript $UpdateScript -CompletedScript $completedScript -ArgumentList $subscriptionName


Locked