Sorting results of a ForEach -parallel workflow statement

Is it possible to sort the output of a workflow that has a Foreach -parallel statement? I’ve got a script that collects trusted domain names and sends them to another script via a workflow for processing. The second script gathers the domain name, IP Address of the DC’s, whether the LDAP port is open on the DC and the date (among other things). When processing is completed by the second script, the output is sent to a .csv file. The script works, but I’d like to list the domain names alphabetically in the .csv file. I’ve tried sending the output to an array and sorting the array, but I must be missing something.

By the way, the ForEach -parallel statement is a requirement.

Here’s the script that runs first:

##########C:\trustsearch.ps1############
$filename = get-date -UFormat %b%d%Y
Function IsolatedNameQuery{
$startDTM = (get-date)
$objUser = New-Object System.Security.Principal.NTAccount(“junk”)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$endDTM = (get-date)
$totaltime = (($endDTM-$startDTM).TotalSeconds)
$script:ftotaltime = “{0:N2}” -f $totaltime
$csvheader = “Isolated Name Query Time (sec.),Domain,Run Number,IP Address,LDAP Query Elapsed Time”
out-file -InputObject $csvheader -FilePath “c:$filename.csv” -Encoding ascii -NoClobber
add-content “$ftotaltime” -path “c:$filename.csv”
}

IsolatedNameQuery

#search all trusted domain objects

Import-module activedirectory
$ADDomainTrust = Get-ADObject -Filter {ObjectClass -eq “trustedDomain”} -Properties *

#workflow

workflow Get-domains
{

param( $trusteddomainlist)
foreach -parallel ($trusteddomain in $trusteddomainlist)
{
$trust = $trusteddomain.name
InlineScript {C:\trustsearch.ps1 $using:trust}
}
}

Get-domains $ADDomainTrust

Here’s the script that does the processing and outputs the .csv file (script #2):

#Collect information on the trusted domains
$filename = get-date -UFormat %b%d%Y
$port = “389”
$trust=$args[0]
$domainarray = @()

foreach($domain in $trust){
$dn = $domain.replace(".", “”)
$domainname = $domain.cn

    #Find IP addressess for all domain controllers for each trusted domain
    Foreach($Address in $domain){
    $ipconfig = [System.Net.Dns]::GetHostAddresses($domain)

        #Telnet to port 389 (LDAP port) to see if it is open on each of the IP addresses.
        Foreach ($ip in $ipconfig){

        $t = New-Object Net.Sockets.TcpClient
            # Use Try\Catch to remove exception info from console if we can't connect
            try
            {
                $t.Connect($ip,$port)
            } catch {}

            #Search external schema
            if($t.Connected)
            {

              $startDTM = (Get-Date)
              $result = (Measure-Command -Expression {Get-ADObject -Filter * -SearchBase (Get-ADRootDSE -Server $ip).SchemaNamingContext -SearchScope Subtree -Server $ip}).TotalSeconds
              $fresult = "{0:N2}" -f $result
              $domainfacts = new-object PSObject -property @{"domain" = $domain; "RunNumber" = $startDTM; "IPAddress" = $ip; "LDAPQueryTime" = $fresult}
              $domainarray += $domainfacts

          
            }
            else
            {

             $domainarray = new-object PSObject -property @{"domain" = $domain; "RunNumber" = $startDTM; "IPAddress" = $ip; "LDAPQueryTime" = 'Server or port not available'}
            }

}

$domainarray | Select domain,RunNumber,IPAddress,LDAPQueryTime | Sort-Object domain -Descending | Format-Table -HideTableHeaders

out-file -InputObject $domainarray -FilePath “c:$filename.csv” -Encoding ascii -Append -NoClobber

Any assistance or ideas would be greatly appreciated.

This:

$domainarray | Select domain,RunNumber,IPAddress,LDAPQueryTime | Sort-Object domain -Descending | Format-Table -HideTableHeaders
out-file -InputObject $domainarray -FilePath "c:\$filename.csv" -Encoding ascii -Append -NoClobber

I don’t fully understand. It absolutely isn’t producing a CSV file, though, it’s producing a formatted table. Also, if I understand your code correctly, $domainarray actually only contains one object at a time, so there’d be nothing to sort. You’re relying on -Append to send each individual object to the text file - which, again, is not a CSV file, because you used Format-Table.

Also note that the commands I pasted above are two separate commands. The first one is essentially accomplishing nothing - it ends with Format-Table, which you’ll never see because this runs as a workflow. The second command, beginning with Out-File, takes the original $domainarray (which has never been altered) and outs it to a file, which implicitly calls Format-Table a second time.

If you did this:

$domainarray | Select domain,RunNumber,IPAddress,LDAPQueryTime | Export-CSV whatever.csv -Append

I’d understand that. At the end, I’d re-read and sort the entire CSV.

Import-CSV whatever.csv | Sort Domain -Desc | Export-CSV whatever2.csv

But right now you’re definitely not producing a CSV file, regardless of the filename extension.