2015-10-01 2 views
1

Во-первых, я связан с PowerShell v2, потому что это то, что установлено по умолчанию в Windows 7. Что я хочу делать из коробки с PowerShell v4 и , возможно, PowerShell v3.PowerShell v2 Преобразует словарь в массив при возврате из функции

Я хочу прочитать объект JSON из файла и использовать его в качестве объекта в своем скрипте. PowerShell v2 не имеет метод ConvertFrom-JSon, поэтому я написал свою собственную реализацию, что я хочу иметь такую ​​же функциональность:

function ConvertFrom-Json 
{ 
    param(
     [Parameter(ValueFromPipeline=$true)] 
     [string]$json 
    ) 
     [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") 
    $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 
    $obj = $ser.DeserializeObject($json) 

    Write-Host $obj.GetType() 

    return $obj 
}   

Я называю эту функцию следующим образом:

$configObj = (Get-Content $configFile) -join "`n" | ConvertFrom-Json 
Write-Host $configObj.GetType() 

Выход это:

System.Collections.Generic.Dictionary`2[System.String,System.Object] 
System.Object[] 

И я не могу взаимодействовать с $ configObj как объект и получить его свойства. На самом деле, я не могу понять, как получить от него какую-либо информацию. Когда я печатаю объект, вывод выглядит следующим образом:

AC Version  Location                                               
--- -------  --------                                               
True v2.0.50727   C:\Windows\assembly\GAC_MSIL\System.Web.Extensions\3.5.0.0__31bf3856ad364e35\System.Web.Extensions.dll                        

Key : DownloadURL 
Value : https://example.com 

Key : dir 
Value : 

Когда я ожидаю, что это выглядит следующим образом:

Key                           Value                          
---                           -----                          
DownloadURL                         https://example.com   
dir 

Есть ли способ обойти эту проблему и получить тот же объект обратно из моего ConvertFrom -Json как существует внутри моего метода?

Спасибо заранее,

Энди

+0

'[недействительных] [System.Reflection.Assembly] :: LoadWithPartialName (" System.Web.Extensions ")' или 'Add-Type -AssemblyName System.Web.Extensions' – PetSerAl

+0

Wow, awesome. Это исправило это! Мне даже не приходило в голову, что LoadWithPartialName возвращает значение, полученное PowerShell. Ты спасатель! И быстро! –

+0

@PetSerAl из любопытства, почему вы ответили на вопрос с комментарием? – Swoogan

ответ

1

Результат каждого оператора, за исключением присвоения и увеличения/уменьшения, рассматривается как часть вашего возвращения функции. Вам не нужно использовать оператор return, чтобы вернуть что-то из функции. Таким образом, ваша функция фактически возвращает два объекта: загружен Assembly объект из LoadWithPartialName метод и словарь от $obj переменная. Когда вы назначаете несколько результатов функции переменной, PowerShell должен упаковывать результаты в массив. Как вы на самом деле не нужен Assembly объекта, вы можете отбрасывать результат из LoadWithPartialName метода [void]:

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions"‌​) 

Также LoadWithPartialName метода Obsolete и вы не должны использовать его на всех. Для загрузки сборки можно использовать Add-Type Строить в командлет:

Add-Type -AssemblyName System.Web.Extensions 

Как не использовать именованные блоки в вашей функции, весь код считается end блок, таким образом, вы только процесс ввода последний трубопровод в функции , Вы должны использовать process блок для обработки каждого трубопровод вводимого объекта:

process{ 
    $ser.DeserializeObject($json) 
} 

Когда оператор возврата коллекции, чем PowerShell перечислить эту коллекцию и писать элемент каждой отдельной коллекции, вместо коллекции в качестве отдельного элемента. Поэтому, если ваш JSON содержит массив на верхнем уровне, вы будете возвращать элементы массива вместо самого массива, как это делает встроенный ConvertFrom-Json.Вы можете использовать унарный оператор массива, чтобы предотвратить перечисление возвращенного массива:

,$ser.DeserializeObject($json) 

The всего:

function ConvertFrom-Json { 
    param(
     [Parameter(ValueFromPipeline=$true)] 
     [string]$json 
    ) 
    begin { 
     Add-Type -AssemblyName System.Web.Extensions 
     $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer 
    } 
    process { 
     ,$ser.DeserializeObject($json) 
    } 
}