Преобразовать строку в PsCustomObject

Проблема, которую я имею, проистекает из прохождения PsCustomObject в качестве аргумента Start-Process Командлет (по сути, я запускаю новый процесс PowerShell для асинхронного запуска сценария из вызывающего сценария). Дело в том, что хотя параметр определяется как тип PsCustomObjectпо какой-то причине он принимается как строка, поэтому, похоже, мне необходимо преобразовать его обратно в PSCustomObject получить доступ к любым атрибутам.

Вот необходимая часть моего скрипта вызова:

# Convert JSON object to PS object
$payload = ConvertFrom-Json $body

Write-Host $payload 
## Returns exactly the following PsCustomObject:

## @{os=Windows Server Datacenter 2016; vmName=sbtestvm; diskType=Managed; username=testuser; 
## password=Pa55w.rd1234; location=West Europe; size=Standard_D1; 
## requestType=0; sender=test}

Write-Host $payload.os
## Returns: Windows Server Datacenter 2016

# Fire up new worker shell Asynchronously
Start-Process powershell.exe -ArgumentList '-NoExit', "$PSScriptRoot\ServiceBus-AsyncWorker.ps1", "'$payload'"  # -Windowstyle Hidden

И мой выполненный скрипт:

Param(
    [Parameter(Mandatory=$True)]
    [PSCustomObject]$Request
)

# Import RequestHandler module to deal with processing service bus requests
Import-Module $PSScriptRoot\RequestHandler\RequestHandler.psm1

Write-Host $Request
## Returns exactly the same as 'Write-Host $payload' in the calling script

Write-Host $Request.os
## Returns empty string

Write-Host $Request.GetType()
## Returns System.String <--- This is the issue

Короче говоря: есть ли способ предотвратить автоматический анализ этого объекта в виде строки? Если нет - как эту строку можно привести к соответствующему типу объекта?

1 ответ

Решение

Start-Process powershell.exe запускает новый процесс PowerShell. Вы не можете передавать объекты PowerShell через границы процессов.

Вы могли бы изменить

Start-Process powershell.exe -ArgumentList '-NoExit', "$PSScriptRoot\ServiceBus-AsyncWorker.ps1", "'$payload'"

в

$PSScriptRoot\ServiceBus-AsyncWorker.ps1 $payload

чтобы избежать создания нового процесса, но он будет запускать скрипт в том же окне.

Если вам нужно запустить скрипт отдельно от консоли, вы можете запустить его как фоновое задание:

$job = Start-Job -ScriptBlock {
    Param($Path, $Data)
    & "$Path\ServiceBus-AsyncWorker.ps1" $Data
} -ArgumentList $PSScriptRoot, $payload

В противном случае вам нужно передать аргумент в сериализованной форме (например, исходный JSON) при порождении нового процесса:

Start-Process powershell.exe -ArgumentList '-NoExit', "$PSScriptRoot\ServiceBus-AsyncWorker.ps1", "`"$body`""

а затем (повторно) создать объект из строки:

Param(
    [Parameter(Mandatory=$true)]
    [string]$Json
)

# Import RequestHandler module to deal with processing service bus requests
Import-Module $PSScriptRoot\RequestHandler\RequestHandler.psm1

$Request = ConvertFrom-Json $Json
...
Другие вопросы по тегам