читать узлы XML с PowerShell - PullRequest
0 голосов
/ 28 мая 2018

Мне нужно выбрать все узлы ниже XML, где имя приложения = "secureApps" через powerShell.

Я использую приведенный ниже скрипт, но получаю ошибку.

$xml = [xml](Get-Content AppsConfiguration.xml)

foreach ($node in $xml.SelectNodes('/configurations/application/app')| Where 
$xml.configurations.application.name -eq "SecureApps" ) {

    $app_name = $node.app_name
    $app_path = $node.app_path

    # Create directory if not found
    if(-Not (Test-Path -Path $app_path)) {
    New-Item $app_path -Type Directory
    }

    # Convert directory to virtual directory
    New-WebVirtualDirectory -Site $secure_website_name.website_name -Name 
    $app_name -PhysicalPath $app_path

    $site_path = $secure_iis_site_location + $app_path
    ConvertTo-WebApplication -PSPath $site_path
}

Проблема заключается вв строке:

foreach ($node in $xml.SelectNodes('/configurations/application/app')| Where $xml.configurations.application.name -eq "SecureApps" ) {

XML, который я использую, выглядит следующим образом:

<?xml version="1.0"?>
<configurations>
<application name="SecureApps">
    <app id= "1">
        <app_name>atl</app_name>
        <app_path>D:\inetpub\secure\admin\atl</app_path>
    </app>
    <app id= "2">
        <app_name>corporate</app_name>
        <app_path>D:\inetpub\secure\admin\corporate</app_path>
    </app>
    <app id= "3">
        <app_name>f2l</app_name>
        <app_path>D:\inetpub\secure\admin\f2l</app_path>
    </app>
    <app id= "4">
        <app_name>GPModality</app_name>
        <app_path>D:\inetpub\secure\admin\GPModality</app_path>
    </app>
</application>
<application name="webApps">
    <app id= "1">
        <app_name>locations</app_name>
        <app_path>D:\inetpub\web\locations</app_path>
    </app>
</application>

1 Ответ

0 голосов
/ 28 мая 2018

У вас есть несколько проблем здесь.

Сначала ваше where условие не работает таким образом.Если вы используете where без блока сценария, у вас есть только три параметра: имя свойства из текущего объекта конвейера, оператор сравнения и фиксированное значение.

То, что вы используете в качестве первого параметра в условии where, является выражениемкоторый доставляет массив объектов, содержащий строки «SecureApps» и «webApps».

PowerShell ожидает строку, содержащую имя свойства в качестве первого позиционного параметра команды where, не может преобразовать массив в такую ​​строку итаким образом, происходит сбой с сообщением об ошибке.

Попытка исправить эту ошибку при сохранении простого синтаксиса вы должны найти свойство в объекте конвейера, с которым вы можете сравнить.

Ваш объект конвейераXML-узел "app", так что вы можете попробовать ParentNode.Name -eq ..., но точечные свойства также не работают с простым синтаксисом where, только с простыми именами свойств.

Итак, чтобы решить эту конкретную проблему, вы могли бывернуться к синтаксису блока скриптов, как это

... | Where { $_.ParentNode.Name -eq "SecureApps" }

Это неТем не менее, оптимально, потому что вы перебираете все узлы app и только потом проверяете родительский узел application.Лучше сначала отфильтровать по правильному узлу application, а затем пройти по всем подузлам приложения:

foreach ($node in ($xml.configurations.application | Where name -eq "SecureApps").app ) {

Существует также возможность, о которой упоминал Ансгар в своем комментарии, использовать тот факт, что .NETs SelectNodes использует выражения XPath, поэтому вы можете использовать условие XPath вместо механизма PowerShell:

foreach ($node in $xml.SelectNodes("/configurations/application[@name='SecureApps']/app")) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...