我们正在尝试在任务序列中更新我们的BIOS,并且我有一个由Lenovo提供的脚本,它在Windows 10和PowerShell v5中运行良好。但是,在使用PowerShell v2的Windows 7中,它无法正常工作。我们无法在Windows 7计算机上升级到v5。
该脚本读取我从SCCM导出的XML文件,并匹配相应的BIOS包,下载并运行它。
所以脚本看起来像:
[xml]$Packages = Get-Content BIOSPackages.xml
# Environment variable call for task sequence only
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$BIOS = (Get-WmiObject -Namespace root\cimv2 -Class Win32_BIOS).SMBIOSBIOSVersion.Substring(0,4)
$ns = New-Object Xml.XmlNamespaceManager $Packages.NameTable
$ns.AddNamespace("def", "http://schemas.microsoft.com/powershell/2004/04")
$Xpathqry = "/def:Objs/def:Obj//def:MS[contains(.,`"$BIOS`")]"
$Package = ($Packages.SelectNodes($xpathqry,$ns))
$PackageID = $Package.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
$tsenv.Value('OSDDownloadDownloadPackages') = $PackageID.InnerXML
它失败了:
$PackageID = $Package.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
我试着用它捏一天,我只是碰壁了。
我得到的是以下错误:
Method invocation failed because [System.Xml.XPathNodeList] doesn't contain a method named 'SelectNodes'. At C:\_SMSTaskSequence\Packages\NC1002CB\Get-BIOSPackages.ps1:17 char:38 + $PackageID = $Package.SelectNodes <<<< ('def:S[contains(@N,"PackageID")]',$ns) + CategoryInfo : InvalidOperation: (SelectNodes:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound
错误信息实际上非常清楚。 $Packages.SelectNodes()
返回XPathNodeList
系列。在后续声明中,当集合没有这样的方法时,你试图在该集合上调用方法SelectNodes()
。这是造成错误的原因。
代码在PowerShell v5中运行的原因是Microsoft引入了一个名为"member enumeration"的新功能,其中包含PowerShell v3,可以自动将对集合的非现有成员(属性和方法)的调用传递给集合的元素。在你的情况下,由于集合$Package
没有方法SelectNodes()
,调用$Package.SelectNodes()
将在PowerShell v2和更旧版本中抛出错误,并在PowerShell v3及更新版本中调用SelectNodes()
对$package
的元素。
有多种方法可以解决这个问题,例如:
$Packages.SelectNodes()
的结果限制为一个项目:
$Package = $Packages.SelectNodes($xpathqry, $ns) |
Select-Object -First 1
$Packages
的每个元素调用$PackageID = $Package[0].SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
:
SelectNodes()