gpt4 book ai didi

powershell - 将对象传递给新的 PowerShell 实例

转载 作者:行者123 更新时间:2023-12-05 03:19:04 25 4
gpt4 key购买 nike

我有一个 PowerShell 脚本需要在新的 PowerShell 实例中执行第二个脚本,传入两个对象。发生的问题是对象被转换为包含第二个脚本中对象类型的字符串。这里有两个示例脚本来说明我正在尝试做的事情。我已经尝试使用 Start-Process 和 Invoke-Expression。我也尝试过展开论点,但这根本不起作用 - 什么都没有通过。

脚本 1:

$hash1 = @{
"key1" = "val1"
"key2" = "val2"
}

$hash2 = @{
"key3" = "val3"
"key4" = "val4"
}

$type1 = $hash1.GetType()
$type2 = $hash2.GetType()

Write-Host "Hash1 type: $type1"
Write-Host "Hash2 type: $type2"

$scriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition

$method = "Start-Process"
Start-Process -FilePath PowerShell "-noExit -command $scriptPath\script2.ps1 -hash1 $hash1 -hash2 $hash2 -method $method"

$method = "Invoke-Expression"
$command = "$scriptPath\script2.ps1 -hash1 $hash1 -hash2 $hash2 -method $method"
Invoke-Expression "cmd /c Start PowerShell -noExit -Command { $command }"

脚本 2:

param(
[PSObject]$hash1,
[PSObject]$hash2,
[string]$method
)

$type1 = $hash1.GetType()
$type2 = $hash2.GetType()

Write-Host "Method: $method"
Write-Host "Hash1 type: $type1"
Write-Host "Hash2 type: $type2"

这是每次调用的输出:

Method: Start-Process
Hash1 type: string
Hash2 type: string
Method: Invoke-Expression
Hash1 type: string
Hash2 type: string

以下是我尝试这样做的一些背景知识:

我有一个脚本可以读取包含文件系统上多个目录的 ACL 信息的 XML 文件。我需要设置每个目录的权限,但每个目录都需要时间传播到所有子项。我想为每个目录异步调用第二个脚本以减少运行时间。我需要第二个脚本的每个实例都有自己的窗口,以便用户可以检查每个实例是否有错误或其他消息。

有人可以帮忙吗?

最佳答案

这是一个使用 Runspace 的简单设置,这允许您运行异步代码而不需要序列化,也不需要通过 Start-Process 奇怪地调用您的脚本.

我将只使用一个 hashtable对于这个简单的示例,要使其尽可能短。

  • script1.ps1
$hash1 = @{
key1 = 'hello'
key2 = 'world'
}

$scriptPath = Join-Path $PSScriptRoot -ChildPath script2.ps1

$action = {
param($path, $hash1, $method)

& $path -hash1 $hash1 -method $method
}
$params = @{
path = $scriptPath
hash1 = $hash1
method = 'Runspace'
}

$iss = [initialsessionstate]::CreateDefault2()
$rs = [runspacefactory]::CreateRunspace($Host, $iss)
$rs.Open()
$ps = [powershell]::Create().AddScript($action).AddParameters($params)
$ps.Runspace = $rs
$async = $ps.BeginInvoke()

# Do my thing in this script while the other instance runs
# ...
# ...

# Receive results from the instance, this is stdout (Success stream)
$output = $ps.EndInvoke($async)
$output # => hello world
# Non-terminating errors are here
$ps.Streams.Error
# Dipose the instance and the runspace when done
$ps, $rs | ForEach-Object Dispose
  • script2.ps1
param(
[PSObject] $hash1,
[string] $method
)

Write-Host "Method: $method"
Write-Host "Hash1 type: $($hash1.GetType())"
'Standard Output: ' + $hash1['key1'] + ' ' + $hash1['key2']
Write-Warning "A Warning"
Write-Error "An Error!"

0..10 | ForEach-Object {
Write-Progress -Activity 'Testing Progress' -PercentComplete ($_ * 10)
Start-Sleep -Milliseconds 200
}

值得注意的是,由于运行空间是针对 CreateRunspace(PSHost, InitialSessionState) 初始化的过载,我们正在通过 automatic variable $Host作为 PSHost 参数,主机现在与新的运行空间相关联,这意味着所有 Streams将直接转到我们的控制台,但错误流除外,所有非终止错误都将出现,而成功流我们可以捕获在我们调用 .EndInvoke(IAsyncResult) 之后.

关于powershell - 将对象传递给新的 PowerShell 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73547767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com