我在使用 v2 中未正确 运行 的 PowerShell 代码时遇到问题
I am having trouble with PowerShell code that doesn't run properly in v2
我们正尝试在任务序列中更新我们的 BIOS,我有一个由 Lenovo 提供的脚本,它在 Windows10 和 PowerShell v5 中运行良好。但是,它无法在 Windows 7 中使用 PowerShell v2 正常工作。我们无法在 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()
returns 一个 XPathNodeList
集合。在随后的语句中,当集合没有这样的方法时,您试图对该集合调用方法 SelectNodes()
。这是导致错误的原因。
代码在 PowerShell v5 中工作的原因是 Microsoft 在 PowerShell v3 中引入了一个名为 "member enumeration" 的新功能,该功能自动将对集合中不存在的成员(属性和方法)的调用传递给 集合的元素。在您的情况下,由于集合 $Package
没有方法 SelectNodes()
,调用 $Package.SelectNodes()
将在 PowerShell v2 和更早版本中引发错误,并在 [ PowerShell v3 和更新版本中的 $package
的 =42=] 元素 。
有多种方法可以解决这个问题,例如
Update PowerShell 到 Windows 7 台机器上的 v3 或更新版本。是的,我看到你说你不能升级 Windows 7 台机器,但这实际上是首选解决方案。
将$Packages.SelectNodes()
的结果限制为一项:
$Package = $Packages.SelectNodes($xpathqry, $ns) |
Select-Object -First 1
在下一个语句中仅使用 $Packages
的第一个元素:
$PackageID = $Package[0].SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
为$Package
的每个元素调用SelectNodes()
:
$PackageID = $Package | ForEach-Obejct {
$_.SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
}
我们正尝试在任务序列中更新我们的 BIOS,我有一个由 Lenovo 提供的脚本,它在 Windows10 和 PowerShell v5 中运行良好。但是,它无法在 Windows 7 中使用 PowerShell v2 正常工作。我们无法在 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()
returns 一个 XPathNodeList
集合。在随后的语句中,当集合没有这样的方法时,您试图对该集合调用方法 SelectNodes()
。这是导致错误的原因。
代码在 PowerShell v5 中工作的原因是 Microsoft 在 PowerShell v3 中引入了一个名为 "member enumeration" 的新功能,该功能自动将对集合中不存在的成员(属性和方法)的调用传递给 集合的元素。在您的情况下,由于集合 $Package
没有方法 SelectNodes()
,调用 $Package.SelectNodes()
将在 PowerShell v2 和更早版本中引发错误,并在 [ PowerShell v3 和更新版本中的 $package
的 =42=] 元素 。
有多种方法可以解决这个问题,例如
Update PowerShell 到 Windows 7 台机器上的 v3 或更新版本。是的,我看到你说你不能升级 Windows 7 台机器,但这实际上是首选解决方案。
将
$Packages.SelectNodes()
的结果限制为一项:$Package = $Packages.SelectNodes($xpathqry, $ns) | Select-Object -First 1
在下一个语句中仅使用
$Packages
的第一个元素:$PackageID = $Package[0].SelectNodes('def:S[contains(@N,"PackageID")]',$ns)
为
$Package
的每个元素调用SelectNodes()
:$PackageID = $Package | ForEach-Obejct { $_.SelectNodes('def:S[contains(@N,"PackageID")]',$ns) }