2 votes

Powershell. Accès à une variable en dehors d'une instance de Runspace

J'ai écrit une petite application en utilisant WPF et Runspaces et j'ai rencontré quelques difficultés.

$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()

$code = {
    #Build the GUI
    [xml]$xaml = @"
   $xaml_code
"@

    $syncHash = [hashtable]::Synchronized(@{ })
    $reader = (New-Object System.Xml.XmlNodeReader $xaml)
    $syncHash.Window = [Windows.Markup.XamlReader]::Load($reader)

    function RunspaceScript {
        param($syncHash, $Servers, $TargetBox)
            $syncHash.Host = $host
            $Runspace = [runspacefactory]::CreateRunspace()
            $Runspace.ApartmentState = "STA"
            $Runspace.ThreadOptions = "ReuseThread"
            $Runspace.Open()
            $Runspace.SessionStateProxy.SetVariable("syncHash", $syncHash)
            $Runspace.SessionStateProxy.SetVariable("Servers", $Servers)
            $Runspace.SessionStateProxy.SetVariable("TargetBox", $TargetBox)

            $code = {
                Function Add-OutputBoxLine {
                    Param ([string]$Message,[string]$Color = "Black")
                    $syncHash.Window.Dispatcher.invoke(
                            [action]{
                                $RichTextRange = New-Object System.Windows.Documents.TextRange($syncHash.$TargetBox.Document.ContentEnd, $syncHash.$TargetBox.Document.ContentEnd)
                                $RichTextRange.Text = "$Message`r`n"
                                $RichTextRange.ApplyPropertyValue([System.Windows.Documents.TextElement]::ForegroundProperty, "$Color")
                                $syncHash.$TargetBox.ScrollToCaret()
                            }
                    )
                }
                $syncHash.Window.Dispatcher.invoke(
                        [action]{ $syncHash.$TargetBox.Clear(); $syncHash.Start_Switchover.IsEnabled = $False })
                if (!$az_connection) {
                    $az_connection = Connect-AzAccount
                }
            }
            $PSinstance = [powershell]::Create().AddScript($Code)
            $PSinstance.Runspace = $Runspace
            $PSinstance.Runspace.Name = "SwitchOver"
            $job = $PSinstance.BeginInvoke()
    }

      # Click Actions
    $syncHash.Start_Switchover.Add_Click(
            {
                RunspaceScript -syncHash $syncHash -Servers $syncHash.Servers.Text -TargetBox "Process_Output"
            })

    $syncHash.Window.ShowDialog()
    $Runspace.Close()
    $Runspace.Dispose()
}

$PSinstance1 = [powershell]::Create().AddScript($Code)
$PSinstance1.Runspace = $Runspace
$job = $PSinstance1.BeginInvoke()

Je veux accéder à la variable $az_connection qui se trouve dans un runpace qui se trouve dans une fonction "RunspaceScript" à partir d'une exécution précédente de cette fonction. Avez-vous une idée de la façon dont cela peut être réalisé ?

P.S. J'ai été obligé de supprimer certaines lignes du code script ici à cause des règles, n'essayez pas de copier et d'exécuter le code, cela ne fonctionnera pas.

2voto

Daniel Points 2020

Le moyen le plus simple est probablement de l'ajouter à $syncHash -. $syncHash.AzConnection = $az_connection . Sinon, vous devez le renvoyer en tant que sortie de votre bloc de script, puis récupérer la sortie une fois que l'AsyncResult est terminé.

function RunspaceScript {
    param($syncHash, $Servers, $TargetBox)
    $syncHash.Host = $host
    $Runspace = [runspacefactory]::CreateRunspace()
    $Runspace.ApartmentState = 'STA'
    $Runspace.ThreadOptions = 'ReuseThread'
    $Runspace.Open()
    $Runspace.SessionStateProxy.SetVariable('syncHash', $syncHash)
    $Runspace.SessionStateProxy.SetVariable('Servers', $Servers)
    $Runspace.SessionStateProxy.SetVariable('TargetBox', $TargetBox)

    $code = {
        Function Add-OutputBoxLine {
            Param ([string]$Message, [string]$Color = 'Black')
            $syncHash.Window.Dispatcher.invoke(
                [action] {
                    $RichTextRange = New-Object System.Windows.Documents.TextRange($syncHash.$TargetBox.Document.ContentEnd, $syncHash.$TargetBox.Document.ContentEnd)
                    $RichTextRange.Text = "$Message`r`n"
                    $RichTextRange.ApplyPropertyValue([System.Windows.Documents.TextElement]::ForegroundProperty, "$Color")
                    $syncHash.$TargetBox.ScrollToCaret()
                }
            )
        }
        $syncHash.Window.Dispatcher.invoke(
            [action] { $syncHash.$TargetBox.Clear(); $syncHash.Start_Switchover.IsEnabled = $False })
        if (!$az_connection) {
            $az_connection = Connect-AzAccount
        }

        ## Output the connection from your scriptblock ##
        $az_connection

        ## OR just add it to your synchronized hashtable ##
        $syncHash.AzConnection = $az_connection
    }
    $PSinstance = [powershell]::Create().AddScript($Code)
    $PSinstance.Runspace = $Runspace
    $PSinstance.Runspace.Name = 'SwitchOver'
    $job = $PSinstance.BeginInvoke()

    ## Wait for the $code scriptblock to finish ##
    While (-not $job.IsCompleted) {
        Start-Sleep -Seconds 1
    }

    ## Pass the job to EndInvoke() to receive the output ##
    $az_connection = $PSinstance.EndInvoke($job) 

    ## Or access it from your synchronized hashtable ##
    $syncHash.AzConnection
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X