【问题标题】:How to call powershell ps1 file with argument in runspacepool with powershell module如何使用powershell模块在runspacepool中调用带有参数的powershell ps1文件
【发布时间】:2021-09-09 04:07:51
【问题描述】:

我正在学习 powershell。目前我有一个严格的要求。我需要从 powershell 模块(psm1)并行调用 powershell 脚本(ps1)。 ps1任务如下

param(
    [Parameter(Mandatory=$true)]
    [String] $LogMsg,
    [Parameter(Mandatory=$true)]
    [String] $FilePath
)
Write-Output $LogMsg
$LogMsg | Out-File -FilePath $FilePath -Append

文件路径类似于“C:\Users\user\Documents\log\log1.log” 在 psm1 文件中,我使用 runspacepool 来执行异步任务。像下面的demo

$MaxRunspaces = 5

$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxRunspaces)
$RunspacePool.Open()

$Jobs = New-Object System.Collections.ArrayList

Write-Host $currentPath
Write-Host $lcmCommonPath

$Filenames = @("log1.log", "log2.log", "log3.log")

foreach ($File in $Filenames) {
    Write-Host "Creating runspace for $File"
    $PowerShell = [powershell]::Create()
    $PowerShell.RunspacePool = $RunspacePool
    $FilePath = -Join("C:\Users\user\Documents\log\",$File)
    $PowerShell.AddScript("C:\Users\user\Documents\foo.ps1").AddArgument($FilePath) | Out-Null
    
    $JobObj = New-Object -TypeName PSObject -Property @{
        Runspace = $PowerShell.BeginInvoke()
        PowerShell = $PowerShell  
    }

    $Jobs.Add($JobObj) | Out-Null
}

但是有两个严重的问题。

  1. 无法将参数传递给 ps1 文件。 我只是尝试在 ps1 文件端创建文件路径,它可以工作并创建文件。但是当我尝试从 psm1 文件中传递参数时。未创建文件。我也尝试使用脚本块,它可以传递参数。但是由于我的ps1代码太大(以上只是其中的一部分),使用脚本块是不真实的。我需要一种将参数传递给 ps1 文件的方法。
  2. 在 psm1 仍在运行时无法在 ps1 文件中获取写入主机信息

如果runspacepool 对将参数传递给ps1 文件有限制,是否有其他解决方案来处理powershell 脚本的异步任务?谢谢。

【问题讨论】:

    标签: windows powershell runspace


    【解决方案1】:

    无法将参数传递给 ps1 文件。

    使用AddParameter() 而不是AddArgument() - 这将允许您按名称将参数绑定到特定参数:

    $PowerShell.AddScript("C:\Users\user\Documents\foo.ps1").
                AddParameter('FilePath', $FilePath).
                AddParameter('LogMsg', 'Log Message goes here') | Out-Null
    

    当 psm1 仍在运行时,无法在 ps1 文件中获取写入主机信息

    正确 - 您无法从未附加到主机应用程序默认运行空间的脚本中获取主机输出 - 但如果您使用 PowerShell 5 或更新版本,您可以$PowerShell 收集结果信息如果您愿意,可以实例化并转发:

    # Register this event handler after creating `$PowerShell` but _before_ calling BeginInvoke()
    Register-ObjectEvent -InputObject $PowerShell.Streams.Information -EventName DataAdded -SourceIdentifier 'WriteHostRecorded' -Action {
      $recordIndex = $EventArgs.Index
      $data = $PowerShell.Streams.Information[$recordIndex]
      Write-Host "async task wrote '$data'"
    }
    

    【讨论】:

    • 嗨,感谢 cmets 写主机。关于传递参数,我尝试了 AddParameter 但它仍然失败。我添加了一种解决方法,首先读取 ps1 文件的字符串,然后将其添加为脚本块。有用。不太清楚为什么,如果有人也遇到它就记录下来。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2014-10-25
    • 2011-10-12
    • 2022-06-23
    相关资源
    最近更新 更多