Прошу помочь с выгрузкой пользователей из xml средствами powershell

Есть xml файл, в котором есть 2 узла (работники и подразделения). Задача в том, чтобы выгрузить конкретные поля из xml в csv. Из узла работники все поля успешно прошел, кроме подразделений так, как там хранятся ссылки на GUID из узла подразделения. Как мне сделать так, чтобы напротив работника выгружать соответствующие им подразделения? https://drive.google.com/drive/folders/11e8wtadRPiuFUWlwZXtVinIGfgol-ox0?usp=sharing

$path_xml = "D:\exp2moodle\company.xml"
$path_xml_department = "КоммерческаяИнформация/Классификатор/Подразделения/Подразделение"
$path_xml_worker = "КоммерческаяИнформация/ОрганизационнаяСтруктура/Работники/Работник"
$file.load($path_xml)
$xml_department = $file.SelectNodes($path_xml_department)
$xml_peoples= $file.SelectNodes($path_xml_worker)
$output = @()
$test = @()
foreach ($person in $xml_peoples) {
   #$IPphone = ($person.Контакты.Контакт | where {$_.Тип -match "IP"}).Значение
    $MailAddress = ($person.Контакты.Контакт | where {$_.Тип -match "Почта"}).Значение
    $SecondName = $person.Фамилия
    $Name = $person.Имя 
    $LastName = $person.Отчество
   #$FIO = $person.Наименование
    $Function = $person.Должность
    $Status = $person.ИсторияСостояний.Состояние | where {$_.Значение -eq "Уволен"}
    if (!$Status){
    $output += [PSCustomObject]@{
       #Наименование = $FIO 
        Фамилия = $SecondName
        Имя_Отчество = [String]::Concat($Name," ",$LastName)
        Должность = $Function
       #Телефон = $IPphone -replace "\D", ""
        Почта = $MailAddress
        }  
    }
}

<#foreach ($dept in $xml_department)
{
    $Подразделения = $dept.Наименование

    $test += [PSCustomObject]@{
        Подразделение = $Подразделения
    } 
}#>

$output | Export-csv -Path "D:\Unloading\employees.csv" -Encoding Default -Delimiter ";" -NoTypeInformation```


  [1]: https://drive.google.com/drive/folders/11e8wtadRPiuFUWlwZXtVinIGfgol-ox0?usp=sharing

Ответы (1 шт):

Автор решения: Hardoman

Используйте Select-Xml, чтобы выбирать нужные вам объекты из XML:

Прочитать всю структуру внутри Подразделения/Подразделение:

select-xml -Path "C:\temp\test.xml" -XPath "Подразделения/Подразделение" | foreach { $_.Node.InnerXML }

К полученным элементам можно обращаться, как к элементам массива типа System.String (не имеют дочерних свойств). В таком случае для каждого отдельного подразделения во вложенном цикле нужно смотреть дочерние элементы.

Прочитать нужный вам атрибут:

$users = select-xml -Path "C:\temp\test.xml" -XPath "Подразделения/Подразделение/Подразделения/Подразделение" | foreach { $_.Node.Ид }

$departments = select-xml -Path "C:\temp\test.xml" -XPath "Подразделения/Подразделение/Подразделения/Подразделение" | foreach { $_.Node.Наименование }

Далее можно сопоставить два массива пользователей и отделов.

Примечание: рекомендуемым способом работы с XML является кастинг его в объект типа XML, который будет автоматически иметь в качестве свойств параметры всех элементов XML файла, однако это не работает с кириллицей, поэтому здесь это не применимо:

[xml]$xmlElm = Get-Content -Path C:\Work\computers-elm.xml
→ Ссылка