You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将PSObject作为参数传递给Start-Process的问题求助

问题原因解析

你遇到的问题本质是PowerShell对象跨进程传递时的字符串化限制。当你通过Start-Process的ArgumentList传递$InputOBJ时,PowerShell会自动把这个PSObject转换成它的默认字符串形式——也就是你看到的@{Server=Server1; Database=Database1}。

但命令行参数是按空格分割的,当这个字符串被传到新的PowerShell进程时,分号后面的 Database=Database1会被当成独立参数,而你的ls.ps1只接收到了第一个参数片段@{Server=Server1;,自然就出现了对象结构损坏的情况。


解决方案1:拆分属性为独立字符串传递

既然单独传字符串参数没问题,直接把对象的属性拆成独立参数传给脚本就可以了,这是最简单直接的方式:

主脚本修改:

$Child.ChildNodes.GetEnumerator()|ForEach-Object{
  $server = $_.grandchilditem1
  $database = $_.grandchilditem2
  $psfilepath = Get-Location
  # 把每个属性作为单独参数传递,避免字符串分割问题
  Start-Process -filepath "powershell.exe" -ArgumentList @("-NoExit", "$psfilepath\ls.ps1", "-Server", $server, "-Database", $database) -WindowStyle Normal
}

对应ls.ps1定义参数:

param(
    [string]$Server,
    [string]$Database
)

Write-Host "Server: $Server, Database: $Database"

解决方案2:用Clixml序列化传递完整对象

如果必须传递完整的PSObject(而不是零散属性),可以先将对象序列化为XML字符串,传递后再反序列化还原:

主脚本修改:

$Child.ChildNodes.GetEnumerator()|ForEach-Object{
  $InputOBJ = New-Object PSObject -Property @{
        Server = $_.grandchilditem1
        Database = $_.grandchilditem2
    }
  # 序列化对象为XML,用引号包裹避免空格分割
  $serializedObj = [System.Management.Automation.PSSerializer]::Serialize($InputOBJ)
  $psfilepath = Get-Location
  Start-Process -filepath "powershell.exe" -ArgumentList @("-NoExit", "$psfilepath\ls.ps1", "`"$serializedObj`"") -WindowStyle Normal
}

对应ls.ps1反序列化:

param(
    [string]$SerializedObject
)

# 把XML字符串还原为PSObject
$InputOBJ = [System.Management.Automation.PSSerializer]::Deserialize($SerializedObject)
Write-Host $InputOBJ
Write-Host "Server: $($InputOBJ.Server), Database: $($InputOBJ.Database)"

这种方法能完整保留对象结构,适合传递复杂对象的场景。


解决方案3:用PowerShell Jobs替代Start-Process

如果你不需要单独的控制台窗口,PowerShell Jobs是更优雅的选择——它原生支持PowerShell对象传递,完全不用处理字符串化的麻烦:

主脚本修改:

$Child.ChildNodes.GetEnumerator()|ForEach-Object{
  $InputOBJ = New-Object PSObject -Property @{
        Server = $_.grandchilditem1
        Database = $_.grandchilditem2
    }
  $psfilepath = Get-Location
  # 启动后台作业,直接传递对象
  Start-Job -ScriptBlock {
      param($obj)
      & "$using:psfilepath\ls.ps1" -InputOBJ $obj
  } -ArgumentList $InputOBJ
}

# 查看所有作业的执行结果
Get-Job | Receive-Job

对应ls.ps1:

param(
    [PSObject]$InputOBJ
)

Write-Host $InputOBJ
Write-Host "Server: $($InputOBJ.Server), Database: $($InputOBJ.Database)"

Jobs不仅能避免参数传递问题,还能方便地管理后台任务的状态和结果。

内容的提问来源于stack exchange,提问作者Adarsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:13:17