Search code examples
powershelljobs

Working with jobs in Powershell


 $contacts1 = Import-Csv "C:\temp\gal\gal1.csv"
       Start-Job -Name Loop1 -ScriptBlock {
           param([string[]]$contacts1)
            foreach ($c1 in $contacts1){
               $name = $c1.displayname
               New-Item -Path "C:\Temp\GAL" -Name "$name"  -ItemType "file"
           }
       } -ArgumentList (,$contacts1)
       Wait-Job -Name Loop1 | Receive-Job
       Get-Job -Name Loop1 | Remove-Job

The above is creating one file with the name created from inside the CSV but then the next three loops just try and create that same name. But if I comment out all the stuff to do with jobs, as below, the loop itself creates the four files with correct names successfully.

$contacts1 = Import-Csv "C:\temp\gal\gal1.csv"
#Start-Job -Name Loop1 -ScriptBlock {
    #param([string[]]$contacts1)
     foreach ($c1 in $contacts1){
        $name = $c1.displayname
        New-Item -Path "C:\Temp\GAL" -Name "$name"  -ItemType "file"
    }
#} -ArgumentList (,$contacts1)
#Wait-Job -Name Loop1 | Receive-Job
#Get-Job -Name Loop1 | Remove-Job

Solution

  • In the first one you work with strings (you pass a string array to the job). Strings does not have a displayname property. The first block will probably raise an error with strict mode (Set-StrictMode -Version "latest"). You will have to pass an array of objects (that have a displayname property) for this to work.

    In the second you work with the objects produced by Import-CSV. The return value of Import-Csv depends on the content of the file. The file probably contains a "#TYPE" line and a header line if you used Export-Csv. One of your headers is probably "displayname".

    Example:

    PS C:\> Get-ChildItem -Filter "windows" | Select-Object "FullName","Name" | Export-Csv -Path "c:\myfolder\test.csv"
    
    PS C:\> Get-Content ".\myfolder\test.csv"
    #TYPE Selected.System.IO.DirectoryInfo
    "FullName","Name"
    "C:\Windows","Windows"
    
    PS C:\> Import-Csv -Path "C:\myfolder\test.csv"
    
    FullName   Name   
    --------   ----   
    C:\Windows Windows
    
    PS C:\> (Import-Csv -Path "C:\myfolder\test.csv").fullname
    C:\Windows
    

    Edit:

    This might depend on the content of the csv (which isn't provided). But your example with jobs will probably work if you just change the parameter type. Like this:

     $contacts1 = Import-Csv "C:\temp\gal\gal1.csv"
           Start-Job -Name Loop1 -ScriptBlock {
               param([pscustomobject[]]$contacts1)
                foreach ($c1 in $contacts1){
                   $name = $c1.displayname
                   New-Item -Path "C:\Temp\GAL" -Name "$name"  -ItemType "file"
               }
           } -ArgumentList (,$contacts1)
           Wait-Job -Name Loop1 | Receive-Job
           Get-Job -Name Loop1 | Remove-Job