powershell - 当脚本读取 XML 文件时,PowerCLI New-VM GuestOSCustomization 失败
问题描述
我有一个 Powershell (v5.1) 脚本(32 位模式),我一直在使用它来创建新的虚拟机(我们的 vRealize 编排似乎无法记录日志)。我正在运行 PowerCLI v5.5。
该脚本运行良好,唯一的问题是脚本中的大量数据是硬编码的。我编写了一个 XML 文件来包含我想要选择的所有可变数据,但是当我添加代码来读取 XML 文件时,VM 将无法在 OSGuestCustomization 期间更改 IP 地址(显然然后是管理员帐户凭据)和因此新的虚拟机对我来说毫无用处。
令人困惑的是为什么要添加这一行:
$script:CMDBInfo = [xml](gc c:\src\Enterprise\Enterprise\Systems\Scripts\Powershell-SCMDEV\Opsbrain\TMCMDB.xml)
到脚本会导致这一行失败:
$create_vm = New-VM -Template $script:json_data.opb_template -ResourcePool $script:json_data.opb_build_cluster -Name $script:json_data.host_name -Datastore $datastore -DiskStorageFormat Thin -OSCustomizationSpec $customization -Confirm:$false -RunAsync -ErrorAction Stop$create_vm = New-VM -Template $script:json_data.opb_template -ResourcePool $script:json_data.opb_build_cluster -Name $script:json_data.host_name -Datastore $datastore -DiskStorageFormat Thin -OSCustomizationSpec $customization -Confirm:$false -RunAsync -ErrorAction Stop
我终于尝试简单地注释掉 GC 并且 New-VM 工作。
一个简短的搜索出现了https://communities.vmware.com/thread/482488,我将磁盘安装在另一台服务器上以检查 VMware 临时文件和日志。
我看到了一些错误,但它们的原因并不是很明显。
c:\windows\setupact.log : dispci.dll: DispCISkipClassInstaller: SetupDiGetSelectedDriver failed with error 0xe0000203.
c:\windows\setuperr.log 为空。
c:\windows\temp\vminst.log :
2017-09-29 14:06:06| tools-build-3917699| INFO: Failed to fetch component state for '_driver_memctl.5C48FA9C_E001_43CB_B2B6_590CD422177E'.
2017-09-29 14:06:40| inst-build-3917699| E1: FILE: FileDeletionRetry: Non-retriable error encountered (C:\Windows\TEMP\vmware-SYSTEM\00007bf9\windows.iso): The system cannot find the file specified (2)
但看起来它完成了:
2017-09-29 14:06:40| inst-build-3917699| I1: Upgrader finished execution, now signalling event.
2017-09-29 14:06:40| inst-build-3917699| I1: Upgrader: returning [0]
我删除了很多注释和“无关”数据,以获得 XML 文件的代表性样本。
<?xml version="1.0" encoding="utf-8"?>
<CMDB>
<IPTable>
<Network Name="DevServerPrivate">
<Range Subnet="192.168.1.0" RangeLow="192.168.1.21" RangeHigh="192.168.1.150" SubnetMask="255.255.255.0" DefGW="192.168.1.1" DNS="8.8.8.8,8.8.4.4" VMwareNetworkLabel="devserver" />
</Network>
</IPTable>
</CMDB>
以及脚本的摘录:
$script:CMDBInfo = [xml](gc D:\src\Enterprise\Enterprise\Systems\Scripts\Powershell-SCMDEV\Opsbrain\TMCMDB.xml)
$TargetNetwork = "$($json_data.environment)ServerPrivate"
$NetworkRanges = $script:CMDBInfo.CMDB.IPTable.Network | Where-Object {$_.Name -eq $TargetNetwork}
# Some ranges may be inactive, meaning we don't want to use them anymore
# Or some ranges may not have any available IP addresses, if multiple ranges are assigned to the environment then we'll want to try all of them to get a valid IP.
foreach($RangeInfo in $NetworkRanges.Range){
if(-not ($RangeInfo.Active -eq 'false')){
$IPAddress = GetIPFromIPAM -Subnet $RangeInfo.Subnet
if([regex]::Matches($IPAddress,'([0-9]{1,3}\.){3}[0-9]').Success -eq 'True'){
break
}
}
}
if([regex]::Matches($IPAddress,'([0-9]{1,3}\.){3}[0-9]').Success -eq 'True'){
$script:json_data | Add-Member -Type NoteProperty -Name ip_address -Value $IPAddress
$script:json_data | Add-Member -Type NoteProperty -Name opb_vm_port_group -Value $RangeInfo.VMwareNetworkLabel
$script:json_data | Add-Member -Type NoteProperty -Name opb_netmask -Value $RangeInfo.SubnetMask
$script:json_data | Add-Member -Type NoteProperty -Name opb_default_route -Value $RangeInfo.DefGW
$script:json_data | Add-Member -Type NoteProperty -Name opb_name_server -Value $RangeInfo.DNS
} else {
LLToLog -EventID $LLERROR -Text "Unable to get an IP address for $TargetNetwork"
#Exit
}
$script:json_data
在最后转储 $script:json_data 后,所有数据都与我在脚本的前一个(工作)迭代中使用的硬编码值相同。
然后我使用数据填充 OSCustomization 对象:
$customization = Get-OSCustomizationSpec -Name "Spec_$host_name" | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $script:json_data.ip_address -SubnetMask $script:json_data.opb_netmask -DefaultGateway $script:json_data.opb_default_route -Dns $script:json_data.opb_name_server[0],$script:json_data.opb_name_server[1]
$customization = Get-OSCustomizationSpec -Name "Spec_$host_name" | Set-OSCustomizationSpec -Domain $script:json_data.dns_domain -DomainUsername "service_account@domain.com" -DomainPassword $DomainAdminPwd
然后创建虚拟机:
$create_vm = New-VM -Template $script:json_data.opb_template -ResourcePool $script:json_data.opb_build_cluster -Name $script:json_data.host_name -Datastore $datastore -DiskStorageFormat Thin -OSCustomizationSpec $customization -Confirm:$false -RunAsync -ErrorAction Stop
现在,我有一个新旧剧本的科学怪人。我尝试通过从 XML 文件中提取信息来执行新脚本的工作,但随后我忽略了所有这些并将 json_data 值设置为旧脚本硬编码值。因此,无论我是否阅读 XML,我总是使用相同的值。
如果我注释掉 XML 的读取,OSGuestCustomization 在 New-VM 克隆完成后大约 2 分钟完成。如果我不加注释,OSGuestCustomization 永远不会完成。我认为有些部分可以:服务器认为它已加入域,但未设置 IP 地址(如 VMWare Tools 报告的那样),并且未设置本地管理员帐户凭据。
解决方案
推荐阅读
- java - checkstyle 配置失败:无法解析配置流
- c++ - 红外接收器多频
- java - 如何将 textView 文本转换为 char 变量?
- url-rewriting - URL 重写在更高的环境中不起作用(未捕获的 ReferenceError:$ 未定义)
- elasticsearch - 嵌套弹性搜索嵌套查询问题 ES7.2
- ffmpeg - 如何从头开始观看或下载潜望镜直播?
- gltf - How to add metadata on a gltf file?
- nginx - nginx 有没有办法使用可用站点直接从 / 重定向到 /page?
- netsuite - 我无法在 netsuite 上进行批量删除
- python - 从 Python 中的一组句子中删除最常见单词中的停用词