1

我正在尝试编写一个使用 VMWare 的 vcloud REST API 添加 NIC 的 powershell cmdlet(VMWare 自己的 powerCLI 似乎不允许这样做)。为了做到这一点,我需要使用这个 XML:

<?xml version="1.0" encoding="UTF-8"?><vcloud:RasdItemsList
    xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
    xmlns:vcloud="http://www.vmware.com/vcloud/v1.5"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    href="https://vcloud.example.com/api/vApp/vm-89c84bd6-c6f2-4e4c-8a7d-c44a3489e2e4/virtualHardwareSection/networkCards"
    type="application/vnd.vmware.vcloud.rasdItemsList+xml">
    <vcloud:Link
        href="https://vcloud.example.com/api/vApp/vm-89c84bd6-c6f2-4e4c-8a7d-c44a3489e2e4/virtualHardwareSection/networkCards"
        rel="edit"
        type="application/vnd.vmware.vcloud.rasdItemsList+xml"/>
</vcloud:RasdItemsList>

并在最后一个 vcloud:Link 下方添加以下元素。

    <ovf:Item>
        <rasd:Address></rasd:Address>
        <rasd:AddressOnParent>0</rasd:AddressOnParent>
        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
        <rasd:Connection
            vcloud:ipAddressingMode="none"
            vcloud:primaryNetworkConnection="true">VM Network</rasd:Connection>
        <rasd:Description>E1000 ethernet adapter on "VM Network"</rasd:Description>
        <rasd:ElementName>Network adapter 0</rasd:ElementName>
        <rasd:InstanceID>1</rasd:InstanceID>
        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
        <rasd:ResourceType>10</rasd:ResourceType>
    </ovf:Item>

现在,我将原始 XML 作为 $xmlDoc 放入 PS 中,并且我尝试了以下代码:

$xmlElt = $xmlDoc.CreateElement("ovf:Item")
$xmlSubElt = $xmlDoc.CreateElement("rasd:Address")
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:AddressOnParent")
$xmlSubText = $xmlDoc.CreateTextNode("0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:AutomaticAllocation")
$xmlSubText = $xmlDoc.CreateTextNode("false")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:Connection")
$xmlSubText = $xmlDoc.CreateTextNode("none")
$xmlSubElt.AppendChild($xmlSubText)
$xmlAtt = $xmlDoc.CreateAttribute("vcloud:primaryNetworkConnection")
$xmlAtt.Value = "True"
$xmlSubElt.Attributes.Append($xmlAtt)
$xmlAtt = $xmlDoc.CreateAttribute("vcloud:ipAddressingMode")
$xmlAtt.Value = "NONE"
$xmlSubElt.Attributes.Append($xmlAtt)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:Description")
$xmlSubText = $xmlDoc.CreateTextNode("Network Adapter 0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ElementName")
$xmlSubText = $xmlDoc.CreateTextNode("Network Adapter 0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:InstanceID")
$xmlSubText = $xmlDoc.CreateTextNode("0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ResourceSubType")
$xmlSubText = $xmlDoc.CreateTextNode("E1000")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ResourceType")
$xmlSubText = $xmlDoc.CreateTextNode("10")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlDoc.LastChild.AppendChild($xmlElt);

这是创建的 XML 的相关位:

<Item>
  <Address />
  <AddressOnParent>0</AddressOnParent>
  <AutomaticAllocation>false</AutomaticAllocation>
  <Connection primaryNetworkConnection="True" ipAddressingMode="NONE">none</Connection>
  <Description>Network Adapter 0</Description>
  <ElementName>Network Adapter 0</ElementName>
  <InstanceID>0</InstanceID>
  <ResourceSubType>E1000</ResourceSubType>
  <ResourceType>10</ResourceType>
</Item>

如您所见,它大部分都有效,但不幸的是,它似乎正在删除 XML 命名空间前缀。它可能仍然有效,但我真的很想匹配格式。我对 XML 和 Powershell 交互还很陌生,所以我的问题是:

  1. 如何让它输出命名空间?
  2. 有没有一种更简单的方法可以手动创建我只是愚蠢地忽略的每个元素?
4

2 回答 2

4

解决了我自己的问题。我需要将命名空间从“rasdItemsList”xpath 加载到 System.Xml.XmlNamespaceManager 中,然后在创建元素时查找每个的 URI。

$nsm = New-Object System.Xml.XmlNamespaceManager($xmldoc.nametable)
$nsm.addnamespace("xsi", $xmldoc.rasdItemsList.GetNamespaceOfPrefix("xsi"))
$nsm.addnamespace("rasd", $xmldoc.rasdItemsList.GetNamespaceOfPrefix("rasd"))
$nsm.addnamespace("vcloud", $xmldoc.rasdItemsList.GetNamespaceOfPrefix("vcloud"))

$xmlElt = $xmlDoc.CreateElement("vcloud:Item", $nsm.LookupNamespace("vcloud"))
$xmlSubElt = $xmlDoc.CreateElement("rasd:Address", $nsm.LookupNamespace("rasd"))
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:AddressOnParent", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:AutomaticAllocation", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("false")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:Connection", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("none")
$xmlSubElt.AppendChild($xmlSubText)
$xmlAtt = $xmlDoc.CreateAttribute("vcloud:primaryNetworkConnection", $nsm.LookupNamespace("vcloud"))
$xmlAtt.Value = "True"
$xmlSubElt.Attributes.Append($xmlAtt)
$xmlAtt = $xmlDoc.CreateAttribute("vcloud:ipAddressingMode", $nsm.LookupNamespace("vcloud"))
$xmlAtt.Value = "NONE"
$xmlSubElt.Attributes.Append($xmlAtt)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:Description", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("Network Adapter 0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ElementName", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("Network Adapter 0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:InstanceID", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("0")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ResourceSubType", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("E1000")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlSubElt = $xmlDoc.CreateElement("rasd:ResourceType", $nsm.LookupNamespace("rasd"))
$xmlSubText = $xmlDoc.CreateTextNode("10")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
$xmlDoc.LastChild.AppendChild($xmlElt);
于 2014-04-25T15:05:58.287 回答
0

为什么不使用 PowerCLI?

New-NetworkAdapter -VM $vm -NetworkName "VM Network" -MacAddress  'aa:bb:cc:dd:ee:ff' -WakeOnLan -StartConnected
于 2014-04-25T09:14:15.030 回答