Azure 强制Powershell将重复值添加到主报告表中

Azure 强制Powershell将重复值添加到主报告表中,azure,powershell,azure-virtual-machine,Azure,Powershell,Azure Virtual Machine,我有一个创建公共IPs报告的脚本。我有一个VM有两个NIC连接到它的问题。我的脚本的设计方式是,VM名称是唯一的键,所有其他数据都在该键上关联并分配给主表。有没有办法绕过这个问题?这是我的剧本: #Data collection $PIP = Get-AzPublicIpAddress $pipOutput = $PIP | ForEach-Object { [PSCustomObject]@{ "IP Name" = $_.Name "IP Address" = $_.IpAddress "

我有一个创建公共IPs报告的脚本。我有一个VM有两个NIC连接到它的问题。我的脚本的设计方式是,VM名称是唯一的键,所有其他数据都在该键上关联并分配给主表。有没有办法绕过这个问题?这是我的剧本:

#Data collection
$PIP = Get-AzPublicIpAddress

$pipOutput = $PIP | ForEach-Object {
[PSCustomObject]@{
"IP Name" = $_.Name
"IP Address" = $_.IpAddress
"Resource Group Name" = $_.ResourceGroupName
"Location" = $_.Location
"VM Name" = ""
"Network Interface" = ""
"Application" = $_.Tag.Application
"Environment" = $_.Tag.Environment
"Role" = $_.Tag.Role
"Decommission" = $_.Tag.Decommission
"Funding" = $_.Tag.Funding
"Provisioning State" = $_.ProvisioningState
"Allocation Method" = $_.PublicIpAllocationMethod
"Version" = $_.PublicIpAddressVersion
"Idle Timeout In Minutes" = $_.IdleTimeoutInMinutes
}
}

$VMs = Get-AzVm -status
$all = @{}
$end = @{}

foreach ($vm in $VMs) {
    $VMNetworkInterfaceSplitToArray = $vm.NetworkProfile.NetworkInterfaces.id.Split('/')
    $VMNetworkInterfaceObject = Get-AzNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $VMNetworkInterfaceSplitToArray[$VMNetworkInterfaceSplitToArray.Count - 1]
    try {
        $VMPublicIpSplitToArray = ($VMNetworkInterfaceObject.IpConfigurations.publicipaddress.Id).Split('/')
        $vm_Public_IP = (Get-AzPublicIpAddress -ResourceGroupName $vm.ResourceGroupName -Name $VMPublicIpSplitToArray[$VMPublicIpSplitToArray.Count - 1]).IpAddress 
    }
    catch {
        $vm_Public_IP = "n/a"
    }

    if($vm_Public_IP -ne "n/a")
    {
    $all.Add($vm_Public_IP,$vm.name)
    $end.Add($vm_Public_IP,$VMNetworkInterfaceObject.name)
    }

    }

foreach ($ipadd in $pipOutput)
{
    if($all.ContainsKey($ipadd."IP Address"))
    {
        $ipadd."VM Name"=$all[$ipadd."IP Address"]
    }
    else
    {
        $ipadd."VM Name"="n/a"
    }
}

foreach ($ipadd in $pipOutput)
{
    if($end.ContainsKey($ipadd."IP Address"))
    {
        $ipadd."Network Interface"=$end[$ipadd."IP Address"]
    }
    else
    {
        $ipadd."Network Interface"="n/a"
    }
}

根据错误:方法调用失败,因为[System.Management.Automation.PSObject]不包含名为“op_Addition”的方法,我建议您创建一个数组来保存所有PSCustomObject。 比如说

Connect-AzAccount

$PIP = Get-AzPublicIpAddress

$pipOutput = $PIP | ForEach-Object {
[PSCustomObject]@{
"IP Name" = $_.Name
"IP Address" = $_.IpAddress
"Resource Group Name" = $_.ResourceGroupName
"Location" = $_.Location
"VM Name" = ""
"Network Interface" = ""
"Application" = $_.Tag.Application
"Environment" = $_.Tag.Environment
"Role" = $_.Tag.Role
"Decommission" = $_.Tag.Decommission
"Funding" = $_.Tag.Funding
"Provisioning State" = $_.ProvisioningState
"Allocation Method" = $_.PublicIpAllocationMethod
"Version" = $_.PublicIpAddressVersion
"Idle Timeout In Minutes" = $_.IdleTimeoutInMinutes
}
}

$vms =Get-AzVM 
$all =@()
Foreach($vm in $vms){
    
    $VMNetworkInterfaceToArray = $vm.NetworkProfile.NetworkInterfaces.id
     foreach($r in $VMNetworkInterfaceToArray ){
 
        $resource = Get-AzResource -ResourceId $r
        $VMNetworkInterfaceObject=Get-AzNetworkInterface -Name $resource.Name -ResourceGroupName $resource.ResourceGroupName
        try{
        $VMPublicIp=Get-AzResource -ResourceId $VMNetworkInterfaceObject.IpConfigurations.publicipaddress.Id
         $vm_Public_IP = (Get-AzPublicIpAddress -ResourceGroupName $VMPublicIp.ResourceGroupName -Name $VMPublicIp.Name).IpAddress 
         }catch {
            $vm_Public_IP = "n/a"
         }

         if($vm_Public_IP -ne "n/a")
        {
             #create custom object to save the details your need
             $obj= [PSCustomObject]@{"VmName"=$vm.Name
                         "VMPublicIP"=$vm_Public_IP
                         "VMNetworkInterface"=$VMNetworkInterfaceObject.Name
                       }
             # save the object into array
             $all +=$obj

        }
     }
}
Foreach($ipadd in $pipOutput){

   foreach($a in $all){
    
     if($a.VMPublicIP=$ipadd.'IP Address'){
       $ipadd.'VM Name' =$a.VmName
       $ipadd.'Network Interface'=$a.VMNetworkInterface
       
     }else{
     
       $ipadd.'VM Name' ="n/a"
       $ipadd.'Network Interface'="n/a"
     
     }
   
   
   }

}
 

更新 请按以下方式更改脚本

Foreach($ipadd in $pipOutput){

   foreach($a in $all){

     if($ipadd.'IP Address'.Equals($a.VMPublicIP)){
     
     $ipadd.'VM Name' =$a.VmName
       $ipadd.'Network Interface'=$a.VMNetworkInterface

     }else{

       $ipadd.'VM Name' ="n/a"
       $ipadd.'Network Interface'="n/a"

     }

   }

}

您遇到错误,因为
$VMNetworkInterfaceObject
可以是单个对象,也可以是集合?如果是,请包含另一个
foreach
停止使用哈希表。[grin]在主循环中进行查找-在主循环中构建VM列表。现在您正在对PublicIpAddress列表进行两次迭代。。。我会一次完成这一切。//我无法向您提供任何详细信息,因为我无法访问您正在使用的对象。[blush]使用哈希表的目的是将NIC和公共ip与VM名称相关联,我稍后将其添加到主$PIPOUTOUP变量中。我试图在一个PSCustomObject中执行相同的操作(通过将这些信息解析到具有3列的表中,使公共ip成为唯一的键,而不是VM名称,因为哈希表只能有2个),但我无法执行此操作,因为错误:方法调用失败,因为[System.Management.Automation.PSObject]不包含名为“op_Addition”的方法。脚本中存在缺陷,因为它将相同的VM名称和NIC添加到每个公共IP条目中。脚本在这个if($vm_Public_IP-ne“n/a”)循环中正确地收集数据,但是这个循环中有一些错误:Foreach($pipOutput中的ipadd)@lubierzca您能详细描述一下错误吗?loop if($vm_Public_IP-ne“n/a”)脚本为公共IP分配了正确的vm名称和NIC名称值$all表如下所示:Public IP VM NIC 1 1 2 2 2 3 3当脚本想要将这些值添加到Foreach($pipOutput中的ipadd)循环中的$Pipoput时,它不会添加$all表中的相应值,而是将相同的VM名称和NIC名称添加到每个公共IP条目中。具体地说,它从$all表中添加最后一个VM和NIC条目,这导致$PIPOUTOUP看起来是这样的:Public IP VM NIC 1 3 2 3 3Script将n/a添加到VM名称和NIC的每个公共ID条目中,但最后一行除外(它添加了正确的值)@lubierzca请尝试使用
foreach($PIPOUTOUP中的ipadd){$ipadd.VM Name'=“n/a”$ipadd.Network Interface'=“n/a”foreach($a in$all){if($ipadd.IP Address.Equals($a.VMPublicIP)){$ipadd.VM Name'=$a.VmName$ipadd.networkinterface'=$a.VMNetworkInterface break}}}$pipOutput |格式表