PS & Winforms in PS Studio looping through DataGridView

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of Nigel Tatschner Nigel Tatschner 2 months, 3 weeks ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #45518
    Profile photo of Nigel Tatschner
    Nigel Tatschner
    Participant

    Hi all,

    I'm creating background jobs to perform a task.
    I get certain values from a DataGridView
    I'm adding the results in to another DGV and removing them from the source DGV.
    I'm controlling the flow to limit the amount of background jobs running at one time.
    everything works as expected but in the source i'm left with some items still in the source DGV after the loop that goes through each item in the source DGV.

    The code for the button that executes the command is below:

    $ScanButton_Click = {
    	
    	$ScanButton.Enabled = $false
    	foreach ($a in $ItemsToScanDGV.Rows)
    	{
    		$AddJobs = $true
    		while ($AddJobs -eq $true)
    		{
    			if ($JobTrackerList.Count -ge ($concurrentjobstb.Text -as [int]))
    			{
    				$AddJobs = $true
    				[System.Windows.Forms.Application]::DoEvents()
    			}
    			else {
    			$ComputerName = (($a.Cells[$ItemsToScanDGV.Columns["HostName"].Index]).Value)
    			$ComputerName = $ComputerName.ToString().Trim()
    			if ($ComputerName -gt "")
    			{
    				$SourceCellIndex = $a.Cells[$ItemsToScanDGV.Columns["HostName"].Index]
    				Add-JobTracker -Name ("$ComputerName" + (Get-Random -Minimum 1000 -Maximum 9999)) -ArgumentList $ComputerName -JobScript {
    					param ($Computer)
    					
    					$ObjectProps = @{
    						"HostName" = "";
    						"IPAddress" = "";
    						"LastRestarted" = "Could Not Query";
    						"RestartedRecently" = "N/A";
    						"RDP" = "N/A";
    						"TryAgain" = "TryAgain"
    					}
    					
    					
    					$NetworkTest = Test-NetConnection -CommonTCPPort RDP -ComputerName $Computer -ErrorAction SilentlyContinue
    					
    					if ($NetworkTest.PingSucceeded)
    					{
    						try
    						{
    							$WMI = Get-WmiObject -Class win32_operatingsystem -ComputerName $Computer -ErrorAction 'Stop'
    							if ($WMI.LastBootUpTime -lt (Get-Date).AddHours(-1)) { $LastHour = "Yes" }
    							Else { $LastHour = "No" }
    							
    							$obj = New-Object System.Management.Automation.PSObject -Property $ObjectProps
    							$obj.HostName = $Computer
    							$obj.IPAddress = $NetworkTest.RemoteAddress
    							$obj.LastRestarted = $WMI.ConvertToDateTime($WMI.LastBootUpTime)
    							$obj.RestartedRecently = $LastHour
    							$obj.RDP = $NetworkTest.TCPTestSucceeded
    							
    							Write-Output $obj
    						}
    						catch
    						{
    							
    							
    							$obj = New-Object System.Management.Automation.PSObject -Property $ObjectProps
    							$obj.HostName = $Computer
    							$obj.IPAddress = $NetworkTest.RemoteAddress
    							
    							Write-Output $obj
    						}
    					}
    					Else
    					{
    						$obj = New-Object System.Management.Automation.PSObject -Property $ObjectProps
    						$obj.HostName = $Computer
    						$obj.IPAddress = $NetworkTest.RemoteAddress
    						
    						Write-Output $obj
    					}
    				} -CompletedScript {
    					param ($job)
    					
    					$hashReturn = Receive-Job -Job $Job
    					ForEach ($Job in $hashReturn)
    					{
    						$OutputDGV.Rows.Add($Job.HostName, $Job.IPAddress, $Job.LastRestarted, $Job.RestartedRecently, $Job.RDP, $Job.TryAgain)
    						foreach ($row in $ItemsToScanDGV.Rows)
    						{
    							if ($row.Cells["HostName"].Value -ne $null)
    							{
    								if ($row.Cells["HostName"].Value.ToString().Equals($Job.HostName))
    								{
    									$ItemsToScanDGV.Rows.Remove($Row)
    									break
    								}
    							}
    						}
    					}
    					If ($JobTrackerList.Count -le 1) { $ScanButton.Enabled = $true }
    				}
    			}
    			$AddJobs = $false
    			[System.Windows.Forms.Application]::DoEvents()
    		}
    	}
    }
    }
    

    Anyone know what i'm going wrong?

    I'm happy to upload the project files somewhere is needed.
    Edit: in fact, here's the link anyway https://www.dropbox.com/s/6o2kxmbsqov86e8/NT%20Monthly%20Patching%20Check.zip?dl=0

    • This topic was modified 2 months, 4 weeks ago by Profile photo of Nigel Tatschner Nigel Tatschner.
    • This topic was modified 2 months, 4 weeks ago by Profile photo of Nigel Tatschner Nigel Tatschner. Reason: Adding project link
    #45682
    Profile photo of Don Jones
    Don Jones
    Keymaster

    I'd probably begin by putting a lot of Write-Verbose statements. Have it tell you what it's pulling from the source grid, what it's trying to delete, and so on. I'd probably also put some debug breakpoints in there – when it tells me it removed something, I'd also let it break so I could manually confirm the contents of the grid at that point.

    I'm not going to be able to run your code, and it's impossible to debug something like this statically. But the first debug step, in any situation, is to get the code to give you some information about what it's doing. Analyze that output to make sure it's what you expected it to be. If it isn't, then you have some evidence of your bug.

    #45747
    Profile photo of Nigel Tatschner
    Nigel Tatschner
    Participant

    I'm not great at debugging none console scripts/applications, I've been using things like [System.Windows.Forms.MessageBox]::Show($Error[0], "ERROR") to give me details replacing the variable with want I want to view.

    When I add the Write-Debug or Write-Verbose to the application i'm assuming the output will appear in the console portion of the PS Studios editor?

    Many Thanks,

    Nigel

    #45776
    Profile photo of Dan Potter
    Dan Potter
    Participant

    No offense but I'd start over with another form. Use one datagrid and update the cells based on the results. Your scannow button should execute for each row selected in the dgv. Use the job tracker function properly.

    Here's a stripped down example of how the jobtracker works. btw, sapien has forums as well.

    foreach ($row in $datagridview1.SelectedRows) {
    				
    				$server = $row.Cells[0].Value
    				
    				if (test-connection $server -count 1 -erroraction "silentlycontinue") {
    
    					$JobScript = {
    						
    						param ($server,
    							$credential)
    						
    						
    						###get a bunch of server info
    						
    						[pscustomobject]@{
    							
    							Server = $server
    							Timestamp = $timestamp
    							KBList = $kblist
    							EventListCount = $eventlist.count
    							ServiceList = $servicelist
    							UPtime = $uptime
    							CSpace = $cconv
    							
    						}
    						
    						
    					}
    
    					
    					$UpdateScript = {
    						Param ($Job)
    						$statusbarpanel1.Text = 'Working...'
    					}
    
    					
    					$CompletedScript = {
    						
    						Param ($Job)
    						$results = Receive-Job -Job $Job
    						
    						$row = $datagridview1.Rows | ? { $_.Cells[0].Value -eq $results.server }
    						
    						$row.Cells[1].Value = $results.timestamp
    						$row.Cells[2].Value = $results.kblist
    						$row.Cells[3].Value = $results.eventlistcount
    						$row.Cells[4].Value = $results.servicelist
    						$row.Cells[5].Value = $results.uptime
    						$row.Cells[6].Value = $results.cspace
    						
    						
    						$statusbarpanel1.Text = $results.server + " Complete."
    						
    
    						
    					}
    					
    					Add-JobTracker -Name $server -JobScript $JobScript -UpdateScript $UpdateScript -CompletedScript $CompletedScript -ArgumentList $server, $credential
    					
    					###ENDJOB####*************************************************************************************
    					
    					
    				} else {
    					
    					$row.Cells[1].Value = 'Offline'
    					$row.Cells[2].Value = 'Offline'
    					$row.Cells[3].Value = 'Offline'
    					$row.Cells[4].Value = 'Offline'
    					$row.Cells[5].Value = 'Offline'
    					$row.Cells[6].Value = 'Offline'
    					
    				}
    				
    			}
    
    #45781
    Profile photo of Dan Potter
    Dan Potter
    Participant

    write-host is the most efficient way of troubleshooting in the studio. Practice manipulating Cells and rows in the dgv, returning info etc. Get in the habit of building or binding datatables so you can use all the methods available.

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

    To see what the form looks like in the example go here.

    https://www.sapien.com/forums/viewtopic.php?f=21&t=10239

    #46082
    Profile photo of Nigel Tatschner
    Nigel Tatschner
    Participant

    Hi Dan, thanks for the reply,

    Liking the look of that, that's what I was hoping this could mature into, just getting to grips with is all now.

    i'll start again with the DGVs and go from there.

    Thank you.

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.