0

I am working on a project which starts with a GUI Wizard to get some info from the user such as EndPoint FQDN, Username, Password, etc..

Once the User has provided all required info and reach to the final page in the GUI, a start button will be ready for him to click. Once this Start button is clicked, the tool will call 32 different scripts that are located into separate files.

To make the GUI more responsive and overcome the hanging issues as well as adding multithreading and better performance, I am using Runspace and RunspcaePools. So the GUI itself is running in a Runspace and once the user clicks on start a RunspacePool will be created and for each script form the 32 scripts there would be a Powershell session created and invoked.

The GUI is working fine and everything is working as expected untill the start button. My issue is that I am not able to call those script files when I am adding the script to the PowerShell Session. it is just nothing happen. If I use Wait-Debugger, I do not see any errors it is as if the ScriptBlock I am passing to the Powershell session (that has the value of the path to the script I want to execute) is just a sting and not a ScriptBlock.

My Code is as follow:

    #   This Section will add all the required Subscript Files into variables to be called by the main code of the tool.
    $SubScriptFolderPath = $CurrentWorkingDirectory + "SubCode\Scripts\"
    $SubscriptFilePath = @{}
    $SubscriptFilePath.BasicVspherePowerCliData = $SubScriptFolderPath + "BasicVspherePowerCliData.ps1"
    $SubscriptFilePath.NsxManagerPowerCliData = $SubScriptFolderPath + "NsxManagerPowerCliData.ps1"
    $SubscriptFilePath.NsxManagerPowerNsxData = $SubScriptFolderPath + "NsxManagerPowerNsxData.ps1"
    $SubscriptFilePath.NsxManagerNsxCliData = $SubScriptFolderPath + "NsxManagerNsxCliData.ps1"
    $SubscriptFilePath.ControllerPowerCliData = $SubScriptFolderPath + "ControllerPowerCliData.ps1"
    $SubscriptFilePath.ControllerPowerNsxData = $SubScriptFolderPath + "ControllerPowerNsxData.ps1"
    $SubscriptFilePath.ControllerNsxCliData = $SubScriptFolderPath + "ControllerNsxCliData.ps1"
    $SubscriptFilePath.ControllerSshData = $SubScriptFolderPath + "ControllerSshData.ps1"
    $SubscriptFilePath.ClusterPowerCliData = $SubScriptFolderPath + "ClusterPowerCliData.ps1"
    $SubscriptFilePath.ClusterPowerNsxData = $SubScriptFolderPath + "ClusterPowerNsxData.ps1"
    $SubscriptFilePath.ClusterNsxApiData = $SubScriptFolderPath + "ClusterNsxApiData.ps1"
    $SubscriptFilePath.HostPowerCliData = $SubScriptFolderPath + "HostPowerCliData.ps1"
    $SubscriptFilePath.HostPowerNsxData = $SubScriptFolderPath + "HostPowerNsxData.ps1"
    $SubscriptFilePath.HostEsxCliData = $SubScriptFolderPath + "HostEsxCliData.ps1"
    $SubscriptFilePath.HostNsxCliData = $SubScriptFolderPath + "HostNsxCliData.ps1"
    $SubscriptFilePath.DvsPowerCliData = $SubScriptFolderPath + "DvsPowerCliData.ps1"
    $SubscriptFilePath.DvsPowerNsxData = $SubScriptFolderPath + "DvsPowerNsxData.ps1"
    $SubscriptFilePath.LogicalSwitchPowerCliData = $SubScriptFolderPath + "LogicalSwitchPowerCliData.ps1"
    $SubscriptFilePath.LogicalSwitchPowerNsxData = $SubScriptFolderPath + "LogicalSwitchPowerNsxData.ps1"
    $SubscriptFilePath.TransportZonePowerCliData = $SubScriptFolderPath + "TransportZonePowerCliData.ps1"
    $SubscriptFilePath.TransportZonePowerNsxData = $SubScriptFolderPath + "TransportZonePowerNsxData.ps1"
    $SubscriptFilePath.DlrPowerCliData = $SubScriptFolderPath + "DlrPowerCliData.ps1"
    $SubscriptFilePath.DlrPowerNsxData = $SubScriptFolderPath + "DlrPowerNsxData.ps1"
    $SubscriptFilePath.DlrNsxCliData = $SubScriptFolderPath + "DlrNsxCliData.ps1"
    $SubscriptFilePath.EsgPowerCliData = $SubScriptFolderPath + "EsgPowerCliData.ps1"
    $SubscriptFilePath.EsgPowerNsxData = $SubScriptFolderPath + "EsgPowerNsxData.ps1"
    $SubscriptFilePath.EsgNsxCliData = $SubScriptFolderPath + "EsgNsxCliData.ps1"
    $SubscriptFilePath.DfwPowerCliData = $SubScriptFolderPath + "DfwPowerCliData.ps1"
    $SubscriptFilePath.DfwPowerNSXData = $SubScriptFolderPath + "DfwPowerNSXData.ps1"
    $SubscriptFilePath.DumpEndPoints = $SubScriptFolderPath + "DumpEndPoints.ps1"


    #   Create  Sync HashTable (GuiHash) to allow readability across different Runscpases and add required variables.
    $Global:GuiHash = [hashtable]::Synchronized(@{ })
    $Global:GuiHash.IPCehckPattern = $IPRegex   #   Add the IPCehckPattern Variable to be used within other runspaces
    $Global:GuiHash.SubscriptFilePath = $SubscriptFilePath  #   Add the SubCodePaths Variable to be used within other runspaces

    #   Crate the Runspace that will be used for the GUI and configure settings. After, Open the Runspace and import variables.
    #   You must import variables that will be used in other Runspaces, thus importing the required variables to this Runspace.
    $GuiRunspace =[runspacefactory]::CreateRunspace()
    $GuiRunspace.ApartmentState = "STA"
    $GuiRunspace.ThreadOptions = "ReuseThread"         
    $GuiRunspace.Open()
    $GuiRunspace.SessionStateProxy.SetVariable("GuiHash",$Global:GuiHash)  
    $GuiRunspace.SessionStateProxy.SetVariable("XamlFilesArray",$XamlFilesArray)

    #   Create a PowerShell Session and add it to the Runspace.
    $GuiPSSession = [PowerShell]::Create()
    $GuiPSSession.Runspace = $GuiRunspace

    #   Create the GUI PowerShell Session ScriptBlock. This will be the main code of the tool.
    [void]$GuiPSSession.AddScript({

          [Some code that is taking care of GUI]

          $GuiHash.WizardFinalPageStart.Add_Click({

               #    Create Session State Object and Add GuiHash Variable to it
               $InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
               $RunHash = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'RunHash',$Global:GuiHash,$Null
               $InitialSessionState.Variables.Add($RunHash)
               #  Create Runspace Pool
               $RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, [int]$env:NUMBER_OF_PROCESSORS + 1, $InitialSessionState, $Host)
               $RunspacePool.ApartmentState = "MTA"  
               $RunspacePool.Open()
               ForEach ($ScriptBlock in $Global:GuiHash.SubscriptFilePath) {
                    $PowerShellSession = [PowerShell]::Create()
                    $PowerShellSession.RunspacePool = $RunspacePool 
                    $PowerShellSession.AddScript({$ScriptBlock})
                    $PowerShellSession.BeginInvoke()
               }
          })

        #   Show Wizard Window.
        $Global:GuiHash.WizardMainWindow.ShowDialog() | Out-Null
    })  

    $ShowGui = $GuiPSSession.BeginInvoke()

I have tried many things such as:

  • Adding & to the beginning of the script path.

  • Adding . to the beginning of the script path.

  • Using Get-Content

  • Using the ScriptBlock System Object

    $Scriptblock = [scriptblock]::Create((Get-Content $ScriptPath))

Nothing seems to work. I would appreciate your help over this one.

Thanks

1 Answers1

0

I think I did the same mistake again, Sorry this project is making my mind to hang sometimes. You need to remove the brackets when calling a script block. so you need to call the script block as below

$PowerShellSession.AddScript($ScriptBlock)