none
Powershell Async script question RRS feed

  • Question

  • Hi! How to make this script Async? if more than 100 adreses, so slow.

       Think about Async realisation.

    # The following line read a plain list of IPs from files.  For this demo, I have
    
    # this line commented out and added a line to just define an array of IPs here
    $scriptRoot = Split-Path -Path $MyInvocation.MyCommand.Path
     
    
    $listofIPs = Get-Content $scriptRoot\ip.txt
    
     
    
    #$listofIPs = "173.136.234.58","173.136.234.59","173.136.234.60"
    
     
    
    #Lets create a blank array for the resolved names
    
    $ResultList = @()
    
     
    
    # Lets resolve each of these addresses
    
    foreach ($ip in $listofIPs)
    
    {
    
         $result = $null
    
        
    
         $currentEAP = $ErrorActionPreference
    
         $ErrorActionPreference = "silentlycontinue"
    
        
    
         #Use the DNS Static .Net class for the reverse lookup
    
         # details on this method found here: http://msdn.microsoft.com/en-us/library/ms143997.aspx
    
         $result = [System.Net.Dns]::gethostentry($ip)
    
        
    
         $ErrorActionPreference = $currentEAP
    
        
    
         If ($Result)
    
         {
    
              $Resultlist += "$ip" + " | " + [string]$Result.HostName
    
         }
    
         Else
    
         {
    
              $Resultlist += "$IP - No HostNameFound"
    
         }
    		
    		"$ip" + " | " + [string]$Result.HostName
     
    }
    
    
     
    
    # If we wanted to output the results to a text file we could do this, for this
    
    # demo I have this line commented and another line here to echo the results to the screen
    
     
    
    $resultlist | Out-File $scriptRoot\output.txt
    
     
    
    #$ResultList
    
     

    Sunday, November 12, 2017 2:28 PM

All replies

  • Use a workflow.

    help about_workflow


    \_(ツ)_/

    Sunday, November 12, 2017 2:40 PM
    Moderator
  • Alternatively, you can use PowerShell RunSpaces. There is a good article available on Scripting Guy blog.

    Beginning Use of PowerShell Runspaces

    I would begin with 5 runspaces. Depending on how CPU intensive you task is, you can create multiple runspaces and adjust it accordingly.


    Happy Scripting :)

    • Proposed as answer by Naw Sunday, November 12, 2017 4:05 PM
    Sunday, November 12, 2017 3:28 PM
  • Workflow is runspaces.  If you are using PS2 then you have to use runspaces.  PS3 and later use Workflow.  It is easier and safer,

    No one should be using PS2.


    \_(ツ)_/

    Sunday, November 12, 2017 4:22 PM
    Moderator
  • What about this: Synchronous

    # The following line read a plain list of IPs from files.  For this demo, I have
    
    # this line commented out and added a line to just define an array of IPs here
    $scriptRoot = Split-Path -Path $MyInvocation.MyCommand.Path
    $listofIPs = Get-Content "$scriptRoot\ip.txt"
    
    #$listofIPs = "173.136.234.58","173.136.234.59","173.136.234.60"
    
    #Lets create a blank array for the resolved names
    $ResultList = @()
    # Lets resolve each of these addresses
    foreach ($ip in $listofIPs){
         $result = $null
         $currentEAP = $ErrorActionPreference
         $ErrorActionPreference = "silentlycontinue"
    
         #Use the DNS Static .Net class for the reverse lookup
         # details on this method found here: http://msdn.microsoft.com/en-us/library/ms143997.aspx
         $result = [System.Net.Dns]::gethostentry($ip)
    
         If($Result){
            $CurrentObject += new-object psobject -Property @{"IP"=$ip;"Result"=$Result.HostName.ToString()}
         }
         else{
            $CurrentObject += new-object psobject -Property @{"IP"=$ip;"Result"="No HostNameFound"}
         }
         $Resultlist+=$CurrentObject
         Write-Host $CurrentObject
    }
    
    # If we wanted to output the results to a text file we could do this, for this
    # demo I have this line commented and another line here to echo the results to the screen
    $resultlist | Out-File $scriptRoot\output.txt
    write-output $ResultList



    • Edited by j0rt3g4 Monday, November 13, 2017 2:45 AM
    Monday, November 13, 2017 2:36 AM
  • And This: Asynchronous

    # The following line read a plain list of IPs from files.  For this demo, I have
    
    # this line commented out and added a line to just define an array of IPs here
    $scriptRoot = Split-Path -Path $MyInvocation.MyCommand.Path
    $listofIPs = Get-Content "$scriptRoot\ip.txt"
    
    #remove all previous job without confirmation
    get-job|Remove-Job -Confirm:$false
    
    #define 1 script with a new parameter called IP that returns the object that you want (custom btw).
    
    $script={
        [CmdletBinding()]
        param(
            [Parameter(Position=0,Mandatory=$true)]$Ip
        )
        BEGIN{
            $outputObject=$null
        }
        PROCESS{
            $result = [System.Net.Dns]::gethostentry($ip)
            $outputObject = new-object psobject -Property @{"IP"=$Ip;"Result"=$Result.HostName.ToString()}
        }
        END{
            return $outputObject
        }
    }
    
    $Alljobs = @()
    # Lets resolve each of these addresses
    foreach ($ip in $listofIPs){
        $Alljobs+= Start-Job -ScriptBlock $script -Name $ip -ArgumentList $ip
    }
    
    $Alljobs | Wait-Job
    $ResultList = $Alljobs | Receive-Job 
    $resultlist | Out-File $scriptRoot\output.txt
    write-output $ResultList | Format-Table ip,Result

    • Proposed as answer by Naw Monday, November 13, 2017 11:33 AM
    Monday, November 13, 2017 2:49 AM
  • If you have 100 addresses you will be starting 100 copies of PowerShell.  Use a workflow.  It is much faster and it can be batched. You can determine how many threads will concurrently. The default is 30I think.

    Or you can partition your list into groups of 10 and run 10 in each job. Workflows are easier and automatically return the results as they become available.


    \_(ツ)_/

    Monday, November 13, 2017 3:13 AM
    Moderator
  • That would be 100 background jobs but hey, it's just a IP -> Name change, it's not big deal.

    Monday, November 13, 2017 4:19 AM