0

I had a requirement to read an input file, which is an xml (as below)

<Parent>
  <Child>
    <grandchilditem1>Server1</grandchilditem1>
    <grandchilditem2>Database1</grandchilditem2>
  </Child>
</Parent>
<Parent>
  <Child>
    <grandchilditem1>Server1</grandchilditem1>
    <grandchilditem2>Database1</grandchilditem2>
  </Child>
</Parent>

My main powershell script parses the xml, and creates an object with input parameters in a foreach loop for each Child and calls another powershell script with the argument as that object created from each child item. This is necessary as to run scripts in parallel in different consoles.

$Child.ChildNodes.GetEnumerator()|ForEach-Object{
  $InputOBJ = New-Object PSObject -Property @{
        Server = $_.grandchilditem1
        Database = $_.grandchilditem2
    }
  $psfilepath = Get-Location
  Start-Process -filepath "powershell.exe" -ArgumentList @("-NoExit", "$psfilepath\ls.ps1 $InputOBJ") -WindowStyle Normal
}

My problem is, this executes fine and opens two different consoles for 2 child nodes, but the $inputobj isn't passing completely. It gets truncated. However, if I pass each individual parameter as a string value, it accepts all.

I want to know, what is the reason that an object isn't properly passing.

In the new console that opens, the output will be only the first item. for eg., my ls.ps1 has a statement

write-host $inputobj 

it outputs, just this.

@{Server=Server1;

The object structure is compromised too. I believe, its being sent as a string instead of an object.

Please let me know if anybody had more knowledge on this.

4

1 回答 1

0

As you can only pass strings to Start-Process an alternative is to serialise the object to xml using Export-Clixml, pass the path to the serialised object, then in your target script deserialise the object using Import-Clixml.

Your main script will look something like this:

$tempObjectPath = [System.IO.Path]::GetTempFileName()
Export-Clixml -InputObject $InputOBJ -Path $tempObjectPath

$psfilepath = Get-Location
Start-Process `
    -filepath "powershell.exe" `
    -ArgumentList @("-NoExit", "$psfilepath\ls.ps1 $tempObjectPath") `
    -WindowStyle Normal

Then in your target script, deserialise the xml back to your PSObject:

$InputOBJ = Import-Clixml -Path $tempObjectPath

# Optionally, delete the temporary file
Remove-Item -Path $tempObjectPath -Force
于 2018-03-16T08:30:31.007 回答