Script Packaged as A Service hangs randomly

Hello, I am trying to package a long-running script of approx 3-4 hours of runtime, If I run the service manually it executes fine, but when I try to trigger using from task scheduler or SQL server agent job or using another windows service, it hangs after running for few minutes or an hour.
I am using the script enclosed under Start-job inside onstart function. Even Smaller script do hang but not always.
Running under Service account having Admin permission.
Full Antivirus exclusions.

Is there any best practice I may be missing while packaging service?

Can you share your packager settings?

A snippet of your script would also be helpful. I’m mostly curious about how you are calling Start-Job in OnStart

Hi Adam, attached sample snippet below and packager setting:


Cap2

Function OnStart() {

Start-Job -Name "DataCollection" -ScriptBlock {


 Function Get-ENVSystems {

 Param(
        [AllowNull()]
        [ValidateSet("INVOKE", "SDK")]
        $State="SDK"
      )


    [string]$domain = ""
    $domain =  ((Get-ADDomain).NetBiosname).tostring()
    $nullempty = "The Identity property on the argument is null or empty"
    $nullnotfound= "Get-ADGroup : Cannot find an object with identity:"
    $Duser = ""
    
    $DataCaptured_date  = ('{0:MM\/dd\/yy hh:mm tt}' -f (get-date)).ToString()
 
 
    #region Miscs
    #Switch option " INVOKE" , "SDK"  ## 
    $State = "SDK"
    $SwitchRedirect = "$State"



	 	    #region Logs path
$defaulthLogPath = "C:\Initialization_LOG_$(get-date -f yyyy-MM-dd).txt"
$deftest = Test-Path "C:\Initialization_LOG_$(get-date -f yyyy-MM-dd).txt"

if($deftest -like 'False')
{

Write-Host "Creating Logfile"

Try {
$ErrorActionPreference = "STOP"
$Global:logpath=New-Item "$defaulthLogPath" -type file -force 
}

Catch
{
    $Dl = get-date -f yyyy-MM-dd:HH:mm
    $err = $_.exception
   "$Dl :: Error On Initialization Log Path `n" | out-file C:\ERRORLOG.LOG -Append

}

}
else
{

    Write-Host "LogFile already Exists"
    $Global:logpath="$defaulthLogPath"
}

#endregion Logs path
    Function Log-out{
        Param(
        [Parameter(ValueFromPipeline)]$name,
        [AllowNull()]
        [ValidateSet("INFO", "ERROR", "SUCCESS", "WARNING")]
        $State="INFO"

      
        )
        
        function Set-logtime{
           $date =Get-date -f dd-MM-yyyy
        #$date.ToString()
            $time=get-date -Format hh-mm-ss
                $timestamping= "LOG $date::$time :`t`t"
                $timestamping
                        }
        $dd= Set-logtime
            $createdNew = $False # Stores Boolean value if the current PowerShell Process gets a lock on the Mutex
            # Create the Mutex Object usin the constructuor -> Mutex Constructor (Boolean, String, Boolean)
            $mutex = New-Object -TypeName System.Threading.Mutex($true, "MutexName1", [ref]$createdNew)
            $mutex.WaitOne() | Out-Null

            Try{
            If($State -like "INFO"){
        Write-Host "$dd EVENT::$State : $name" -ForegroundColor Cyan
        "$dd EVENT::$State : $name" *>>$Global:logpath}
            elseif($State -like "ERROR")
            {
        Write-Host "$dd EVENT::$State : $name" -ForegroundColor Yellow -BackgroundColor Red
        "$dd EVENT::$State : $name" *>>$Global:logpath
            }
            elseif($State -like "SUCCESS")
            {
        Write-Host "$dd EVENT::$State : $name" -ForegroundColor White -BackgroundColor DarkGreen
        "$dd EVENT::$State : $name" *>>$Global:logpath
            }
            elseif($State -like "WARNING")
            {
        Write-Host "$dd EVENT::$State : $name" -ForegroundColor red -BackgroundColor Yellow
        "$dd EVENT::$State : $name" *>>$Global:logpath
            }
            $mutex.ReleaseMutex()
            }
            Catch
            {
            $mutex.ReleaseMutex() | Out-Null
            
            }            
                        
                }


                                            $DDCDATA = ""
                                            $DDCDATA = Get-BrokerMachine -AdminAddress $DDCSERVERS.Pri_DDC -MaxRecordCount 10000000 -SessionSupport SingleSession | Select DesktopGroupName, AssociatedUserNames,HostedMachineName,MachineName,HostingServerName,DeliveryType,RegistrationState,Lastconnectiontime,CatalogName,SessionSupport,SessionStateChangeTime,SessionProtocol,LastConnectionUser,DesktopKind,HypervisorConnectionName,OStype,OSversion,PowerState, IPAddress 
                                            [Array]$CreationDateData = Get-ProvVM -AdminAddress $DDCSERVERS.Pri_DDC -MaxRecordCount 10000000 | Select VMname, Creationdate

                                            $DDCDATA | Export-Csv c:\tld1.csv -NoTypeInformation
                                            


}

Get-ENVSystems -State SDK

}
}


Function OnStop() { 
    Get-Job -Name DataCollection |Remove-Job -Force
}

$canStop = $true

Hi Adam, Any Idea If I am missing anything?

Hey @afaque01,

The script and settings look fine. I am wondering that if you started the script using Start-ThreadJob, it would be successful. This would keep the entire script running within the same process and wouldn’t start a separate PS process with Start-Job.

The module can be found here: PowerShell Gallery | ThreadJob 2.0.0

Hey Adam,

Thank you, I will get it a go.