Parallel Work flow or Jobs

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
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
sekou2331
Posts: 262
Joined: Wed Aug 15, 2012 6:07 am

Parallel Work flow or Jobs

Post by sekou2331 » Wed Feb 14, 2018 5:58 am

I have been working on a multicast script for a while now. I finally got it running but found that after setting it to 20 second receive time it can take up to 20 min depending on how many connections I am trying to access. So I wanted to try running in parallel to see if I can cut the time in half. I was trying to use Work flow but it looks like it just runs through and skips the 20 second wait time I am using. Is it better to use Jobs? Also if it is how would I use it with my code below. Lastly it could also be I am using Work Flow incorrectly.

Code: Select all

function Multicast-Listen([int]$Port, [string]$IPMCastAddress, [string]$IPLocalAddress, [string]$INI_file, [string]$ConnectorName) {
	
	#First create the multicast socket.
	$mCastSocket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.AddressFamily]::InterNetwork, [System.Net.Sockets.SocketType]::Dgram, [System.Net.Sockets.ProtocolType]::Udp)
	
	#Now create the local endpoint using the address and port passed in.
	$locEndPoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Parse($IPLocalAddress), $Port)
	
	#Create the remote endpoint (any)
	$remEndPoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Parse([Net.IPAddress]::Any), 0)
	#I'm not sure why, but if you don't cast this to an EndPoint object, it won't work
	$remEndPoint = [System.Net.EndPoint]$remEndPoint
	
	#Define our MulticastOption object (mcast address etc.)
	
	$mCastOption = New-Object System.Net.Sockets.MulticastOption([System.Net.IPAddress]::Parse($IPMCastAddress), [System.Net.IPAddress]::Parse($IPLocalAddress))
	$mCastSocket.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::Socket, [System.Net.Sockets.SocketOptionName]::ReuseAddress, $true)
	$mCastSocket.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::IP, [System.Net.Sockets.SocketOptionName]::AddMembership, $mCastOption)
	
	#Bind the socket to the endpoint.
	$mCastSocket.Bind($locEndPoint)
	$mCastSocket.ReceiveTimeout = 20000
	
	#We need an array of bytes.
	[byte[]]$bytes = 0 .. 255 | %{ 0 }
	
	$enc = New-Object System.Text.ASCIIEncoding
	$receivedBytes = $mCastSocket.ReceiveFrom($bytes, [ref]$remEndPoint)
	$str = $enc.GetString($bytes, 0, $receivedBytes)
	
	$mCastSocket.ReceiveTimeout
	# add output to an array 
	$mdump_Object = New-Object System.Object
	$mdump_Object | Add-Member -type NoteProperty -name ComputerName -Value $env:computername
	$mdump_Object | Add-Member -type NoteProperty -name Soruce -Value $IPMCastAddress
	$mdump_Object | Add-Member -type NoteProperty -name Port -Value $port
	$mdump_Object | Add-Member -type NoteProperty -name Interface -Value $IPLocalAddress
	$mdump_Object | Add-Member -type NoteProperty -name Multicast -Value $remEndPoint.ToString()
	$mdump_Object | Add-Member -type NoteProperty -name INI_file -Value $INI_file
	$mdump_Object | Add-Member -type NoteProperty -name ConnectorName -Value $ConnectorName
	
	#Write to log file.
	Write-Log -Message "Waiting for a connection on $IPMCastAddress $port $IPLocalAddress"
	
	
	
	if ($mdump_Object.Multicast -eq '0.0.0.0:0') {
		$mdump_Object | Add-Member -type NoteProperty -name Status -Value "Failed"
		
		Write-Log -Message "Didnt Received multicast from $($remEndPoint.ToString()) $($str)" -Level Error
	}
	else {
		Write-Log -Message "Received multicast from $($remEndPoint.ToString()) $($str)"
		Write-Log -Message "Connection closed."
		
		$mdump_Object | Add-Member -type NoteProperty -name Status -Value "Passed"
	}
	
	
	return $mdump_Object
	
}



$multiCastLines = Get-SMDiniContent

workflow MultiCast-Workflow {
	parallel {
		ForEach -Parallel ($multiCastLine in $multiCastLines) {
			# The commands run in parallel on each connection.   
			$multicast_run = Multicast-Listen -IPMCastAddress $multiCastLine.Soruce -Port $multiCastLine.Port -IPLocalAddress $multiCastLine.interface -INI_file $multiCastLine.INI_file -ConnectorName $multiCastLine.ConnectorName
			
			$WORKFLOW:test += $multicast_run
			#$all_Data_Failed_Passed += $multicast_run
			
		}
		[array]$all_Data_Failed_Passed = @($test)
	}
}

$all_Data_Failed_Passed | Export-Csv "C:\$($env:computername).csv" -notype


MultiCast-Workflow

User avatar
jvierra
Posts: 12895
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Parallel Work flow or Jobs

Post by jvierra » Wed Feb 14, 2018 5:20 pm

Multicast listening is designed to be used using an async callback. This allows us to not have to wait for n input but to receive one when it arrives. Doing this in PowerShell will be a programming challenge. That is what programming is all about.

Try finding full C# examples of setting up multiple listeners. Consider writing this in a compiled language.

Also note that your workflow is wrong. You need to build and test this at a command prompt before trying to use it in a form.

A workflow can be run as a job. See help.

User avatar
sekou2331
Posts: 262
Joined: Wed Aug 15, 2012 6:07 am

Re: Parallel Work flow or Jobs

Post by sekou2331 » Thu Feb 15, 2018 10:25 am

Ok thanks for your help. Also I am not using this in a form. Can you give me an example of how I can make this work with workflow and or jobs?

User avatar
jvierra
Posts: 12895
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Parallel Work flow or Jobs

Post by jvierra » Thu Feb 15, 2018 10:44 am

If you search and use help you will find many examples of jobs and workflows.

help about_workflows
help about_jobs

User avatar
sekou2331
Posts: 262
Joined: Wed Aug 15, 2012 6:07 am

Re: Parallel Work flow or Jobs

Post by sekou2331 » Thu Feb 15, 2018 5:14 pm

Ok thanks

Locked