Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описывается универсальный соединитель CSV. Статья относится к следующим продуктам:
Для MIM 2016 Коннектор доступен для загрузки из Центра загрузки Майкрософт.
Заметка
Служба подготовки Azure AD теперь предоставляет упрощенное решение на основе агента для подготовки пользователей в CSV-файлы без полного развертывания синхронизации MIM. Мы рекомендуем оценить, соответствует ли он вашим потребностям. Дополнительные сведения.
Подготовка примеров CSV-файлов
На сервере, на котором запущен сервер синхронизации MIM, создайте папку C:\GCSV и скопируйте в него следующие CSV-файлы, найденные в приложении A — примеры CSV-файлов. Обязательно предоставьте учетной записи службы синхронизации MIM разрешения на чтение и запись в эту папку.
Скопируйте следующий CSV-файл в папку C:\GCSV\SCRIPTS:
- Пример CSV-файла пользователей (Users.csv)
- Пример CSV-файла групп (Groups.csv)
- Пример CSV-файла участников (Members.csv)
Заметка
В этом руководстве предполагается, что CSV-файлы находятся на сервере синхронизации MIM: C:\GCSV и сохраняются с помощью указанных имен файлов. Если вы устанавливаете их в другом месте или переименовываете эти файлы, необходимо внести соответствующие изменения в течение всего руководства.
Подготовка примеров скриптов PowerShell
На сервере, на котором запущен сервер синхронизации MIM, создайте папку C:\GCSV\SCRIPTS и скопируйте примеры скриптов PowerShell, расположенные в приложении B . Примеры файлов PowerShell в него. Убедитесь, что учетная запись службы синхронизации MIM имеет соответствующие разрешения PowerShell ExecutePolicy для выполнения скриптов.
Скопируйте следующие скрипты PowerShell в папку C:\GCSV\SCRIPTS:
- Пример скрипта предварительного импорта (Pre-Import.ps1)
- Пример скрипта после импорта (Post-Import.ps1)
- Пример скрипта предварительного экспорта (Pre-Export.ps1)
- Пример скрипта после экспорта (Post-Export.ps1)
Заметка
В этом руководстве предполагается, что CSV-файлы находятся в следующем пути на сервере синхронизации MIM: C:\GCSV\SCRIPTS. Если установить их в другом месте, необходимо вносить соответствующие изменения в течение всего руководства.
Важный
Для учетной записи службы синхронизации MIM требуются соответствующие разрешения PowerShell ExecutePolicy, на сервере синхронизации MIM, чтобы выполнить примеры скриптов PowerShell.
Создать новый соединитель
В следующем списке представлен общий обзор шагов, описанных в этом руководстве. Для выполнения этих задач необходимо использовать учетную запись с ролью администратора синхронизации MIM.
- Откройте окно создания нового агента управления (MA) из диспетчера синхронизации MIM.
- Выберите универсальный соединитель CSV в качестве типа соединителя.
- Укажите путь к файлу и имя CSV-файла, который необходимо импортировать или экспортировать.
- Укажите кодировку, разделитель значений, разделитель многозначных значений и квалификатор текста для CSV-файла.
- Выберите, следует ли использовать значения в первой строке в качестве полей заголовка или нет.
- Выберите типы объектов и атрибуты, которые нужно импортировать или экспортировать из CSV-файла.
- Настройте раздел, профиль выполнения и детали сопоставления для MA.
- Укажите пути и параметры скриптов для сценариев PowerShell, если таковые есть.
- Запустите MA для выполнения операций импорта, синхронизации или экспорта.
- Оцените результаты.
Начнем!
Чтобы создать универсальный соединитель CSV, в диспетчере синхронизации MIM выберите Агент управления и Создать. Выберите соединитель Generic CSV (Microsoft).
Укажите имя для соединителя (например, общий CSV) и нажмите кнопку Далее.
Связь
Страница подключения содержит пути к файлам, в которых соединитель может находить CSV-файлы пользователей, групп и участников групп.
На следующем рисунке показан пример страницы подключения:
Ниже приведен список значений, которые должны быть предоставлены для параметров на этой странице:
Имя параметра | Установка значения | Примечания |
---|---|---|
файлов пользователей | C:\GCSV\USERS.CSV | (Полный путь и используемое имя файла.) |
Файл групп | C:\GCSV\GROUPS.CSV | (Полный путь и используемое имя файла.) |
Файл членов | C:\GCSV\MEMBERS.CSV | (Полный указанный путь и имя файла.) |
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Возможности
На этой странице описываются возможности соединителя. Возможности соединителя GCSV исправлены и не могут быть изменены.
Ниже приведено изображение в качестве примера страницы возможности.
Подробное описание этих параметров возможностей см. в универсальном соединителе CSV— техническом руководстве.
После просмотра конфигураций нажмите кнопку Далее.
Схема 1 (конфигурации формата CSV-файла)
Соединитель Generic CSV (GCSV) использует три типа разделителей (или разделителей) для разделения и анализа полей CSV и их значений: разделители значений, многозначные разделителии квалификаторы текста. Более подробное объяснение этих типов разделителей можно найти в техническом справочнике — универсальный соединитель CSV.
Эта страница содержит параметры значения символов для этих разделителей и тип кодирования, который использовался для создания файла в формате CSV.
На следующем рисунке показан пример страницы схемы 1 (конфигурации формата CSV-файла).
Ниже приведен список отдельных конфигураций.
- использовать заголовки для обнаружения схем: если выбран этот параметр, соединитель будет игнорировать первую запись каждого CSV-файла в качестве записи данных и использовать ее в качестве записи заголовка (то есть имена каждого поля). Если этот параметр не выбран, соединитель предоставляет универсальное имя для каждого поля (например, Attribute1, Attribute2 и т. д.) и использует первую строку в качестве записи данных.
- разделитель значений: этот символ разделяет поля (то есть значения) записей CSV. Запятая (,) — это значение по умолчанию, но разрешен любой буквенно-цифровой символ, который можно распечатать.
- разделитель многозначных значений: этот тип разделителя используется для разделителя отдельных значений многозначной строки (например, прокси-адресов) или ссылочных атрибутов (например, подчиненных).) По умолчанию используется точка с запятой (;) но любой печатный буквенно-цифровой символ является допустимым.
- квалификатор текста: если строковое значение содержит символы, которые иначе будут интерпретированы как разделители (например, запятые), то требуется, чтобы CSV парсер правильно интерпретировал строку как одно поле. Двойные кавычки (") — это значение по умолчанию, но разрешен любой буквенно-цифровой символ, который можно распечатать.
- кодировка файла: этот параметр указывает кодировку, используемую в CSV-файлах, добавленных на вкладке "Подключение". Убедитесь, что он соответствует кодировке CSV-файлов.
Заметка
Если вы не уверены в типе кодирования CSV-файлов, попробуйте использовать тип кодирования по умолчанию Юникод. Юникод является общим стандартом, который поддерживает множество символов и знаков, что делает его хорошим вариантом для кодирования текстовых данных на большинстве языков и наборов символов.
Схема 2 (конфигурации идентификаторов и ссылочных полей)
Значение привязки — это уникальный идентификатор записи в CSV-файле. Он отличает одну запись от других. Соединитель GCSV также использует это значение для создания различающегося имени (DN), который однозначно идентифицирует объект пространства соединителя.
На этой странице параметры атрибута привязки настраиваются для каждого CSV-файла, перечисленных на странице подключения.
На следующем рисунке показан пример страницы схемы 2 (конфигурации полей идентификации и ссылок).
В следующей таблице приведены отдельные значения, которые должны быть назначены каждому из параметров на этой странице:
Имя параметра | Установка значения |
---|---|
поле ID записи пользователя | ИдентификаторСотрудника |
Поле идентификатора записи пользователя тип атрибута | строка |
Поле идентификатора записи группы | GroupID |
тип атрибута поля идентификатора записи группы | строка |
идентификатор родительской группы | ParentID |
идентификатор члена | MemberID |
тип объекта-члена | ObjectType |
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Схема 3 (конфигурации схемы пользовательских атрибутов файла)
Эта страница используется для назначения типа данных для каждого атрибута в схеме CSV-файла Users и может ли он иметь несколько значений.
Пример страницы схемы 3 (конфигурации схемы атрибутов файла пользователей) показан на изображении ниже.
В следующей таблице приведены отдельные значения, которые должны быть назначены каждому из параметров на этой странице:
Имя параметра | Установка значения | Примечания |
---|---|---|
тип атрибута DisplayName | строка | Примеры квалифицированных строк находятся в этом поле |
DisplayName является многозначным | false | -- |
тип атрибута AccountName | строка | -- |
Поле/переменная AccountName содержит несколько значений | ложь | -- |
тип атрибута "КодСтраны" | Целое число | -- |
CountryCode может иметь несколько значений | ложь | -- |
типа атрибута Manager | Справочник | Содержит значения привязанных атрибутов для записей пользователей назначенных им руководителей (например, E001) |
Диспетчер имеет многозначную | ложь | -- |
тип атрибута ProxyAddresses | строка | -- |
ProxyAddresses является многозначным | TRUE | Содержит примеры разделения многозначных строк |
Тип атрибута IsActive | булевые | -- |
IsActive имеет многозначные значения | ложь | -- |
типа атрибута ProfilePic | двоичный | -- |
Параметр ProfilePic содержит несколько значений | ложный | -- |
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Схема 4 (конфигурации схемы атрибутов файлов групп)
Эта страница используется для назначения типа данных для каждого атрибута в схеме CSV-файла групп и может ли он иметь несколько значений.
На следующем рисунке показан пример страницы Схемы 4 (Конфигурации схемы атрибутов файловых групп).
В следующей таблице приведены отдельные значения, которые должны быть назначены каждому из параметров на этой странице:
Имя параметра | Установка значения | Примечания |
---|---|---|
тип атрибута DisplayName | строка | -- |
DisplayName имеет многозначное значение | ложь | Предоставляет пример квалифицированных строковых значений. |
Тип атрибута Описание | строка | -- |
Описание является многозначным | ложный | -- |
тип атрибута владельца | Справочник | Предоставляет пример ссылочных значений. |
Владелец имеет множество значений | ложь | -- |
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Глобальные параметры (конфигурация скриптов PowerShell)
Эта страница позволяет настроить скрипты PowerShell, которые будут выполняться до и (или) после операций импорта и /или экспорта. Значение этих входных параметров предоставляет возможность выполнять широкий спектр действий по предварительной и последующей обработке записей пользователей и групп идентификации.
На следующем рисунке приведен пример страницы Глобальных параметров.
В следующей таблице приведены отдельные значения, которые должны быть назначены каждому из параметров на этой странице:
Имя параметра | Установленное значение | Примечания |
---|---|---|
предварительно импортируемый файл | C:\GCSV\SCRIPTS\PRE-IMPORT.CSV | Этот скрипт выполняется до полного импорта |
файл после импорта | C:\GCSV\SCRIPTS\POST-IMPORT.CSV | Этот скрипт выполняется после полного импорта |
предварительно экспортируемый файл | C:\GCSV\SCRIPTS\PRE-EXPORT.CSV- | Этот скрипт выполняется до полного экспорта или (разностного) экспорта |
Файл после экспорта | C:\GCSV\SCRIPTS\POST-EXPORT.CSV | Этот скрипт выполняется до полного экспорта или (разностного) экспорта |
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Выполнение скрипта PowerShell
Соединитель GCSV запускает каждый настроенный скрипт PowerShell в собственном сеансе и не обеспечивает поддержку передачи переменных между выполнением скриптов.
Кроме того, соединитель GCSV выполняет скрипт PowerShell внутри файлов, а не в качестве командлета. Это означает, что входные параметры нельзя передать в скрипты, добавив их в конец инструкций пути. Это приводит к сбою выполнения скрипта.
Важный
Соединитель GCSV не поддерживает использование входных параметров при выполнении скриптов PowerShell.
Если выполнение скрипта предварительного импорта или предварительного экспорта вызывает исключение, чтобы предотвратить импорт или экспорт неправильно обработанных записей пользователей или групп, соединитель GCSV остановит выполнение всего профиля выполнения.
Аналогичным образом, если во время операции после импорта или экспорта происходит исключение, это вызывает сбой в выполнении операции.
Ошибки, возникающие во время выполнения скрипта PowerShell, будут входить в журнал сервера синхронизации MIM *Event *Log.
Входной параметр PowerShell: "OperationType"
Хотя использование входных параметров не поддерживается, соединитель GCSV передает один входной параметр в выполнение каждого скрипта PowerShell: OperationType
.
Входная переменная OperationType
будет иметь значение Full или Delta для демонстрации типа операции (например, полный импорт, разностный импорт, полный экспорт, разностный экспорт), который выполняется с помощью скрипта. Это значение позволяет скриптам проверять, выполняются ли они в контексте полного или разностного импорта и экспорта и выполняют соответствующие задачи предварительной или последующей обработки.
Иерархия подготовки
Поскольку CSV-файлы не хранят информацию в иерархической структуре, универсальный соединитель CSV не поддерживает иерархические конфигурации.
На следующем рисунке показан пример страницы иерархии подготовки.
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Секции и иерархии
Универсальный соединитель CSV создает отдельное различающееся имя (DN) для каждого пользователя и группы в пространстве соединителя, следуя этому формату LDAP:
CN=[ANCHOR_VALUE],Object=User|Group,O=CSV
На следующем рисунке показан пример страницы разделов и иерархий.
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Типы объектов
Для универсального CSV-коннектора необходимо указать как минимум тип объекта User. Выбор типа объекта Group необязателен.
На следующем рисунке показан пример страницы типа объектов .
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Атрибуты
На этой странице отображается нормализованный список всех атрибутов во всех схемах выбранных типов объектов.
На следующем рисунке представлен пример страницы атрибутов .
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Заметка
Атрибуты привязки всегда требуются для правильной работы соединителя GCSV.
Якоря
Универсальный соединитель CSV не поддерживает использование сложных привязок или конфигураций атрибутов привязки, отличающихся от обозначения поля идентификатора привязки соответствующего объекта в CSV-файле. Поэтому поля выбора привязки заблокированы. Чтобы внести изменения в обозначение атрибута привязки, вернитесь на страницу схемы 2 (конфигурации идентификаторов и ссылочных полей).
На следующем рисунке показан пример страницы привязок .
После просмотра параметров по умолчанию на странице нажмите кнопку Далее.
Фильтры соединителей
Это руководство не будет использовать настройки фильтров соединителей. В этом разделе поддерживается непрерывность руководства.
На следующем изображении показан пример страницы фильтров соединителей .
После просмотра параметров по умолчанию на странице нажмите кнопку Далее.
Правила присоединения и проекции
В этом руководстве не используются конфигурации правил соединения и проекции. Этот раздел предназначен для обеспечения преемственности в руководстве.
На следующем рисунке показан пример страницы Правила присоединения и проекции.
После просмотра параметров по умолчанию на странице нажмите кнопку Далее.
Поток атрибутов
Это руководство не будет использовать конфигурации правил потока атрибутов. Этот раздел предназначен для обеспечения непрерывности в руководстве.
На следующем рисунке показан пример страницы потока атрибутов .
Убедившись, что параметры соответствуют значениям по умолчанию, нажмите кнопку Далее.
Депровизирование
В этом руководстве мы не будем изменять параметры удаления по умолчанию этого соединителя. Этот раздел предназначен для обеспечения непрерывности в руководстве.
На следующем изображении показан пример страницы снятия доступа.
Убедившись, что параметры соответствуют значениям по умолчанию, нажмите кнопку Далее.
Создание профиля выполнения полного импорта
Для импорта данных удостоверений пользователей и групп из записей CSV в объекты пространства соединителя требуется профиль полного запуска импорта.
Чтобы создать новый профиль полного запуска импорта, выполните следующие действия.
- Вернитесь к Менеджеру службы синхронизации.
- Выберите агент управления GCSV.
- Щелкните правой кнопкой мыши на нём и выберите Настроить профили запуска.
- Щелкните Новый Профиль.
Откроется окно "Настройка профиля запуска".
Назовите профиль запуска
На странице "Имя профиля" введите следующее имя: Полный импорт
На следующем рисунке показан пример страницы профиля.
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Указать тип
На странице "Настройка шага" выберите Тип: Полный импорт.
Фильтрация соединителей работает так же в соединителе GCSV, что и в любом другом соединителе ECMA.
На следующем рисунке показан пример страницы фильтра соединителя.
Убедившись, что параметры соответствуют указанным значениям, нажмите кнопку Далее.
Тип конфигурации агента управления
На странице "Тип конфигурации агента управления" убедитесь, что раздел O=CSV выбран.
Оставьте остальные параметры в значениях по умолчанию. Нажатие кнопки Готово создаст профиль запуска.
Проверка результатов
В этом разделе описаны шаги, необходимые для проверки результатов создания нового соединителя GCSV и импорта записей пользователей и групп из примера CSV-файлов.
Запуск полного импорта
После создания профиля запуска выполните следующие шаги, чтобы выполнить запуск нового профиля полного импорта:
- Вернитесь к Диспетчеру службы синхронизации.
- Выберите агент управления GCSV.
- Щелкните его правой кнопкой мыши и выберите запустить.
- Выберите полный импорт и нажмите кнопку ОК.
Проверка результатов операции полного импорта
Должно быть пять (5) добавлений на основе содержимого образцов CSV-файлов.
На следующем рисунке приведен пример результатов успешного импорта содержимого примеров CSV-файлов:
Изучение пространства соединителя GCSV
После создания профиля запуска выполните указанные ниже действия, чтобы выполнить запуск этого нового профиля полного импорта:
- Вернитесь к Менеджеру службы синхронизации.
- Выберите агент управления соединителя GCSV.
- Щелкните его правой кнопкой мыши и выберите место соединителя поиска.
- Оставьте область по умолчанию Поддерево и нажмите кнопку 'Поиск'.
На следующем рисунке показан пример окна пространства соединителя поиска .
Проверка объекта пользователя
Выберите один из объектов пользователя для проверки. Ниже приведен пример объекта пространства соединителя GCSV пользователя:
Проверка поля DisplayName показывает, как квалифицированная строка была правильно проанализирована.
Нажатие на кнопку в разделе ProxyAddresses показывает, что многозначная строка правильно проанализирована в отдельные значения:
Проверка Объекта Группы
Выбор одного из объектов группы для проверки. Следующее изображение является примером объекта пространства соединителя GCSV группы:
Щелкнув кнопку в элементе, вы получите информацию о том, как связывающие записи группового файла с файлом "Члены" были правильно загружены как члены:
Проверка журналов выполнения PowerShell
Примеры скриптов PowerShell, приведенные в этом руководстве, предназначены для добавления записи CSV в центральный журнал для демонстрации их успешного выполнения.
Расположение по умолчанию для этого журнала — C:\GCSV\PS_Run_Ledger.csv.
Открытие журнала показывает:
"DateTime","Stage","Name","Type","Description"
"3/17/2024 1:05:44 PM","Pre","Import","Full","The Pre-Import PowerShell script was executed successfully."
"3/17/2024 1:05:46 PM","Pre","Import","Full","The Post-Import PowerShell script was executed successfully."
Эти две записи указывают на то, что скрипты PowerShell для предварительного импорта и после импорта успешно выполнялись. Обратите внимание, что поле Type указывает, что эти скрипты PowerShell выполнялись во время полного импорта. Он получает эти значения из входного параметра OperationType PowerShell, который указывает, был ли скрипт запущен во время операции Full или Delta.
Приложение A. Пример CSV-файлов
В следующих разделах содержатся CSV-файлы, используемые в этом руководстве.
Пример CSV-файла пользователей
В конфигурации соединителя в этом руководстве предполагается имя файла USERS.CSV.
EmployeeID,DisplayName,AccountName,CountryCode,Manager,ProxyAddresses,IsActive,ProfilePic
E001,"Smith, John",JS001,1,,SMTP:john.smith@contoso.com;smtp:js001@contoso.com,True,SgBTADAAMAAxAA==
E002,"Doe, Jane",JD003,1,E001,SMTP:jane.doe@contoso.com;smtp:jd002@contoso.com,True,SgBEADAAMAAyAA==
E003,"Perez, Juan",JP003,1,E001,SMTP:juan.perez@contoso.com;smtp:jp003@contoso.com,False,SgBEADAAMAAyAA==
Пример CSV-файла групп
В конфигурации соединителя в этом руководстве предполагается имя файла GROUPS.CSV.
GroupID,DisplayName,Description,Owner
G001,Test Group (G001),"This group is for teams A, B, and C",E002
G002,Test Group (G002),"This group is for teams D, E, and F",E003
Пример CSV-файла участников
В конфигурации соединителя в этом руководстве предполагается имя файла MEMBERS.CSV.
ParentID,MemberID,ObjectType
G001,E001,USER
G001,E002,USER
G001,E003,USER
G002,E001,USER
G002,E002,USER
G002,E003,USER
G002,G001,GROUP
G003,E001,USER
G003,E002,USER
G003,E003,USER
G003,G001,GROUP
Приложение B. Примеры файлов PowerShell
В этом приложении содержится набор примеров скриптов PowerShell, используемых в этом руководстве. В следующих разделах подробно описаны некоторые соображения, на которые следует обратить внимание при выполнении.
Важный
любое использование команд write-host
в сценариях PowerShell приведет к сбою эксекта скрипта.
Пример скрипта PowerShell перед импортом
В конфигурации соединителя в этом руководстве предполагается, что имя файла PRE-IMPORT.PS1.
param ([string]$OperationType)
[string]$stage = "Pre"
[string]$operation = "Import"
[string]$filePath = "C:\GCSV\PS_Run_Ledger.csv"
# Create a new record
$record = [PSCustomObject]@{
"DateTime" = (Get-Date).ToString()
"Stage" = $stage
"Type" = $OperationType
"Name" = $operation
"Description" = "The $stage-$operation PowerShell script was successfully executed before a $OperationType-$operation."
}
$record | Export-Csv -Path $FilePath -NoTypeInformation -Append
Пример скрипта PowerShell после импорта
В конфигурации соединителя в этом руководстве предполагается, что имя файла POST-IMPORT.PS1.
param ([string]$OperationType)
[string]$stage = "Post"
[string]$operation = "Import"
[string]$filePath = "C:\GCSV\PS_Run_Ledger.csv"
# Create a new record
$record = [PSCustomObject]@{
"DateTime" = (Get-Date).ToString()
"Stage" = $stage
"Type" = $OperationType
"Name" = $operation
"Description" = "The $stage-$operation PowerShell script was successfully executed after a $OperationType-$operation."
}
$record | Export-Csv -Path $FilePath -NoTypeInformation -Append
Пример скрипта PowerShell перед экспортом
В конфигурации соединителя в данном руководстве предполагается, что имя файла PRE-EXPORT.PS1.
param ([string]$OperationType)
[string]$stage = "Pre"
[string]$operation = "Export"
[string]$filePath = "C:\GCSV\PS_Run_Ledger.csv"
# Create a new record
$record = [PSCustomObject]@{
"DateTime" = (Get-Date).ToString()
"Stage" = $stage
"Type" = $OperationType
"Name" = $operation
"Description" = "The $stage-$operation PowerShell script was successfully executed before a $OperationType-$operation."
}
$record | Export-Csv -Path $FilePath -NoTypeInformation -Append
Пример скрипта PowerShell после экспорта
В конфигурации соединителя в этом руководстве предполагается, что имя файла POST-EXPORT.PS1.
param ([string]$OperationType)
[string]$stage = "Post"
[string]$operation = "Export"
[string]$filePath = "C:\GCSV\PS_Run_Ledger.csv"
# Create a new record
$record = [PSCustomObject]@{
"DateTime" = (Get-Date).ToString()
"Stage" = $stage
"Type" = $OperationType
"Name" = $operation
"Description" = "The $stage-$operation PowerShell script was successfully executed after a $OperationType-$operation."
}
$record | Export-Csv -Path $FilePath -NoTypeInformation -Append