1

I am sure I have had this working before with no issues but now I am not sure what is going on.

Script1.ps1:

$Output = PowerShell.exe -File "C:\Temp1\Script2.ps1"
$Output.Value1

Script2.ps1:

$HashTable = New-Object PSObject -Property @{
    "Value1" = "Data1"
    "Value2" = "Data2"
    "Value3" = "Data3"
}
return $HashTable

I was expecting to get a clean table that I could pull data from but instead I get this:

screenshot

If I just run Script2 on it's own I can use $HashTable.Value1 but returning it to Script1 seems to be an issue.

1
  • Your hashtable actually starts with @. Here you are creating a PSObject. Commented Jan 11, 2017 at 20:53

3 Answers 3

3

When you are running PowerShell.exe - you are effectively calling external command, and result you get is most likely [System.Object[]]. You can verify it easily using method GetType:

$Output.GetType()

The way you should run PowerShell scripts is either call operator (&) or dot-sourcing operator (.). Former will run a script in it's own scope (so variables/functions defined in the script won't "leak" into the parent scope). Latter will execute script as if it was integral part of the parent. In your case call operator should do what you need:

$Output = & "c:\temp\Script1.ps1"
# or - as there are no spaces in the path, so script acts as any other command...
$Output = c:\temp\Script1.ps1

That should give you custom object, as expected. To get just hashtable - you don't need New-Object - just return hash table passed to Property parameter of that command.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks for that. it all became rather obvious. I started using PowerShell.exe -File to circumvent an issue I had with environmental variables in the path, but the call operator also resolves this issue. Thanks for the assistance
2

You're running Script2.ps1 in a different PowerShell process. PowerShell objects like hashtables are not transported across process boundaries. Instead the output is transformed into an array of strings.

Demonstration:

PS C:\> $Output = powershell.exe -File '.\test.ps1'
PS C:\> $Output

Value1              Value2              Value3
------              ------              ------
Data1               Data2               Data3


PS C:\> $Output.GetType().FullName
System.Object[]
PS C:\> $Output[0].GetType().FullName
System.String
PS C:\> $Output | % { '=' + $_.Trim() + '=' }
==
=Value1              Value2              Value3=
=------              ------              ------=
=Data1               Data2               Data3=
==
==

Run the script in the current PowerShell process (e.g. via the call operator) to avoid this:

PS C:\> $Output = & '.\test.ps1'
PS C:\> $Output

Value1              Value2              Value3
------              ------              ------
Data1               Data2               Data3


PS C:\> $Output.GetType().FullName
System.Management.Automation.PSCustomObject
PS C:\> $Output.Value1
Data1

Side note: as @sodawillow pointed out in the comments to your question you're creating a custom object, not a hashtable.

Comments

1

Agree with sodawillow; just use:

[Hashtable] $HashTable = @{ 'Value1' = 'Data1';
                            'Value2' = 'Data2';
                            'Value3' = 'Data3'
                          }
return $HashTable;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.