构建PowerCLI批量OVF导出工具的问题

3

背景

我正在创建一个脚本,使用PowerCLI进行大规模的OVF导出,使用的是VMware的ovftool。该脚本通过执行以下功能来实现:

  • 通过PowerCLI参数,获取vCenter地址,导出要求的VMs命名方案以及OVFs应该导出到哪里
  • 连接到vCenter实例
  • 将符合指定命名方案的所有VM放入列表中
  • 循环遍历该列表,并使用ovftool和已构建的VM路径将每个VM导出为ovf文件

脚本:VMs-to-OVF.ps1

# Take in vCenter address, naming scheme of VMs to be exported, and where the OVFs should be exported

param (

[string]$vcenter = $(throw "

    vCenter address required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <192.168.1.200>`n

    .\VMs-to-OVF.ps1 -vcenter <vcenter.test.com>"),

[string]$vmNamingScheme = $(throw "

    VM naming scheme required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-1>`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-*>`n"),

[string]$exportLocation = $(throw "

    Export location required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-1> -exportLocation 192.168.1.100:\`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-*> -exportLocation X:\`n")

)

# Connect to vCenter

Connect-VIServer -Server $vcenter

# $VMs is an array of VM names that will be exported
# $vmNamingScheme gives the VM naming pattern we are looking for

$VMs = $(get-vm -name $vmNamingScheme | select name | format-list | out-string)
$VMs = $VMs.replace("Name : ","")
$VMs = $VMs.replace(" ","")
$VMs = $VMs.split("`n")
$VMs = $VMs|?{$_ -ne $VMs[1]}

# This loop iterates through the $VMs array and performs an OVF export, to the location
# specified in $exportLocation, for each VM name in the array
# $vmPath is comprised of the path to the VM and $VM holds the actual VM name

foreach ($VM in $VMs){
    if ($VMs -ne $null){ 

    # ***THIS SCRIPT ASSUMES THE get-vmfolderpath SCRIPT IS IN THE SAME DIRECTORY AS ITSELF***
    # get the folder path of the VM using the get-vmfolderpath script (this will align with
    # the path in vSphere Folders and Templates view)

    $vmPath = "get-vm -name $VM | .\get-vmfolderpath.ps1"
    &$vmPath

    # ***THIS SCRIPT ASSUMES THE DEFAULT INSTALL PATH FOR THE ovftool PROGRAM
    # run the ovftool command with the proper arguments

    &'C:\Program Files\VMware\VMware OVF Tool\ovftool.exe' vi://$vcenter$vmPath$VM $exportLocation
    }
}

Accompanying Script: get-vmfolderpath

param(
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [string]$folderid,
    [switch]$moref
)

$folderparent=get-view $folderid

if ($folderparent.name -ne 'vm'){
    if($moref){
        $path=$folderparent.moref.toString()+'\'+$path
    }
    else{
        $path=$folderparent.name+'\'+$path
    }
    if ($folderparent.parent){
        if($moref){
            get-vmfolderpath $folderparent.parent.tostring() -moref
        }
        else{
            get-vmfolderpath($folderparent.parent.tostring())
        }
    }
}
else {
    if ($moref){
        return (get-view $folderparent.parent).moref.tostring()+"\"+$folderparent.moref.tostring()+"\"+$path
    }
    else {
        return (get-view $folderparent.parent).name.toString()+'\'+$folderparent.name.toString()+'\'+$path
    }
}

错误

如果将文本复制并粘贴到PowerCLI控制台中,则for循环的每个迭代中构建的ovftool命令将起作用,但是在直接从脚本运行时不起作用。当从脚本中运行定制的ovftool命令时,将产生以下错误:

The term 'get-vm -name VM-NAME | .\get-vmfolderpath.ps1' is not
recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.At
C:\Users\username\Desktop\VMs-to-OVF.ps1:85 char:4
+         &$vmPath
+          ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (get-vm -name CA...mfolderpath.p
   s1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

我已经检查的事项:

  • "get-vm -name vm_name | .\get-vmfolderpath.ps1" 命令在 PowerCLI 控制台中直接运行,可以返回正确的虚拟机路径。
  • 所有变量输出了预期值。
  • 如果在脚本中生成的完整 ovftool 命令在 PowerCLI 控制台中运行,则可以正确地导出虚拟机。

你为什么要使用 ovftool 而不是 Export-vApp?当此操作失败时,$vmpath 的确切值是多少?你似乎还遇到了除 ovftool 调用之外的其他参数问题。 - Etan Reisner
我对帖子进行了轻微修改。现在我只是尝试使用以下代码构建VM的路径:$vmPath = "get-vm -name $VM | .\get-vmfolderpath.ps1" ,然后执行 &$vmPath。我收到的错误略有不同。我已经更新了帖子中的错误块。此外,我不知道 Export-vApp 可以用于导出OVFs。这是真的吗? - Chris Willis
如果我使用花括号,我会收到错误提示:Get-VM VM with name 'VM-NAME' was note found using specified filter(s). 另外,如果我使用命令: Export-VApp -Destination $exportLocation -VM $VM,我会得到错误提示:Export-VApp: Could not find find VirtualMachine with name VM-NAME。我开始怀疑是不是我传递虚拟机名称时有误或其他问题。现在我只能猜测了。 - Chris Willis
VM-NAME是什么?您能够使用Get-VM并获取到您期望的虚拟机吗?Export-VApp命令中的-VM标志需要一个虚拟机对象而不是一个字符串。因此,我不太清楚在那种情况下错误的含义是什么(除非您可能使用了视图,并且该虚拟机从视图中移动/更改了位置)。 - Etan Reisner
查找具有唯一名称的虚拟机。调用 Get-VM -Name "Unique VM Name"。它是否有效?如果有效,可以使用 Export-VApp -Name "Unique VM Name" 吗?您可以使用 $vm = Get-VM -Name "Unique VM Name"; Export-VApp -VM $vm 吗?我不知道您目前在测试中使用的虚拟机名称是什么,但它只是虚拟机的名称,不是路径,也不是 moref 等。 - Etan Reisner
显示剩余8条评论
1个回答

0

这只是对此问题的一个总结。我找到了解决方案。我的猜测是,当您操作由Get-VM cmdlet返回的VM列表时,可能会丢失某些信息。在VMs-to-OVFs脚本中,如果所有"$VM ="行都替换为下面的单行,则可以保留该信息。

$VMs = get-vm -name $vmNamingScheme

在for循环中,使用“.Name”属性将每个单独的VM对象传递给get-vmfolderpath脚本。

$vmPath = get-vm -name $VM.Name | .\get-vmfolderpath.ps1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接