Проблемы с типом десериализованного объекта, особенно с классами Powershell 5 и Import-CliXml

У меня возникают проблемы с классами и типами объектов Powershell 5 при повторном импорте десериализованных объектов с помощью команды Import-CliXml.

У меня есть объект типа Computer, и я хочу сохранить его как xml, а затем повторно импортировать его при следующем запуске скрипта.

class Computer 
{
    $Private:hostname
    $Private:ipAddress

    Computer([String] $hostname, [String] $ipAddress)
    {
        $this.hostname = $hostname
        $this.ipAddress = $ipAddress
    }
    static [Computer] reserialize([PSObject] $deserializedComputer)
    {
        return [Computer]::new($deserializedComputer.hostname, $deserializedComputer.ipAddress)
    }
}

Я экспортирую и импортирую объект, используя следующее:

$computer = [Computer]::new("test-machine", "192.168.1.2")
$computer | Export-CliXml C:\Powershell\exportTest.xml
$deserializedComputer = Import-CliXml C:\Powershell\exportTest.xml

Я понимаю, что когда этот объект повторно импортируется, он десериализуется и в основном представляет собой просто контейнер данных (типа [Deserialized.Computer]). Я пытаюсь выяснить, как проверить тип этого объекта, прежде чем я попытаюсь повторно сериализовать его, используя мой метод повторной сериализации.

Например, если я попытаюсь применить $deserializedComputer, он скажет мне, что:

Cannot convert value "Computer" to type "Computer". Error: "Cannot convert the "Computer" value of type "Deserialized.Computer" to type 
"Computer"."

Я понимаю, почему это нельзя привести, я просто использую сообщение об ошибке, чтобы указать, что объекту известно, что он имеет тип [Deserialized.Computer]

Я не могу найти ничего, возвращаемого из $deserializedComputer.getMember(), который указывает, что он имеет тип [Deserialized.Computer], единственная информация, которую я могу найти, это то, что он имеет тип [PSObject], как я могу проверить, что этот объект действительно типа [Десериализованный.Компьютер]?

Я должен добавить, что тип [Deserialized.Computer] не существует во время выполнения, поэтому я не могу использовать его непосредственно в своем коде, иначе я бы просто использовал:

$deserializedComputer.getType() -eq [Deserialized.Computer]

person Dan Hampshire    schedule 23.01.2017    source источник
comment
$deserializedComputer — это [psobject] со значением листа PSTypeNames, равным Deserialized.Computer. См. $deserializedComputer.psobject.TypeNames   -  person Mathias R. Jessen    schedule 23.01.2017


Ответы (1)


Используйте (Подсказка: gm — это псевдоним для Get-Member)

$type = $deserializedComputer | gm | Select -Property TypeName -First 1

тогда вы сможете получить доступ к значению, например

$type.TypeName

Вы также можете ввести проверку, чтобы убедиться, что это компьютер, используя

$deserializedComputer.ToString()

Или, если вы хотите использовать другой способ

[type]$deserializedComputer.ToString()

Изменить:

Вы можете проверить это, используя следующие

# you can also use $deserializedComputer.ToString() -eq [Computer].ToString()
if ([type]$deserializedComputer.ToString() -eq [Computer])
{

}

Ваш полный класс будет выглядеть примерно так:

class Computer 
{
    $Private:hostname
    $Private:ipAddress

    Computer(){}

    Computer([String] $hostname, [String] $ipAddress)
    {
        $this.hostname = $hostname
        $this.ipAddress = $ipAddress
    }
    static [Computer] reserialize([PSObject] $deserializedComputer)
    {
    # you can also use $deserializedComputer.ToString() -eq [Computer].ToString()
    if ([type]$deserializedComputer.ToString() -eq [Computer])
    {
       return [Computer]::new($deserializedComputer.hostname, $deserializedComputer.ipAddress)
    }
    return [Computer]::new()
    }
}

И экспорт/импорт

$filePath = "C:\Powershell\exportTest.xml"

$computer = [Computer]::new("test-machine", "192.168.1.2")
$computer | Export-CliXml $filePath
$deserializedComputer = Import-CliXml $filePath

И метод повторной сериализации

[Computer]::reserialize($deserializedComputer)
person Patrick Mcvay    schedule 26.01.2017