【问题标题】:ConvertTo-Json on VMWare objects doesn't workVMWare 对象上的 ConvertTo-Json 不起作用
【发布时间】:2016-06-24 12:04:32
【问题描述】:

在 powershell 中将 VM 对象转换为 json , ($json = ConvertTo-Json $vm -Compress)

我收到“已添加具有相同密钥的项目”异常。

PS SQLSERVER:\> C:\Users\admin\Desktop\inventory.ps1
ConvertTo-Json : An item with the same key has already been added.
At C:\Users\huradmin\Desktop\inventory.ps1:68 char:31
+     if($vm -ne $null){$json = ConvertTo-Json $vm -Compress;      insertToElasticSearc ...
+                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [ConvertTo-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertToJsonCommand

insertToElasticSearch : Cannot bind argument to parameter 'json' because it is null.
At C:\Users\admin\Desktop\inventory.ps1:68 char:89
+ ... icSearch -json $json -info:$true -Verbose:$true}
+                    ~~~~~
+ CategoryInfo          : InvalidData: (:) [insertToElasticSearch], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,insertToElasticSearch

getVMHosts 函数返回 VM 来宾列表。请在下面找到我的代码。

function getVMHosts{
Param(
[Parameter(Mandatory=$True,Position=1)]
[string]$vcenter,
[Parameter(Mandatory=$False)]
[switch]$info=$false
)
try
{
    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Importing VMWare modules" -verbose:$info
    Get-Module -ListAvailable -Name "VMware.*" | Import-Module
    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Connecting to Vcenter:$vcenter" -verbose:$info
    [void]::$(Connect-VIServer -Server $vcenter -ErrorAction SilentlyContinue)
    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Getting Data center servers" -verbose:$info
    $DCs = Get-Datacenter
    $VMs = $null
    foreach($dc in $DCs)
    {
        Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Getting VM servers for Data Center:$dc" -verbose:$info
        $VMs=$VMs+ $(Get-Datacenter -Name $dc.Name | Get-VM -Verbose:$info| Select PowerState,Name, NumCpu,MemoryMB,GuestId,VMHost, @{N="IP Address";E={@($_.guest.IPAddress[0])}})
    }
    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Disconnecting from VCenter:$vcenter" -verbose:$info
    Disconnect-VIServer -Server $vcenter -ErrorAction SilentlyContinue -Confirm:$false
    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Returning VM Lists" -verbose:$info
    return $VMs
}
catch
{
    $errorMessage = "$($_.Exception.Message)`n$(($_|select -ExpandProperty invocationinfo).PositionMessage)"
    Write-Warning -Message "Catched an exception in Function:$($MyInvocation.MyCommand)`n$errorMessage" -Verbose:$true
}
}
$vmHosts = getVMHosts -vcenter "vcenter"
$counter = 0
foreach($vm in $vmHosts)
{    
if($vm -ne $null){$json = ConvertTo-Json $vm -Compress;insertToElasticSearch json $json -info:$true -Verbose:$true}   
}

【问题讨论】:

  • 尝试删除getVMHosts 中的“return”,并将其替换为$VMs 单独一行。 technet.microsoft.com/en-us/library/hh847760.aspx
  • 另外,Disconnect-VIServer 命令可能会将值吐回管道,因为您没有将其设置为变量或将其强制转换为 [void]

标签: json powershell type-conversion vmware powercli


【解决方案1】:

试试ConvertTo-JSON -Depth 1Sounds like 对象中有同名的属性。

【讨论】:

    【解决方案2】:

    我没有 VCenter 来验证脚本,但我对您的脚本进行了一些重构,使其更符合 powershell 风格。

    注意事项:

    CmdletBinding 为您提供 -Verbose 和其他功能
    默认情况下,任何未设置为变量的对象都会输出到管道
    Return 不会像大多数开发人员所期望的那样

    function getVMHosts{
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$True,Position=1)]
            [string]$vcenter,
        )
        try
        {
            Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Importing VMWare modules"
            Get-Module -ListAvailable -Name "VMware.*" | Import-Module
            Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Connecting to Vcenter:$vcenter"
            [void]$(Connect-VIServer -Server $vcenter -ErrorAction SilentlyContinue)
            Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Getting Data center servers"
            Get-Datacenter |
                ForEach-Object {
                    Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Getting VM servers for Data Center:$_"
                    Get-Datacenter -Name $_.Name |
                        Get-VM -Verbose:$Verbose|
                        Select PowerState, Name, NumCpu, MemoryMB, GuestId, VMHost, @{N="IP Address";E={@($_.guest.IPAddress[0])}}
            }
    
            Write-Verbose "$(get-date -Format "dd/MM/yyyy HH:mm") - Function:$($MyInvocation.MyCommand) - Disconnecting from VCenter:$vcenter"
            [void]Disconnect-VIServer -Server $vcenter -ErrorAction SilentlyContinue -Confirm:$false
        }
        catch
        {
            $errorMessage = "$($_.Exception.Message)`n$(($_|select -ExpandProperty invocationinfo).PositionMessage)"
            Write-Warning -Message "Exception caught in Function:$($MyInvocation.MyCommand)`n$errorMessage"
        }
    }
    
    getVMHosts -vcenter "vcenter" |
        ForEach-Object {
            $json = ConvertTo-Json $_ -Compress;
            insertToElasticSearch json $json -info:$true -Verbose:$true
        }
    }
    

    【讨论】:

    • 感谢您的回复和cmets。我尝试运行上面的代码,但在 ConvertTo-Json 操作中仍然遇到相同的错误。
    【解决方案3】:

    答案已删除,因为可能没有帮助

    【讨论】:

      【解决方案4】:

      正如 noam 所说,那里有物体导致了这种情况。提取基本情况作为例子

      get-vm <insertexamplevmname> | Select PowerState, Name, NumCpu, MemoryMB, GuestId, VMHost, @{N="IP Address";E={@($_.guest.IPAddress[0])}} | convertto-json -Depth 1
      

      您将看到 VMHost 不仅是它正在运行的主机的名称,而且是实际的主机对象,它也有一个 Name 属性,就像 VM 有一个 Name 一样。

      因此,您可能想要像从来宾对象中提取 IP 地址一样提取 VMHost 名称。

      get-vm <insertexamplevmname> | Select PowerState, Name, NumCpu, MemoryMB, GuestId, @{N="Hostname";E={@($_.VMhost.Name)}}, @{N="IP Address";E={@($_.guest.IPAddress[0])}} | convertto-json
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-20
        • 1970-01-01
        相关资源
        最近更新 更多