Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start-Job passing XML object to -ArgumentList working different in Powershell V2 & V3

I'm testing a deployment script for my application on Windows Server 2012 with Powershell v3. The script runs fine on Win Server 2008 R2 and Win 7 with Powershell v2. The issue I'm running into now is that I can not access properties of XML variables passed via -ArgumentList.

I've been able to reproduce the issue on Win 7 and Win Server 2012 with Powershell v3 in a simple script that doesn't have any of the SharePoint, IIS, misc that my main script does.

Script (I think I borrowed this from a similar question I can't find now):

$xml = [xml] (Get-Content (Get-Item (".\input.xml")))
$foobar = $xml.Stuff.FooBars.Foobar 

$ScriptBlock = {        
    $foobar = $args[0]

    write-host "Inside the job..."
    write-host ("Foobar     : "+$foobar)
    write-host ("Foobar.Foo : "+$foobar.Foo)
}

write-host "Outside the job..."
write-host ("Foobar: "+$foobar)
write-host ("Foobar.Foo : "+$foobar.Foo)

Start-Job -ScriptBlock $ScriptBlock -ArgumentList $foobar | Out-Null        
While (Get-Job -State "Running") { Start-Sleep 2 }               

write-host ("Jobs Completed.")    
Get-Job | Receive-Job          
Remove-Job * 

The Input XML:

<?xml version="1.0"?>
<Stuff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FooBars>
    <FooBar>
      <Foo>ThisIsAFoo</Foo>
     <Bar>ThisIsABar</Bar>
    </FooBar>
  </FooBars> 
</Stuff>

Output from Powershell v2:

PS C:\Powershell3Issues> .\demo.ps1
Outside the job...
Foobar: System.Xml.XmlElement
Foobar.Foo : ThisIsAFoo
Jobs Completed.
Inside the job...
Foobar     : System.Collections.ArrayList System.Collections.ArrayList
Foobar.Foo : ThisIsAFoo

Output from Powershell v3:

PS C:\Powershell3Issues> .\demo.ps1
Outside the job...
Foobar: System.Xml.XmlElement
Foobar.Foo : ThisIsAFoo
Jobs Completed.
Inside the job...
Foobar     : System.Collections.ArrayList System.Collections.ArrayList
Foobar.Foo :

Note the missing Foobar.Foo value.

I've also tried the $using syntax in v3 but it does the same thing.

like image 377
Brandon Avatar asked Jan 19 '26 09:01

Brandon


2 Answers

Try this to specify the version of PowerShell to run the job under:

Start-Job -ScriptBlock $ScriptBlock -ArgumentList $foobar -PSVersion 2.0
like image 159
Richard Anthony Freeman-Hein Avatar answered Jan 22 '26 02:01

Richard Anthony Freeman-Hein


I'm using PS 3.0 and it does change data types. I modified your script to take a look:

$xml = [xml] (Get-Content .\input.xml)
$foobar = $xml.Stuff.FooBars.Foobar 
"Foobar Outside type = $($foobar.Gettype())"

$ScriptBlock = {        
    $foobar = $args[0]
    "Foobar Inside type = $($foobar.Gettype())"
}

Start-Job -ScriptBlock $ScriptBlock -ArgumentList $foobar | Out-Null
While (Get-Job -State "Running") { Start-Sleep 2 }     
Get-Job | Receive-Job 

The output I got was:

Foobar Outside type = System.Xml.XmlElement
Foobar Inside type = System.Collections.ArrayList System.Collections.ArrayList

I'll keep looking and see what I find.

Update:

When I run the script in PS 2.0 using the command powershell -version 2.0 I get an error saying:

Method invocation failed because [Deserialized.System.Xml.XmlElement] doesn't contain a method named 'Gettype'.
+ CategoryInfo          : InvalidOperation: (Gettype:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
+ PSComputerName        : localhost 

It changes from System.Xml.XmlElement to Deserialized.System.Xml.XmlElement, right? I'll keep looking and see what I find.

Workaround:

A workaround could be instead of passing an object just pass a string.

$xml_path = 'C:\input.xml'
$sb = {
    $xml = [xml](Get-Content $args[0])
    ...
}
Start-Job -ScriptBlock $sb -Args $xml_path

I'm done searching. My head hurts when I go in depth on things.

like image 35
E.V.I.L. Avatar answered Jan 22 '26 02:01

E.V.I.L.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!