Метод Tostring() пользовательских объектов PowerShell и export-clixml

1. У меня есть эти XML- файлы, которые содержат данные из сторонних командлетов, экспортированных через export-clixml в качестве резервной копии.
Они выглядят так (только с большим количеством объектов):

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>Deserialized.System.Object</T>
    </TN>
    <ToString>OldDomain\UserName</ToString>
    <Props>
      <S N="AdministratorName">OldDomain\UserName</S>
      <Obj N="AdministratorType" RefId="1">
        <TN RefId="1">
          <T>Deserialized.System.Enum</T>
          <T>Deserialized.System.ValueType</T>
          <T>Deserialized.System.Object</T>
        </TN>
        <ToString>Full</ToString>
        <I32>1</I32>
      </Obj>
    </Props>
  </Obj>
</Objs>

2 Обычно я импортирую их с помощью import-clixml и снова отправляю их в эти сторонние командлеты для воссоздания данных. Работает отлично.

3 Теперь мне нужно заменить *OldDomain* на * NewDomain *, прежде чем их использовать.
Поэтому я импортирую данные и затем заменяю значения:

foreach ($prop in $subobj.psobject.properties) {         
    If ($prop.Value -match $oldval) {
        $prop.Value = ($prop.Value) -replace ($oldval,$newval) 
    }    
}

Это работает в теории, и если я смотрю на объекты после замены, они выглядят хорошо.

4 Но после передачи данных в командлеты я продолжал получать сообщения об отсутствии " OldDomain". "OldDomain" даже не должен быть в объекте больше...
Это заняло у меня какое-то время, но потом я узнал, откуда взялся "OldDomain". Это становится ясно, когда я снова экспортирую объект после замены значений:

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>Deserialized.System.Object</T>
    </TN>
    <ToString>OldDomain\UserName</ToString>                 <<<<<<<<<<<<
    <Props>
      <S N="AdministratorName">NewDomain\UserName</S>       <<<<<<<<<<<<
      <Obj N="AdministratorType" RefId="1">
        <TN RefId="1">
          <T>Deserialized.System.Enum</T>
          <T>Deserialized.System.ValueType</T>
          <T>Deserialized.System.Object</T>
        </TN>
        <ToString>Full</ToString>
        <I32>1</I32>
      </Obj>
    </Props>
  </Obj>
</Objs>


Значение находится в tostring() - Метод. Но почему в методе tostring() есть статическое значение? Это должен быть МЕТОД.
И по какой-то причине командлеты используют это значение внутри метода tostring().

5. Помимо причины, я попытался заменить значение внутри tostring(). Но это метод, поэтому единственный способ переопределить это, я знаю, это добавить новый метод с тем же именем:

$subobj | Add-Member -MemberType scriptmethod -Name tostring {$replVal} -Force

Это сработало только наполовину, потому что оно не заменяло значение tostring() содержимым переменной $replVal (которое является " NewDomain"), но самой переменной $replVal.
Так что $subobj.tostring() - это то, что у вас есть в $ replval, когда вы вызываете метод tostring(), а не фиксированное значение.
Так что мне нужно, чтобы метод script работал как noteproperty и позволял мне назначать фиксированное значение, например tostring() = $replvalue


Так что я не понимаю.

А) Почему функция tostring() находится в файле export-clixml?

Б) Почему в хранимом объекте есть фиксированное значение для метода (tostring())?

В) и самое важное: как заменить фиксированное значение внутри tostring()?


Спасибо и наилучшими пожеланиями, FFM



1 ответ

Решение

A) Я не уверен, но для объекта имеет смысл иметь определение метода в экспорте.

Б) Если моя причина для А) верна (и, вероятно, это не так), то эта статичность была бы ошибкой в ​​реализации записи определения метода из файла. В принципе, я думаю, что вы правы, и что это не должно быть так

C)

$subobj | Add-Member -MemberType ScriptMethod -Name ToString -Value {$this.AdministatorName} -Force

Не уверен, правильно ли я понял это свойство (AdministatorName). Но $this В определении вашего сценария метод относится к объекту, поэтому вы можете программно получить его таким образом.

Изменить после обсуждения:

$replVal = 'A value'
$block = [ScriptBlock]::Create("'{0}'" -f ($replVal -replace "'","``'"))
$subobj | Add-Member -MemberType ScriptMethod -Name ToString -Value $block -Force

Это позволит вам изменить $replVal без изменения значения ToString(),

Другие вопросы по тегам