Search code examples
powershelljobs

Powershell start-job in script seemingly does not start a job


So i got the following situation:

i wrote a script that starts jobs (essentialy starts a specific script with parameters) and monitors them according to the current time. When i start the script, everything works fine except that i can't seem to find the jobs.

Full script:

`

#-- Global Variables

Write-Host "Enter Credentials for Network Share"

$cred = Get-Credential
$Source = Read-Host "Enter Source"
$Destination = Read-Host "Enter Destination"
$Sleepduration = Read-Host "Enter Sleepduration of Robocopy"

$runtime_throttled_start = "0600"
$runtime_throttled_end = "1759"

$runtime_unthrottled_start = "1801"
$runtime_unthrottled_end =  "2359"

$runtime_unthrottled_start_nextday = "0001"
$runtime_unthrottled_end_nextday = "0558"

$Date = Get-Date -Format "MM-dd-yyyy"
$Logfile = "$PSScriptRoot\Logs\start-copy\start-copy-$Date.log"

$Script_Root = "C:\temp"

$Status = "0"

#-- Functions

function logging ($Value) { 

    $Script_Output = "$(Get-Date -Format "MM-dd-yyyy HH:mm:ss") - $Value"

    Write-Host $Script_Output
    Write-Output $Script_Output >> $Logfile

}

function main {

    if (! (Test-Path "$PSScriptRoot\Logs\start-copy")) {

        Logging "Creating Logging folder..."
        New-Item -Path "$PSScriptRoot\Logs" -Name "start-copy" -Type "directory"

    }

    $i = 1

    try {

        while ($i -eq 1) {

            $Time = get-date -Format "HHmm"

            if (($Time -ge $runtime_throttled_start) -and ($Time -le $runtime_throttled_end)) {

                if (($Status -eq "not_throttled") -or ($Status -eq 0)) {

                    Logging "Stopping running jobs..."
                    Get-Job | Where-Object {$_.Command -match "sync-job"} | Remove-Job -Force

                    Logging "Starting throttled script..."
                    Start-Job -Name Robocopy_Throttled -Filepath ".\sync-job.ps1" -ArgumentList "$Source", "$Destination", $Script_Root, $Sleepduration, "0", "$runtime_throttled_start-$runtime_throttled_end", "$cred"

                    $nextday = $false

                }

                $Status = "throttled"
                Logging "Status: $Status"

            }

            if ((($Time -ge $runtime_unthrottled_start-1) -and ($Time -le ($runtime_unthrottled_end))) -or (($Time -ge $runtime_unthrottled_start_nextday) -and ($Time -le $runtime_unthrottled_end_nextday))) {

                if (($Status -eq "throttled") -or ($Status -eq 0)) {

                    Logging "Stopping running jobs..."
                    Get-Job | Where-Object {$_.Command -match "sync-job"} | Remove-Job -Force

                    Logging "Starting unthrottled script..."
                    Start-Job -Name Robocopy_Unthrottled -Filepath ".\sync-job.ps1" -ArgumentList "$Source", "$Destination", $Script_Root, $Sleepduration, "3", "$runtime_unthrottled_start-$runtime_unthrottled_end", "$cred"

                    $nextday = $false

                }

                $Status = "not_throttled"
                Logging "Current status: $Status"

            }

            if (($Time -eq "0000") -and ($nextday -eq $false)) {

                $nextday = $true

                Logging "Next day, stopping running jobs once..."
                Get-Job | Where-Object {$_.Command -match "sync-job"} | Remove-Job -Force

                Logging "Starting next-day unthrottled script...."
                Start-Job -Name Robocopy_Unthrottled_nextday -Filepath ".\sync-job.ps1" -ArgumentList "$Source", "$Destination", $Script_Root, $Sleepduration, "3", "$runtime_unthrottled_start_nextday-$runtime_unthrottled_end_nextday", "$cred"

                $Status = "not_throttled_nextday"
                Logging "Current status: $Status"

            }  

            Logging "Waiting 10 Seconds for the next check"
            Start-Sleep 10

            Logging "The following Jobs are currently running:
            Get-Job | Where-Object {$_.Command -match "sync-job"}

        }

    }

    finally {

        Logging "Stopping and removing all jobs..."
        Get-Job | Where-Object {$_.Command -match "sync-job"} | Remove-Job -Force

    }

}

main

Now if i execute get-job while this script is running, there are no jobs present:

(get-job).count 0

Starting a Job from Powershell (not via script) does work:

Start-Job -Name Robocopy_Throttled -Filepath ".\sync-job.ps1" -ArgumentList "$Source", "$Destination", $Script_Root, $Sleepduration, "0", "$runtime_throttled_start-$runtime_throttled_end", "$cred"

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
9      Robocopy_Throt… BackgroundJob   Running       True            localhost            <#…

(get-job).count
1

Also (according to the script logs), the script job is running and is transfering data as it should. that's what is confusing me the most. You guys got any idea?

Also if you guys are interested in the script that actually does the job:

param (

    $Source,
    $Destination,
    $Root,
    $Sleepduration,
    $Mode,
    $Runtime,
    $Cred

)

#-- Global Variables

$Date = Get-Date -Format "MM-dd-yyyy_HH-mm"
$Time = Get-Date -Format "HH:mm"

Write-Host $Logfile

if ($Time -eq "00:00") {

    $Logfile = "$Root\Logs\Log-$Date-unthrottled_nextday.txt"

}

else {

    switch ($Mode) {

        0 {$Logfile = "$Root\Logs\Log-$Date-throttled.txt"}
        3 {$Logfile = "$Root\Logs\Log-$Date-unthrottled.txt"}

    }

}

#-- Functions

function logging ($Value) { 

    $Script_Output = "$(Get-Date -Format "MM-dd-yyyy HH:mm:ss") - $Value"

    Write-Host $Script_Output
    Write-Output $Script_Output >> $Logfile

}

function sync-folder ($Source, $Destination, $Mode) {

    if (!(Get-PSDrive -PSProvider FileSystem).Name -eq "TempMmount") {

        $cred = Get-Credential
        New-PSDrive -Name "TempMount" -PSProvider "FileSystem" -Credential $Cred -Root $Source

    }

    switch ($Mode) {

        0 {robocopy $Source $Destination /e /z /copy:DAT /dcopy:DA /W:5 /xo /im /IPG:8 /log+:$Logfile /RH:$runtime /tee}

        1 {robocopy $Source $Destination /e /z /copy:DAT /dcopy:DA /W:5 /xo /im /IPG:8 /log+:$Logfile /tee}

        2 {robocopy $Source $Destination /e /z /copy:DAT /dcopy:DA /W:5 /xo /im /IPG:8 /log+:$Logfile /tee /L}

        3 {robocopy $Source $Destination /e /z /copy:DAT /dcopy:DA /W:5 /xo /im /log+:$Logfile /RH:$runtime /tee}

        Default {Write-Host "No Mode has been chosen. Exiting script..."; Exit}

    }

    Remove-PSDrive -Name "TempMount"

}

#-- Main Method

function main {

    Write-Host "Source Directory: $Source"
    Write-Host "Destination Directory: $Destination"

    $Current_User = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    Logging "User who's executing this script: $Current_User"

    #-- Create Log Directory if it does not exist yet

    if (! (Test-Path "$Root\Logs")) {

        Logging "Creating Log Directory`n"
        
        New-Item -Path $Root -Name "Logs" -Type "Directory"

    }

    else {

        Logging "Log Directory already exists. Proceeding.. `n"

    }

    $Modes = 
    "(0) - Normal run (requires runtime)`n",
    "(1) - run only once`n",
    "(2) - Dry run once`n",
    "(3) - run without bandwidth limit (requires runtime)"

    Write-Host "`nYou got the following exectuion modes:`n`n $Modes`n"
    Write-Host "You have chosen the following Mode: $Mode"

    #-- Endless loop for repetetive sync
    #-- Sleepduration is set by the Sleepduration variable

    $i = 1

    while ($i -eq 1) {

        Write-Host "===============================================================================`n"
        Write-Output "===============================================================================`n" >> $Logfile

        try {

            Logging "Starting Sync between $Source and $Destination `n"
            sync-folder $Source $Destination $Mode

            switch ($Mode) {

                0 {Logging "Sync complete. Waiting $Sleepduration Seconds for the next Sync`n"; Start-Sleep $Sleepduration}
                1 {Logging "Mode = run once, sync complete. Stoping script...`n"; Write-Host "`n===============================================================================`n"; Write-Output "`n===============================================================================`n" >> $Logfile; Exit}
                2 {Logging "Mode = Dry run once, test complete. Stopping script..."; Write-Host "`n===============================================================================`n"; Write-Output "`n===============================================================================`n" >> $Logfile; Exit}
                3 {Logging "Mode = no throttle, sync complete. Waiting $Sleepduration Seconds for the next Sync`n"; Start-Sleep $Sleepduration}

            }

        }

        catch {

            Logging "There was a Problem with the sync. Following Error message may be helpful:`n"
            Logging "$_`n"

            Write-Host "`n===============================================================================`n"
            Write-Output "`n===============================================================================`n" >> $Logfile

        }

    }

}

main

This is done in Powershell 7


Solution

  • Open two PS windows at the same time and try this to demonstrate why:

    enter image description here

    You wont see a job running for your script from another PS session/thread.