Reputation: 43
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:
If I just run Script2 on it's own I can use $HashTable.Value1
but returning it to Script1 seems to be an issue.
Upvotes: 1
Views: 4013
Reputation: 200203
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.
Upvotes: 2
Reputation: 2229
Agree with sodawillow; just use:
[Hashtable] $HashTable = @{ 'Value1' = 'Data1';
'Value2' = 'Data2';
'Value3' = 'Data3'
}
return $HashTable;
Upvotes: 1
Reputation: 8650
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.
Upvotes: 3