![](/img/trans.png)
[英]How do I properly pass arguments to a scriptblock using powershell runspaces?
[英]How do you reuse local functions in different PowerShell runspaces?
我一直在玩耍並學習運行空間和 Winforms,我想知道我如何 go 為我制作的每個不同的運行空間重用 function。 我可以通過在每個腳本塊中包含 function 的完整腳本來使其工作,但我希望只編寫一次 function 並在創建新運行空間時引用它。
這是我目前擁有的:
$hash = [hashtable]::Synchronized(@{})
$Script:Jobs = [system.collections.arraylist]::Synchronized((New-Object System.Collections.ArrayList))
# Our main GUI Form object
$hash.Form = New-Object System.Windows.Forms.Form
# Results that come back from the query get saved here
$script:hash.ServerResults = $null
# Buttons
$hash.QueryServerButton = New-Object System.Windows.Forms.Button
# Button properties
$hash.QueryServerButton.Location = New-Object System.Drawing.Point(40,300)
$hash.QueryServerButton.Size = New-Object System.Drawing.Size (105,40)
$hash.QueryServerButton.Text = "Get Servers"
$hash.QueryServerButton.Add_Click({
PerformRunspaceAction($QueryServer)
})
$hash.ServerTab.Controls.Add($hash.QueryServerButton)
$QueryServer = {
$connectionString = "Server=xxx\xxx;Database=xxxx;Trusted_Connection=True;"
$sql = @"
SELECT * FROM DB_DB;
"@
do {
Start-Sleep -Seconds 30
$script:hash.ServerResults = sqlExecuteRead $connectionString $sql $pars
} while ($true)
}
Function PerformRunspaceAction {
param($scriptRun)
$newRunspace = [runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("hash", $hash)
$Powershell = [powershell]::Create().AddScript($scriptRun)
$Powershell.Runspace = $newRunspace
[void]$Script:Jobs.Add((
[PSCustomObject]@{
PowerShell = $PowerShell
Runspace = $PowerShell.BeginInvoke()
}
))
}
function sqlExecuteRead($connectionString, $sqlCommand, $pars) {
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$connection.Open()
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)
if ($pars -and $pars.Keys) {
foreach($key in $pars.keys) {
# avoid injection in varchar parameters
$par = $command.Parameters.Add("@$key", [system.data.SqlDbType]::VarChar, 512);
$par.Value = $pars[$key];
}
}
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
$adapter.Fill($dataset) | Out-Null
$connection.Close()
return $dataset.tables[0].rows
}
它的布局方式不起作用,但是如果我將 sqlExecuteRead function 移動到 $QueryServer 中,它可以正常工作。 問題是我想在許多其他運行空間中使用這個 function 並且希望不要到處復制粘貼它。 抱歉,如果代碼似乎缺少部分/用例沒有意義,因為我不得不刪掉很多。 :)
任何幫助表示贊賞!
這是一種初始化運行空間的方法,包括本地 session 中的預定義函數。 下面的代碼將函數添加到InitialSessionState
實例,在這種情況下,我們將使用Default2
session state因為這是一個更輕的版本。 然后使用RunspacePool
CreateRunspacePool(Int32, Int32, InitialSessionState, PSHost)
構造函數實例化 RunspacePool,它允許我們將預定義的InitialSessionState
實例與其中的函數一起包含在內。
using namespace System.Management.Automation.Runspaces
function Say-Hello1 {param($i) "Hello from function 1 - Runspace $i" }
function Say-Hello2 {param($i) "Hello from function 2 - Runspace $i" }
[SessionStateFunctionEntry[]] $funcs = Get-Command Say-Hello* | ForEach-Object {
[SessionStateFunctionEntry]::new($_.Name, $_.Definition)
}
$iss = [initialsessionstate]::CreateDefault2()
$iss.Commands.Add($funcs)
$rspool = [runspacefactory]::CreateRunspacePool(1, 10, $iss, $Host)
$rspool.Open()
$runspaces = 1..10 | ForEach-Object {
$ps = [powershell]::Create().AddScript({
param($i)
Start-Sleep 2
Say-Hello1 $i
Say-Hello2 $i
}).AddParameters(@{ i = $_ })
$ps.RunspacePool = $rspool
@{
Instance = $ps
AsyncResult = $ps.BeginInvoke()
}
}
foreach($runspace in $runspaces) {
$runspace.Instance.EndInvoke($runspace.AsyncResult)
$runspace.Instance.Dispose()
}
$rspool.Dispose()
在上面的示例中,您會注意到我們可以使用Get-Command
來定位將使用運行空間初始化的所需函數,此 cmdlet 允許使用通配符以及多個 function 名稱。 假設您有函數Get-This
、 Set-That
和Add-SomethingElse
,您還可以創建具有確切函數名稱的SessionStateFunctionEntry
枚舉:
[SessionStateFunctionEntry[]] $funcs = Get-Command Get-This, Set-That, Add-SomethingElse | ForEach-Object {
[SessionStateFunctionEntry]::new($_.Name, $_.Definition)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.