2017-01-11 2 views
1

Уверен, что у меня была эта работа до этого без проблем, но теперь я не уверен, что происходит.PowerShell Hashtable неверно возвращается

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 

Я ожидал получить чистую таблицу, в которой я мог бы вытащить данные из, но вместо этого я получаю это:

screenshot

Если я просто запускаю Script2 на нем Я могу использовать $HashTable.Value1, но возвращение его в Script1 кажется проблемой.

+0

Ваш 'hashtable' фактически начинается с @. Здесь вы создаете 'PSObject'. – sodawillow

ответ

3

При работе с PowerShell.exe вы фактически вызываете внешнюю команду, и результат получается, скорее всего, [System.Object[]]. Вы можете проверить это легко с помощью метода GetType:

$Output.GetType() 

, как вы должны запускать сценарии PowerShell либо оператор вызова (&) или точка-Sourcing оператор (.). Former запускает скрипт в своей собственной области (поэтому переменные/функции, определенные в скрипте, не будут «течь» в родительскую область). Последний выполнит скрипт, как если бы он был неотъемлемой частью родителя. В вашем случае оператор должен сделать то, что вам нужно:

$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 

Это должно предоставить вам пользовательский объект, как и ожидалось. Чтобы получить только хэш-таблицу - вам не нужно New-Object - просто вернуть хеш-таблицу, переданную в параметр Property этой команды.

+0

Удивительный, спасибо за это. все это стало довольно очевидным. Я начал использовать 'PowerShell.exe -File', чтобы обойти проблему, связанную с переменными окружения на пути, но оператор вызова также устраняет эту проблему. Спасибо за помощь –

1

Согласен с sodawillow; просто используйте:

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

Вы используете Script2.ps1 в другом процессе PowerShell. Объекты PowerShell, такие как hashtables, не переносятся через границы процесса. Вместо этого вывод преобразуется в массив строк.

Демонстрация:

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= 
== 
==

Запуск сценария в текущем процессе PowerShell (например, с помощью оператора вызова), чтобы избежать этого:

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 Примечание: в качестве @sodawillow указано в комментарии к вашему вопросу вы создаете пользовательский объект, а не хэш-таблицу.

Смежные вопросы