¿Trabajo en segundo plano para actualizar datos en un formulario mientras se ejecuta el script?

¡Espero que algún valiente me ayude!

Estoy trabajando desde hace unos días en una herramienta Powershell que muestra un tablero en la esquina de la pantalla para dar algunos diagnósticos de la computadora en "tiempo real" de la red. Este panel se puede minimizar en el área de notificación.

Primero, creé una función que obtiene los diagnósticos y muestra el estado en el formulario. Traté de actualizar los datos con un temporizador (Ver:Datos en tiempo real con Powershell GUI)

El problema fue que mi función tardó demasiado tiempo en ejecutarse y congeló la interfaz. Así que los botones en el formulario ya no se podían usar ... (Ver:El evento del mouse no funciona después del primer temporizador. )

Ahora, trato de usar trabajos en segundo plano. Mi idea es iniciar un trabajo en modo de bucle y obtener su estado en un intervalo de temporizador.

Primero, el trabajo no podía llamar a una función declarada en mi script principal (línea 361). Sé que puedo usar global y / o no usar una función, pero escribir el código directamente en el ScriptBlock, pero ... incluso con esto, no sé cómo dejar que el trabajo se convierta en un bucle y obtener su estado por intervalo (línea 368) ...

Puedes ver que no estoy realmente experimentando en PowerShell y GUI ... Ha pasado un tiempo desde que me desarrollé y fue en otro idioma ...

Gracias de antemano por su amable ayuda

Si quieres ejecutarlo, he subido la carpeta de imágenes aquí:https://omerta.is/2A1L

Aquí está mi código a continuación

 ####################################### FUNCTIONS   ########################################

#Get diagnostics status
function GetStatus
{

    #Create a return table
    [hashtable]$Return = @{}

    ###Test LAN adapter###
    $EthernetAdapter = (Get-WMIObject Win32_NetworkAdapter | Select Name, NetConnectionStatus | Where Name -like "*Gigabit*")

    If ($EthernetAdapter -ne $null)
    {
        If ($EthernetAdapter.NetConnectionStatus -eq 2)
            {$Return.LANOnStatus = $True}
        else
            {$Return.LANOnStatus = $False}
    }
    else
    {
        $Return.LANOnStatus = $False
    }



    ###Test Wi-Fi adapter###
    $WiFiAdapter = (Get-WMIObject Win32_NetworkAdapter | Select Name, NetConnectionStatus | Where Name -like "*Wireless*")

    If ($WiFiAdapter -ne $null)
    {
        If ($WiFiAdapter.NetConnectionStatus -eq 2)
            {$Return.WiFiOnStatus = $True}
        else
            {$Return.WiFiOnStatus = $False}
    }
    else
    {
        $Return.WiFiOnStatus = $False
    }



    ###Test Network (Default Gateway Reachable)###
    $DefaultGateway = (Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | Sort-Object metric1 | select nexthop, metric1, interfaceindex).nexthop

    If ($DefaultGateway -ne $null)
    {
        If (Test-Connection -ComputerName $DefaultGateway -Count 1 -TTL 4 -Quiet)
            {$Return.NetworkStatus = $True}
        else
            {$Return.NetworkStatus = $False}
    }   
    else 
    {
        $Return.NetworkStatus = $False
    }          


    #Test Internet connection
    $GoogleWebSite = "www.google.com"

    Try
        {$Return.GoogleStatus = Test-Connection -ComputerName $GoogleWebSite -Count 1 -TTL 64 -Quiet}
    Catch
        {$Return.GoogleStatus = $False}


    ###DontReplyToo###
    $DontReplyTooWebSite = "mdm.pictet.com"

    Try
        {$Return.DontReplyTooStatus = Test-Connection -ComputerName $DontReplyTooWebSite -Count 1 -TTL 64 -Quiet}
    Catch
        {$Return.DontReplyTooStatus = $False}


    ###DONT REPLY###
    $DontReplyWebsite = "www.idontreply.com"

    Try
        {$Return.DontReplyStatus = Test-Connection -ComputerName $DontReplyWebsite -Count 1 -TTL 64 -Quiet}
    Catch
        {$Return.DontReplyStatus = $False}       


    #Return the table
    Return $Return

}


########################################### EVENTS ###########################################


#Manual Synchronization
function ManualSync
{
    Sync-Content

}


#Open Browser from dashboard
function Open-Browser
{
    &($BrowserExe)      
}


#Open a help message on click on help icon
function Open-Help($HelpText)
{

    [System.Windows.Forms.MessageBox]::Show($HelpText,"Hotlines",0,32)
}


#Close Dashboard form on click on minimize icon
function Minimize-Dashboard
{

    #Close Dashboard on click minimize
    $Form.WindowState = "Minimize"
    $Form.Visible = $False
    $objNotifyIcon.Visible = $True 

    #!!!!! TO CHECK !!!!!
    Wait-Event -Timeout 15 -SourceIdentifier NotifyIcon_Event
    Remove-Event -SourceIdentifier NotifyIcon_Event

}


#Open Dashboard form on double click on agent icon in notification area
function OpenDashboard
{

    #Open Dashboard on double-click
    $Form.Visible = $True
    $Form.WindowState = "Normal"

}

######################################### ASSEMBLIES #########################################


[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")    
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")  
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Timers")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()


######################################### VAR & CONST ########################################

#Screen placement
$Screen = [system.windows.forms.screen]::PrimaryScreen
$FormPos = $Screen.Bounds.Width - 160

#Dashboard Timer
$Timer = New-Object 'System.Windows.Forms.Timer'
$Timer.Interval = 3000

#Home directory of the program
$HomeDir = Split-Path $script:MyInvocation.MyCommand.Path

#Dashboard Images
$Background = [system.drawing.image]::FromFile("$HomeDir\img\interface.png")
$GreenLight = [system.drawing.image]::FromFile("$HomeDir\img\greenlight.png")
$RedLight = [system.drawing.image]::FromFile("$HomeDir\img\redlight.png")
$SyncImg = [system.drawing.image]::FromFile("$HomeDir\img\sync.png")
$BrowserImg = [system.drawing.image]::FromFile("$HomeDir\img\browser.png")
$HelpImg = [system.drawing.image]::FromFile("$HomeDir\img\help.png")
$MinimizeImg = [system.drawing.image]::FromFile("$HomeDir\img\minimize.png")

#Agent Images
$IconStd = New-Object system.drawing.icon ("$HomeDir\img\icon.ico")
$IconFocus = New-Object system.drawing.icon ("$HomeDir\img\icon_focus.ico")

#Log files
$LogLastSync = ("$HomeDir\Logs\LastSync.log")
$LogSyncAgent = ("$HomeDir\Logs\SyncAgentError.log")

#Browser Module
$BrowserExe = "$HomeDir\bin\Browser.exe"

#Free File Sync Module
$SyncAgentExe = "$HomeDir\bin\SyncAgent.exe"
$SyncJob = "$HomeDir\bin\SyncSettings.xml"

#Strings
$HelpText = "Hotline: 432423432423423"


########################################### FORMS ###########################################


#Dashboard Windows Forms
$Form = New-Object System.Windows.Forms.Form
$Font = New-Object System.Drawing.Font("Arial Unicode MS",10,[System.Drawing.FontStyle]::Bold)
$Lb_LANOn = New-Object System.Windows.Forms.Label
$Lb_WiFiOn = New-Object System.Windows.Forms.Label
$Lb_Network = New-Object System.Windows.Forms.Label
$Lb_Google = New-Object System.Windows.Forms.Label
$Lb_DontReplyToo = New-Object System.Windows.Forms.Label
$Lb_DontReply = New-Object System.Windows.Forms.Label
$Pb_LANOn = New-Object System.Windows.Forms.PictureBox
$Pb_WiFiOn = New-Object System.Windows.Forms.PictureBox
$Pb_Network = New-Object System.Windows.Forms.PictureBox
$Pb_Google = New-Object System.Windows.Forms.PictureBox
$Pb_DontReplyToo = New-Object System.Windows.Forms.PictureBox
$Pb_DontReply = New-Object System.Windows.Forms.PictureBox
$Pb_Sync = New-Object System.Windows.Forms.PictureBox
$Pb_Browser = New-Object System.Windows.Forms.PictureBox
$Pb_Help = New-Object System.Windows.Forms.PictureBox
$Pb_Minimize = New-Object System.Windows.Forms.PictureBox

#Agent Windows Form
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Add_Click({OpenDashboard})
Register-ObjectEvent $objNotifyIcon Click NotifyIcon_Event


#Dashboard Interface Generation
$Form.Size = '150, 220'
$Form.FormBorderStyle = 'None'
$Form.Name = "Form"
$Form.StartPosition = 'Manual'
$Form.Location = $FormPos.ToString()+', 10'
$Form.Text = "Dashboard"
$Form.Font = $Font
$Form.BackgroundImage = $Background
$Form.BackgroundImageLayout = "None"
$Form.TransparencyKey = "White"
$Form.BackColor = "White"
#$Form.Opacity = '.85'

$Form.Controls.Add($Lb_LANOn)
$Lb_LANOn.Location = '10, 30'
$Lb_LANOn.Size = '75, 20'
$Lb_LANOn.Text = "LAN On"
$Lb_LANOn.ForeColor = 'Gray'
$Lb_LANOn.BackColor = "Transparent"

$Form.Controls.Add($Lb_WiFiOn)
$Lb_WiFiOn.Location = '10, 55'
$Lb_WiFiOn.Size = '75, 20'
$Lb_WiFiOn.Text = "Wi-Fi On"
$Lb_WiFiOn.ForeColor = 'Gray'
$Lb_WiFiOn.BackColor = "Transparent"

$Form.Controls.Add($Lb_Network)
$Lb_Network.Location = '10, 80'
$Lb_Network.Size = '75, 20'
$Lb_Network.Text = "Network"
$Lb_Network.ForeColor = 'Gray'
$Lb_Network.BackColor = "Transparent"

$Form.Controls.Add($Lb_Google)
$Lb_Google.Location = '10, 105'
$Lb_Google.Size = '75, 20'
$Lb_Google.Text = "Google"
$Lb_Google.ForeColor = 'Gray'
$Lb_Google.BackColor = "Transparent"

$Form.Controls.Add($Lb_DontReplyToo)
$Lb_DontReplyToo.Location = '10, 130'
$Lb_DontReplyToo.Size = '75, 20'
$Lb_DontReplyToo.Text = "DontReplyToo"
$Lb_DontReplyToo.ForeColor = 'Gray'
$Lb_DontReplyToo.BackColor = "Transparent"

$Form.Controls.Add($Lb_DontReply)
$Lb_DontReply.Location = '10, 155'
$Lb_DontReply.Size = '75, 20'
$Lb_DontReply.Text = "Dont Reply"
$Lb_DontReply.ForeColor = 'Gray'
$Lb_DontReply.BackColor = "Transparent"

$Form.Controls.Add($Pb_LANOn)
$Pb_LANOn.Location = '115, 33'
$Pb_LANOn.Size = '15, 15'
$Pb_LANOn.Image = $RedLight
$Pb_LANOn.BackColor = "Transparent"

$Form.Controls.Add($Pb_WiFiOn)
$Pb_WiFiOn.Location = '115, 58'
$Pb_WiFiOn.Size = '15, 15'
$Pb_WiFiOn.Image = $RedLight
$Pb_WiFiOn.BackColor = "Transparent"

$Form.Controls.Add($Pb_Network)
$Pb_Network.Location = '115, 83'
$Pb_Network.Size = '15, 15'
$Pb_Network.Image = $RedLight
$Pb_Network.BackColor = "Transparent"

$Form.Controls.Add($Pb_Google)
$Pb_Google.Location = '115, 108'
$Pb_Google.Size = '15, 15'
$Pb_Google.Image = $RedLight
$Pb_Google.BackColor = "Transparent"

$Form.Controls.Add($Pb_DontReplyToo)
$Pb_DontReplyToo.Location = '115, 133'
$Pb_DontReplyToo.Size = '15, 15'
$Pb_DontReplyToo.Image = $RedLight
$Pb_DontReplyToo.BackColor = "Transparent"

$Form.Controls.Add($Pb_DontReply)
$Pb_DontReply.Location = '115, 158'
$Pb_DontReply.Size = '15, 15'
$Pb_DontReply.Image = $RedLight
$Pb_DontReply.BackColor = "Transparent"

#Toolbar

$Form.Controls.Add($Pb_Sync)
$Pb_Sync.Location = '20, 195'
$Pb_Sync.Size = '20, 20'
$Pb_Sync.Image = $SyncImg
$Pb_Sync.BackColor = "Transparent"
$Pb_Sync.Add_Click({Sync-Content})

$Form.Controls.Add($Pb_Browser)
$Pb_Browser.Location = '51, 195'
$Pb_Browser.Size = '20, 20'
$Pb_Browser.Image = $BrowserImg
$Pb_Browser.BackColor = "Transparent"
$Pb_Browser.Add_Click({Open-Browser})

$Form.Controls.Add($Pb_Help)
$Pb_Help.Location = '82, 195'
$Pb_Help.Size = '20, 20'
$Pb_Help.Image = $HelpImg
$Pb_Help.BackColor = "Transparent"
$Pb_Help.Add_Click({Open-Help($HelpText)})

$Form.Controls.Add($Pb_Minimize)
$Pb_Minimize.Location = '113, 195'
$Pb_Minimize.Size = '20, 20'
$Pb_Minimize.Image = $MinimizeImg
$Pb_Minimize.BackColor = "Transparent"
$Pb_Minimize.Add_Click({Minimize-Dashboard})

   ########## MAIN

#Status Init
#$Status = GetStatus 

#Create the Status Background Job 
Start-Job -Name "jobGetStatus" -ScriptBlock {$Status = GetStatus} #function not recognized by Background Job

#Wait for job result
While (Get-Job -Name "jobGetStatus" | where { $_.State -eq "Running" })
    {Start-Sleep 1}

#Get Status on Timer Tick
$Timer.Add_Tick({Get-Job -Name "jobGetStatus" | Receive-Job}) #job not updated

#Display new status on tick
$Timer.Add_Tick({
                        #LAN
                        If ($Status.LANOnStatus -eq $True)
                            {$Pb_LANOn.Image = $GreenLight}
                        else
                            {$Pb_LANOn.Image = $RedLight}

                        #WIFI
                        If ($Status.WiFiOnStatus -eq $True)
                            {$Pb_WiFiOn.Image = $GreenLight}
                        else
                            {$Pb_WiFiOn.Image = $RedLight}

                        #NETWORK
                        If ($Status.NetworkStatus -eq $True)
                            {$Pb_Network.Image = $GreenLight}
                        else
                            {$Pb_Network.Image = $RedLight}

                        #GOOGLE
                        If ($Status.GoogleStatus -eq $True)
                            {$Pb_Google.Image = $GreenLight}
                        else
                            {$Pb_Google.Image = $RedLight}

                        #DontReplyToo
                        If ($Status.DontReplyTooStatus -eq $True)
                            {$Pb_DontReplyToo.Image = $GreenLight}
                        else
                            {$Pb_DontReplyToo.Image = $RedLight}            

                        #BING
                        If ($Status.DontReplyStatus -eq $True)
                            {$Pb_DontReply.Image = $GreenLight}
                        else
                            {$Pb_DontReply.Image = $RedLight}         

})

#Start Timer
$Timer.Enabled = $True

#Agent Init
$objNotifyIcon.Icon = $IconStd
$objNotifyIcon.Text = "Dashboard"
$objNotifyIcon.Visible = $True 

#Show Interface
$Form.ShowDialog() 

  ############## END

Respuestas a la pregunta(1)

Su respuesta a la pregunta