无法将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
相关产品推荐
相关产品推荐

