PowerShell将数据转储到xml文件中,然后稍后读取并将其转换为原始对象

时间:2018-09-06 15:38:22

标签: xml powershell

我正在这里进行一个项目,而我陷入了一件事情。 该项目是针对客户环境的评估过程的自动化。

这个想法是在客户环境上运行一个脚本,该脚本将从客户环境中检索许多信息,然后将其转储到xml文件中,然后稍后使用另一个脚本,读取转储的xml文件并在其中转换数据到PowerShell对象以对此数据执行分析。

检索到的数据应该以一种方式进行组织,所以我要做的是获取所有信息和数据,并将它们添加到PSCustomeObject / HashTable中,然后将其转换为xml,然后将其保存到所需的路径。

要整理我在PSCustomObject / HashTable中检索到的数据,实际上我有一个嵌套的PSCustomObject / HashTable,这使其变得更加复杂。

将要检索的数据具有不同的类型,其中一些实际上是一个csv文件,其中一些是字符串,其他是系统对象。

下面是我正在处理代码的示例。

#Get NSX Controller Config From Managing NSX Manager.
$ControllerConfig = $ContConfig

#Get NSx Controller VM vSphere Info.
$ControllerVmInfo = Get-VM -Server $vCenterServerHostingWorkingNsxControllers | Where-Object {$_.ExtensionData.moref.value -Eq $ContConfig.virtualMachineInfo.objectId}
$ControllerESXi = Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-VMHost
$ControllerCluster = Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Cluster
$ControllerDataStore = Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Datastore
$ControllerSnapShot = Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Snapshot
$ControllerClusterResources = Get-ClusterInfo -ReqVIServer $vCenterServerHostingWorkingNsxControllers -ReqCluster $ControllerCluster.Name
$ControllerVMCpuUsagePercent = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Realtime -Stat cpu.usage.average | Sort-Object Timestamp -Descending | Select-Object -First 1).Value
$ControllerVMMemUsagePercent = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Realtime -Stat mem.usage.average | Sort-Object Timestamp -Descending | Select-Object -First 1).Value
$ControllerVMUsedDiskSpace = [math]::Round(((Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name).UsedSpaceGB | Measure-Object -Sum).sum)
$ControllerCpuHistoricUsage = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Stat cpu.usage.average)
$ControllerMemoryHistoricUsage = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Stat mem.usage.average)
$ControllerVMDiskReadLatency = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Realtime -Stat virtualdisk.totalreadlatency.average)
$ControllerVMDiskWritLatency = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Realtime -Stat virtualdisk.totalwritelatency.average)
$ControllerVMMaxTotalLatency = (Get-VM -Server $vCenterServerHostingWorkingNsxControllers -Name $ControllerVmInfo.Name | Get-Stat -Stat disk.maxTotalLatency.latest)

#Get NSX Controller SSH Output.
$ControllerSSHPassword = ConvertTo-SecureString $EnvironmentInfo.NsxControllersPassword -AsPlainText -Force
$ControllerCredentials = New-Object System.Management.Automation.PSCredential ("admin", $ControllerSSHPassword)
$ControllerSSHSession = New-SSHSession -ComputerName $ContConfig.ipAddress -Credential $ControllerCredentials -AcceptKey
$ControllerClusterStatus = (Invoke-SSHCommand -SSHSession $ControllerSSHSession -Command "show control-cluster status").Output
$ControllerClusterStartupNodes = (Invoke-SSHCommand -SSHSession $ControllerSSHSession -Command "show control-cluster startup-nodes").Output
$ControllerDiskStatus = (Invoke-SSHCommand -SSHSession $ControllerSSHSession -Command "show status").Output | Where-Object {$_ -Match "\S+\s+\d+\s+\d+\s+\d+\s+(\d+)%\s(\/\S*)$"}
$ControllerUpTime = (Invoke-SSHCommand -SSHSession $ControllerSSHSession -Command "show status").Output | Where-Object {$_ -Match "Uptime"}
Remove-SSHSession -SSHSession $ControllerSSHSession | Out-Null  

#Add all retrived data in a Hash Table
$NsxControllerDataRetrival = New-Object PSObject -Property @{
    ControllerId = $ControllerConfig.id
    ControllerConfig = $ControllerConfig
    ControllervSphereInfo = New-Object PSObject -Property @{
        ControllerVmInfo = $ControllerVmInfo
        ControllerESXi = $ControllerESXi
        ControllerCluster = $ControllerCluster
        ControllerDataStore = $ControllerDataStore
        ControllerSnapShot = $ControllerSnapShot
        ControllerClusterResources = $ControllerClusterResources
        ControllerVMCpuUsagePercent = $ControllerVMCpuUsagePercent
        ControllerVMMemUsagePercent = $ControllerVMMemUsagePercent
        ControllerVMUsedDiskSpace = $ControllerVMUsedDiskSpace
        ControllerCpuHistoricUsage = $ControllerCpuHistoricUsage
        ControllerMemoryHistoricUsage = $ControllerMemoryHistoricUsage
        ControllerVMDiskReadLatency = $ControllerVMDiskReadLatency
        ControllerVMDiskWritLatency = $ControllerVMDiskWritLatency
        ControllerVMMaxTotalLatency = $ControllerVMMaxTotalLatency
    }
    ControllerSshInfo = New-Object PSObject -Property @{
        ControllerClusterStatus = $ControllerClusterStatus
        ControllerClusterStartupNodes = $ControllerClusterStartupNodes
        ControllerDiskStatus = $ControllerDiskStatus
        ControllerUpTime = $ControllerUpTime
    }
}

 ($NsxControllerDataRetrival | ConvertTo-Xml).Save($ResultFilePath + "NSX-Controller-Data-" + $EnvironmentInfo.NsxManagerFqdn + ".xml")

实际上,如果我使用PSObject并将其转换为XML,则会由于以下错误而出错,因为我需要添加深度,但是很难确定所需的深度,请记住,上面的操作会重复多次用不同的数据来提取不同的时间。

ConvertTo-Xml : Unexpected end of file has occurred. The following elements are not closed: Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Object, 
Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Property, Object, Property, Property, Property, Property, Property, Property, Property, Property, 
Property, Property, Property, Property, Property, Property, Property, Object, Objects. Line 6, position 10817.
At \\tsclient\RDP-Shared-Folder\New-Multi-Site-Tool\Sub-Scripts\CGS-AT-Gather-NSX.ps1:1065 char:29
+                         ($NsxControllerDataRetrival | ConvertTo-Xml).Save($Re ...
+                                                       ~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [ConvertTo-Xml], XmlException
    + FullyQualifiedErrorId : System.Xml.XmlException,Microsoft.PowerShell.Commands.ConvertToXmlCommand

如果使用HashTable添加所有数据,然后将它们转储到XML文件中,则XML文件格式非常困难,并且在阅读时我无法弄清楚点符号或XPath查询来提取属性/元素稍后介绍xml文件。 xml文件的示例如下:

<?xml version="1.0" encoding="utf-8"?>
<Objects>
  <Object Type="System.Collections.Hashtable">
    <Property Name="Key" Type="System.String">ControllerSshInfo</Property>
    <Property Name="Value" Type="System.Collections.Hashtable">
      <Property Name="Key" Type="System.String">ControllerClusterStatus</Property>
      <Property Name="Key" Type="System.String">ControllerUpTime</Property>
      <Property Name="Value" Type="System.String">Uptime: 106 days 16 hours 43 minutes 54 seconds </Property>
      <Property Name="Key" Type="System.String">ControllerClusterStartupNodes</Property>
      <Property Name="Value" Type="System.String[]">
        <Property Type="System.String">192.168.4.61, 192.168.4.62, 192.168.4.63</Property>
      </Property>
      <Property Name="Key" Type="System.String">ControllerDiskStatus</Property>
      <Property Name="Value" Type="System.Object[]">
        <Property Type="System.String">devtmpfs         2009560       0   2009560   0% /dev</Property>
        <Property Type="System.String">/dev/sda2        3997376 2266940   1504340  61% /</Property>
        <Property Type="System.String">/dev/sda1         999320   40952    889556   5% /boot</Property>
        <Property Type="System.String">/dev/sda6        1998672    3092   1874340   1% /config</Property>
        <Property Type="System.String">/dev/sda3        3997376    8184   3763096   1% /os_bak</Property>
        <Property Type="System.String">/dev/sda5        5029504 1795892   2955084  38% /var/log</Property>
        <Property Type="System.String">/dev/sda7        5029504   10236   4740740   1% /image</Property>
        <Property Type="System.String">/dev/sda4        3997376  142004   3629276   4% /var/cloudnet/data</Property>
      </Property>
    </Property>

如果能帮助我以更简单的格式将数据转储到xml文件中,或者甚至将我指向可以执行上述操作的其他路径,我将不胜感激。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您是否尝试过Export-CliXml和Import-CliXml?这是为了将PS对象另存为XML并返回。

https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Export-Clixml?view=powershell-5.1

这将获取dirinfo个对象,进行导出和导入,然后转储第一个对象。

Export-Clixml -InputObject $x -path c:\temp\test.xml
$listing = Import-Clixml -Path c:\temp\test.xml
$listing[0] | gm

输出

TypeName: Deserialized.System.IO.DirectoryInfo
....